%%disallow={camelcase}
@@(title Euphoria v4.1)@
%%maxnumlevel = 4
%%toclevel = 3
%%output=index
<<TOC level=1>>
@@(index <<font color="$(1)" text=`$(+)`>>)@
@@(subindex **$$(color #009999 bug fixed:)**)@
%%output=eu_intro
= Euphoria Programming Language v4.1
@[toc|]
<<LEVELTOC level=1 depth=4>>

!!CONTEXT:../docs/welcome.txt
%%output = welcome

%%output=quick_over
== Quick Overview

Welcome to the Euphoria programming language!

Euphoria is a programming language with the following advantages over
conventional languages:

; Euphoric
: A remarkably simple, flexible, powerful language definition that is easy to
   learn and use.
; Dynamic
: Variables grow or shrink without the programmer having to worry about
   allocating and freeing chunks of memory.  Objects of any size can be assigned
   to an element of a Euphoria sequence (array).
; Fast
: A high-performance, state-of-the-art interpreter that's significantly faster
   than  conventional interpreters such as Perl and Python.
; Compiles
: An optimizing [[:Euphoria To C Translator]], that can boost your speed
even further, often by a factor of 2x to 5x versus the already-fast
interpreter.
; Safe
: Extensive run-time checking for: out-of-bounds
subscripts, uninitialized variables, bad parameter values for library
routines, illegal value assigned to a variable and many more. There are
no mysterious machine exceptions~--you will always get a full English
description of any problem that occurs with  your program at run-time,
along with a call-stack trace-back and a dump of all of your variable
values. Programs can be debugged quickly, easily and  more thoroughly.
; High level
: Features of the underlying hardware are completely
hidden. Programs are not aware of word-lengths, underlying bit-level
representation of values, byte-order etc.
; Debugger
: A full-screen source debugger and an execution profiler are included.
; Editor
: A full-screen, multi-file editor is also included.
On a color monitor, the editor displays
Euphoria programs in multiple colors, to highlight comments, reserved
words, built-in functions, strings, and level of nesting of brackets.
It optionally performs auto-completion of statements, saving you typing
effort and reducing syntax errors. This editor is written in Euphoria,
and the source code is provided to you without restrictions. You are
free to modify it, add features, and redistribute it as you wish.
; Multi-platform
: Euphoria programs run under Windows, Linux, OS/X, FreeBSD, NetBSD, OpenBSD
and can be easily ported to any platform supporting GCC.
; Stand-alone
: You can make a single, stand-alone executable
file from your program.
; Generic
: Euphoria routines are naturally
generic. The example program below shows a  single routine that will
sort any type of data~--integers, floating-point numbers, strings etc.
Euphoria is not an "object-oriented" language, yet it achieves many of
the benefits of these languages in a much simpler way.
; Free
: Euphoria is completely free and open source.

<eucode>
include std/console.e
sequence original_list

function merge_sort(sequence x)
-- put x into ascending order using a recursive merge sort
    integer n, mid
    sequence merged, a, b

    n = length(x)
    if n = 0 or n = 1 then
        return x  -- trivial case
    end if

    mid = floor(n/2)
    a = merge_sort(x[1..mid])       -- sort first half of x
    b = merge_sort(x[mid+1..n])     -- sort second half of x

    -- merge the two sorted halves into one
    merged = {}
    while length(a) > 0 and length(b) > 0 do
        if compare(a[1], b[1]) < 0 then
            merged = append(merged, a[1])
            a = a[2..length(a)]
        else
            merged = append(merged, b[1])
            b = b[2..length(b)]
        end if
    end while
    return merged & a & b  -- merged data plus leftovers
end function

procedure print_sorted_list()
-- generate sorted_list from original_list
    sequence sorted_list
    
    original_list = {19, 10, 23, 41, 84, 55, 98, 67, 76, 32}
    sorted_list = merge_sort(original_list)
    for i = 1 to length(sorted_list) do
    	display("Number [] was at position [:2], now at [:2]", 
    	        {sorted_list[i], find(sorted_list[i], original_list), i}
    	    )
    end for
end procedure

print_sorted_list()     -- this command starts the program
</eucode>

Euphoria has come a long way since v1.0 was released in July 1993 by **R**apid
**D**eployment **S**oftware (//RDS//).
There are now enthusiastic users around the world.

%%output=intro
== Introduction
:<<LEVELTOC level=2 depth=4>>

=== Yet Another Programming Language?

Euphoria is a very high-level programming language. It is unique among a
crowd of conventional languages.

=== Great Features

* Open source
* Free for personal and commercial use
* Produces royalty-free, stand-alone, programs
* Multi-platform ~-- //Windows//, //OS X//, //Linux//, //FreeBSD//,
  //OpenBSD//, //NetBSD//, ...
* Provides a choice of multi-platform GUI toolkits: IUP, GTK, wxWindows
* Syntax colored profiling, debugging and tracing of code
* Dynamic memory allocation and efficient garbage collection
* Interfacing to existing C libraries and databases
* Well-documented, lots of example source-code, and an enthusiastic forum
* Edit and run convenience

=== Euphoria is unique

What makes Euphoria unique is a design that uses just two basic data-types ~--
 //atom// and //sequence//, and two 'helper' data-types ~-- //object// and
 //integer//.

* An **atom** is single numeric value (either an integer or floating point)
* A **sequence** is a list of zero or more //objects//.
* An **object** is a //variant// type in that it can hold an atom or a sequence.
* An **integer** is just a special form of atom that can only hold integers. You
can use the integer type for a performance advantage in situations where
floating point values are not required.

What follows from this design are some advantages over conventional languages:

* The language syntax is smaller ~-- and thus easier to learn
* The language syntax is consistent ~-- and thus easier to program
* Routines are more generic ~-- a routine used for strings may also be
applied to any data structure
* A higher level view of programming ~-- because sequences encompass
conventional lists, arrays, tables, tuples, ..., and all other
data-structures.
* Sequences are dynamic ~-- you may create and destroy at will ~-- and
modify them to any size and complexity
* It supports both //static// data typing and //dynamic// data typing.

=== Beyond Elegance Sequences

* Euphoria programs are considerably faster than conventional interpreted
languages ~-- Euphoria makes a better website server
* Euphoria programs can be translated then compiled as C programs ~-- fast
programs become even faster
* Euphoria lets you write multi-tasking programs ~-- independent of the
platform you are using
* Euphoria has a coherent design ~-- Euphoria programmers enjoy programming
in Euphoria

=== As a first programming language

* Easy to learn, easy to program
* No limits as to what you can program
* Euphoria programming skills will enhance learning other languages

=== But, my favorite language is...

You will find that Euphoria programmers are also knowledgeable in other
languages. I find that the more tools you have (saws and hammers, or programming
languages) the richer you are. Picking the correct tool is part of the art of
programming. It will remain true that some people can program better in their
favorite language rather than an arguably superior language.

Give Euphoria a try, and discover why it has enthusiastic supporters.

=== Products

The //Euphoria// **Interpreter** is used to execute your code directly with no
binding or compilation steps. Edit, run, edit, run.

The //Euphoria// **Binder** is used to create stand-alone programs by "binding" the
Euphoria interpreter onto your source code.

The //Euphoria// **Translator** converts Euphoria-source into C-source. This
allows Euphoria programs to be compiled by a standard C compiler to make even
faster stand-alone programs.

You can freely distribute the Euphoria interpreter, and any other files
contained in this package, in whole or in part, so anyone can run a Euphoria
program that you have developed. You are completely free to distribute any
Euphoria programs that you write.

=== Requirements

To run the //Windows// version of Euphoria, you need any Windows 95 or any later
32-bit version of Windows.  It runs fine on XP, Vista, and Windows 7.

To run the //Unix// version of Euphoria you need a supported //Unix// platform
(Linux, FreeBSD, NetBSD or OpenBSD) and GCC v4.x. Binary packages are available
for various platforms and distributions which remove the need for GCC to be
present.

To run the //OS X// version of Euphoria, you need an Intel based Mac.

=== Conventions used in the manual

Euphoria has multiple interpreters, the main one being ##eui##.

* On //Windows// platforms you have two choices. If you run ##eui## then a console
window is created. If you run ##euiw## then no console is created, making
it suitable for GUI applications.

The manual will only reference ##eui## in examples and instructions; the
reader is left to choose the correct interpreter.

Euphoria runs on many platforms. When operating system specific issues must be 
described you will see these descriptions:

* //"Windows"// is a general reference to operating systems from Microsoft. 
!! lines above run off right side of page 
You will see the constant ##WINDOWS## used for //Windows// specific code.

* //"Unix"// is a general reference to the family operating systems that
includes Linux, FreeBSD, NetBSD, OpenBSD, Mac OS X, ... You will see the
constant ##UNIX## used for //Unix// specific code.

Directory names in //Windows// use ##\## separators, while //Unix// systems use ##/##.
//Unix// users should substitute ##/## when they examine sample code.
Hint: //Windows// users can now use ##/## in directory names.

Operating system names are often trademarks. There is no intent to infringe on 
their owner's rights.
Within a paragraph, Euphoria keywords (like ##atom## or ##while##) and program 
excerpts are written in a ##fixed font##. 

Samples of Euphoria programs will be syntax colored using a fixed font:
<eucode>
for i=1 to 10 do
  ? i
end for
-- this is a comment line
-- above is a 'for loop' example
</eucode>

=== Discover Euphoria

For more information, visit [[http://www.OpenEuphoria.org | OpenEuphoria.org]],
and be sure to join the active [[http://openeuphoria.org/forum/index.wc|discussion forum]].

=== Disclaimer

Euphoria is provided "as is" without warranty of any kind. In no event shall
any authors of Euphoria or contributors to Euphoria be held liable for any
damages arising from the use of, or inability to use, this product.


!!CONTEXT:../docs/whatsnew4_0.txt
%%output = whatsnew4_0

== What's new in 4.0?

Euphoria v4.0 is a very large jump in functionality from the previous stable release, 3.1.1.

Euphoria has a brand new standard library consisting of over 800 public members.
Too numerous to list here, please see the reference section of this manual.

=== General Changes

* New manual and documentation system
* New logo
* Switched to using our own ticket system
* Switched to using our own self hosted Mercurial SCM system

=== Executable name changes

|| Old                         || New         || Description             ||
| ##ex## and ##exwc##           | ##eui##      | Euphoria Interpreter     |
| ##ec## and ##ecw##            | ##euc##      | Euphoria to C Translator |
| ##bind.bat## and ##bind##     | ##eubind##   | Euphoria Binder          |
| ##shroud.bat## and ##shroud## | ##eushroud## | Euphoria Shrouder        |

=== Language Enhancements

* Conditional compilation using the ##[[:ifdef statement]]##.
* [[:Character Strings and Individual Characters|Raw strings]], which can include multilined text.
* [[:Comments|Multiline comments]] using the C-styled comments ##/* .. */##, which can be nested.
* [[:Atoms and Sequences|Binary, Octal and alternative Decimal and Hexadecimal number format]] - 
  ##0b10 (2), 0t10 (8), 0d10 (10), 0x10 (16)##
* [[:Character Strings and Individual Characters|Hexadecimal string]] formats. Use ##\x## to embed 
  any byte value into a standard string, or create an entire hexadecimal byte string using 
  ##x" ... "##
* Function results can now be ignored.
* Optional list terminator. The final item in a list can be the dollar symbol (##$##).
  This is just a place holder for the //end-of-list//, making it easier to
  add and delete items from the source code without having to adjust the commas.
* [[:enum|Enumerated values/types]] (##enum##, ##enum type##)
* Built-in ##eu:## [[:namespace]]
* Declare variable anywhere, not just at the top of a routine. 
* Scoped variables (declared inside an ##if## for example)
* Assign on declaration. You can now declare a variable and assign it an initial value on the same statement.
* The ##[[:object]]()## built-in function can now be used to safely test if a variable has been initialized or not.
* Forward referencing. You no longer need to lexically declare a routine before using it.
* Additional loop constructs ...
** ##[[:loop]]##/##[[:until]]##
** You can [[:Header Labels|label]] a loop 
** ##while X with [[:entry]]##
** ##[[:exit]]##, ##[[:continue]]##, ##[[:retry]]##. All with an optional ##"label"##
** ##[[:goto statement|goto]]##
* Additional conditional constructs
** ##switch## statement with or without ##[[:fallthru]]##
** You can [[:Header Labels|label]] an ##if## or ##switch##
** ##break## keyword allows exiting from ##[[:if]]## / ##[[:switch]]## blocks
* Default/optional parameters for routines
* Additional scope modifiers
** ##[[:export]]##
** ##[[:public]]## (##public include##)
** ##[[:override]]##
* Built in [[:Core Sockets|sockets]]
* Built in [[:Regular Expressions]]
* Resource clean up that can be triggered manually, or when an object's reference count goes to zero
* Automatic inlining of small routines, [[:with / without inline]]
* Built in, optimized sequence operations (##[[:remove]]##, ##[[:insert]]##, ##[[:splice]]##, 
  ##[[:replace]]##, ##[[:head]]##, ##[[:tail]]##)
* Built in peek and poke 2 byte values, 1 byte signed values, peek null terminated strings,
  ##[[:peek]]##, ##[[:peek2]]##, ##[[:peek_string]]##, ##[[:poke]]## and ##[[:poke2]]##
* Fine grained control over which, if any, warnings will be generated by Euphoria,
  [[:with / without warning]].

=== Tool Additions / Enhancements

* General
** [[:The User Defined Preprocessor|User Defined Preprocessor]]
** [[:Set Up the Euphoria Configuration File (eu.cfg)|Configuration system]] (eu.cfg)
** Version display for all tools
* Interpreter
** New test mode, [[:Command line switches]]
** Batch mode for unattended execution such as a CGI application, [[:Command line switches]]
* [[:Euphoria To C Translator|Translator]]
** Compiles directly
** Can compile in debug mode using the ##-debug## argument
** Can write a makefile
** Can compile/bind a resource file on Windows
** Now includes ##eudbg.lib##, ##eu.a## and ##eudbg.a## files in addition to the ##eu.lib##
   file enabling one to link against debug libraries and also use the MinGW compiler directly
   without having to recompile sources.
* New independent shrouder
* Coverage Analysis
* Disassembler
* [[:EuDist - Distributing Programs]]
* [[:EuDOC - Source Documentation Tool]]
* [[:EuTEST - Unit Testing]]

!!CONTEXT:../docs/licensing.txt
%%output = licensing

== Licensing

This product is free and open source, and has benefited from the contributions
of many people. You have complete royalty-free rights to distribute any
Euphoria programs that you develop. You are also free to distribute the 
interpreter, backend and even translator. You can ##shroud## or ##bind## 
your program and distribute the resulting files royalty-free.

You may incorporate any Euphoria source files from this package into your
program, either "as is" or with your modifications. (You will probably need at
least a few of the standard ##euphoria\include## files  in any large program).

We would appreciate it if you told people that your program was developed using
Euphoria, and gave them the address: [[http://www.openeuphoria.org/]] of our
Web page, but we do not require any such acknowledgment.

Icon files, such as ##euphoria.ico## in ##euphoria\bin##, may be distributed
with or without your changes.

The high-speed version of the Euphoria Interpreter back-end is written in ANSI
C, and can be compiled with many different C compilers. The complete source
code is in ##euphoria\source##, along with ##execute.e##, the alternate,
Euphoria-coded back-end. The generous Open Source License allows both
personal and commercial use, and unlike many other open source
licenses, your changes do not have to be made open source.

Some additional 3rd-party legal restrictions might apply when you use the
[[:Euphoria To C Translator]].

----


!!CONTEXT:../License.txt
%%output = 

{{{
Copyright (c) 2007-2011 by OpenEuphoria Group
Copyright (c) 1993-2006 Rapid Deployment Software (RDS)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The copyright holders request, but do not require, that you:

1. Acknowledge RDS and others who contributed to this software.
2. Provide a link to www.RapidEuphoria.com, if possible, from your Web site.
}}}

!!CONTEXT:../docs/credits.txt
%%output = credits

== Euphoria Credits
:<<LEVELTOC level=2 depth=4>>

Euphoria has been continuously developed since it was started in 1993
by Robert Craig. In 2006, version 3.0 was released as open source. Various
releases were made to the 3.x series and then in the 4th quarter of
2010 the largest update ever was made to Euphoria, starting the
Euphoria 4.x series.

It has taken quite a few people to get this far and we would like to
recognize them here. Authors/Contributors are listed in alphabetical 
order by their last name.

For an up-to-date listing, see the [[wiki:EuphoriaContributors|EuphoriaContributors]]
 page at the [[http://openeuphoria.org/wiki/view/home.wc|OpenEuphoria Wiki]].

=== Current Authors

  * Jim Brown
  * Tom Ciplijauskas
  * Jeremy Cowgar
  * C. K. Lester
  * Matthew Lewis
  * Derek Parnell
  * Shawn Pringle

=== Past Authors

  * Robert Craig
  * Chris Cuvier
  * Junko Miura

=== Contributors

  * Jiri Babor
  * Chris Bensler
  * CoJaBo
  * Jason Gade
  * Ryan Johnson
  * Lonny Nettnay
  * Marco Antonio Achury Palma
  * Michael Sabal
  * Dave Smith - Graphics
  * Kathy Smith
  * Randy Sugianto
%%output=installation
= Installing Euphoria
<<LEVELTOC level=1 depth=4>>

!!CONTEXT:../docs/installing.txt
%%output = installing

%%output=installing_euphoria
== Installation
:<<LEVELTOC level=2 depth=4>>

To install Euphoria, consult the instructions below for your particular 
operating system.

=== Windows

All versions other than Windows 95 work without problems.  To use Windows 95, it must have Internet Explorer version 4 or higher
installed (included in service pack 2.5).  To use the new socket functions you will also Windows 2000 or later.  To use all of the new standard library functions you will need at least Windows XP or later.

Euphoria is frequently tested on Windows versions: XP, Vista, 7.

To install Euphoria on //Windows//, visit the following URL:

:http://openeuphoria.org/wiki/view/DownloadEuphoria.wc

The "Standard" version is a complete Euphoria installation, with
Interpreter, Binder, Translator. Included are demo programs and
documentation.

The "Open Watcom" version has the contents of the "Standard" version, 
plus a bundled compiler. This is a convenient way of producing compiled executables
from Euphoria programs.

Download the latest //Windows// installer found under the Binary Releases 
heading of the Current version of Euphoria. Run the program and follow the 
prompts to get Euphoria installed.
   
The installer copies the required files; adds the binary subdirectory to 
your path, if you leave 'update environment' checked; and if you leave 
'Associate file extensions' checked, it associates icons and various actions to
Euphoria file extensions.  Please do not open 'Euphoria Console Files' from Explorer;
they are meant to be run from the command line.

The installer does not set the environment variable **EUDIR** to the Euphoria 
directory even though many third-party programs expect that to be set.  This is
so an older version of EUPHORIA can also still work on the same system.  To set this variable
please see the section [[:manually_edit_your_environment| "How to manually edit your environment in Windows"]] below.

==== Possible Problems 

* On Windows XP/2000, be careful that your PATH and EUDIR do not conflict with autoexec.nt, which can also be used to set environment variables.
* On WinME/98/95 if the install program fails to edit your autoexec.bat file, you will have to do it yourself. Follow the manual procedure  described below.
* Euphoria cannot be run under Windows 3.1 and some unpatched versions of Windows 95 will not be able to run EUPHORIA 4.0.
* You have two EUPHORIA installs and you want to change the environment to use another EUPHORIA.

@[:manually_edit_your_environment|]
==== How to manually modify the environment in Windows

Your EUPHORIA installation directory by default will be C:\Euphoria.  It is possible to install to 
%PROGRAMFILES%\Euphoria, or anywhere you wish.  Careful when using the %ProgramFiles% special location (C:\Program Files on most systems in English).  The %ProgramFiles% directory invariably contains spaces by default.  It is a good idea to use the short 8.3 version of the name, or surround with double quotes.  Ofcourse, you'll just have to substitute your real installation
directory for the C:\EUPHORIA examples below.

===== How to manually modify the environment in Windows (Windows NT/2000/XP)
 
 On Windows XP select: Start Menu -> Control Panel -> Performance
 &Maintenance -> System -> Advanced then click the "Environment Variables"
 button. Click the top "New..." button then enter EUDIR as the Variable Name
 and c:\euphoria (or whatever is correct) for the value, then click OK. Find
 PATH in the list of your variables, select it, then click "Edit...". Add
 {{{;c:\euphoria\bin}}} at the end and click OK.

 On Windows Vista, You'll find the environment variables available at
 Start Menu -> Control Panel -> "System and Maintenance" -> "System" 
 -> "Advanced system settings" -> "Environment Variables" (button)
 
 Other versions of Windows will have the environment variables somewhere in the control panel.

===== How to manually modify the environment in Windows (ME/98/95/3.1) 

 #    In the file c:\autoexec.bat add C:\EUPHORIA\BIN to the list of
       directories in your PATH command. You might use the MS-DOS Edit command,
       Windows Notepad or any other text editor to do this.\\
\\
       You can also go to the Start Menu, select Run, type in sysedit and press
       Enter. autoexec.bat should appear as one of the system files that you
       can edit and save.     
 #  In the same autoexec.bat file add a new line:\\
         SET EUDIR=C:\EUPHORIA \\
       The EUDIR environment variable indicates the full path to the main
       Euphoria directory.
 #  Reboot (restart) your machine. This will define your new PATH and EUDIR
       environment variables.
\\
\\
 Some systems, such as Windows ME, have an autoexec.bat file, but it's a hidden
 file that might not show up in a directory listing. Nevertheless it's there,
 and you can view it and edit it if necessary by typing, for example: notepad
 c:\autoexec.bat in a DOS window.


=====  More on editing environment variables


* set EUDIR to the location of your Euphoria installation directory.
* In PATH you need to include %EUDIR%\BIN.
* There is another, optional, environment variable used by some experienced
 users of Euphoria. It is called EUINC (see the [[:include statement]] ). It determines a search path for
 included files and this variable is used by new and older versions of EUPHORIA. However, for 4.0 and above we now have a [[:set_up_the_euphoria_configuration_file|"configuration file"]] for adding include paths and other settings.

@[:modifying_the_registry|]
==== Modifying the Registry
 
Updating the environment is not enough, your old installation will still be called when you open a Euphoria program in explorer or invoke the Euphoria program on the command line without typing in the interpreter (eui euiw).  Do not type in the single quotes.

You can set these in regedit (replace C:\EUPHORIA with your Euphoria installation directory):
{{{
HKEY_CLASSES_ROOT\.exw\(Default) 
    => 'EUWinApp'
HKEY_CLASSES_ROOT\EuWinApp\(Default) 
    => 'Euphoria Windows App'
HKEY_CLASSES_ROOT\EUWinApp\shell\open\command\(Default) 
    => 'C:\EUPHORIA\BIN\euiw.exe "%1"'
HKEY_CLASSES_ROOT\EUWinApp\shell\translate\command\(Default) 
    => 'C:\EUPHORIA\BIN\euc.exe "%1"'

HKEY_CLASSES_ROOT\.ex\(Default) 
   => 'EUConsoleApp'
HKEY_CLASSES_ROOT\EUConsoleApp\(Default) 
   => 'Euphoria Console App'
HKEY_CLASSES_ROOT\EUConsoleApp\shell\open\command\(Default) 
   => 'C:\EUPHORIA\BIN\eui.exe "%1"'
HKEY_CLASSES_ROOT\EUConsoleApp\shell\translate\command\(Default) 
   => 'C:\EUPHORIA\BIN\euc.exe -con "%1"'

HKEY_CLASSES_ROOT\.e\(Default) => 'EUInc'
HKEY_CLASSES_ROOT\EUInc\(Default) => 'Euphoria Include File'
HKEY_CLASSES_ROOT\.ew\(Default) => 'EUInc'
}}}

You can also set an editor for your EUPHORIA programs this way:
{{{
HKEY_CLASSES_ROOT\EUWinApp\shell\edit\command"\(Default) 
   => 'C:\EUPHORIA\BIN\euiw.exe C:\EUPHORIA\BIN\edx.ex "%1"'
HKEY_CLASSES_ROOT\EUConsoleApp\shell\edit\command"\(Default) 
   => 'C:\EUPHORIA\BIN\euiw.exe C:\EUPHORIA\BIN\edx.ex "%1"'
HKEY_CLASSES_ROOT\EUInc\shell\edit\command"\(Default) 
   => 'C:\EUPHORIA\BIN\euiw.exe C:\EUPHORIA\BIN\edx.ex "%1"'
}}}

You can setup to allow the supplied editor program open to the line where the last failure occured in ex.err files:
{{{
HKEY_CLASSES_ROOT\.err\(Default) => 'EUError'
HKEY_CLASSES_ROOT\EUError\(Default) => 'Error File'
HKEY_CLASSES_ROOT\EUError\shell\debug 
    => 'Debug what created this error file'
HKEY_CLASSES_ROOT\EUError\shell\debug\command\(Default) 
    => 'C:\EUPHORIA\BIN\eui.exe C:\EUPHORIA\BIN\edx.ex'
HKEY_CLASSES_ROOT\EUError\DefaultIcon\(Default) 
    => 'C:\Windows\system32\shell32.dll,78'
}}}



=== UNIX like OSes

The Packaging scripts are maintained in the source code repository for these three Linux distributions: Arch, Debian, and Slackware.  The distribution specific packages installs Euphoria in locations according to the filesystem location conventions of that particular distribution.  If your OS is not Linux or is not a Linux of one of these distributions, read on.

Euphoria may be installed using either a tarball source and binary archive ( ##.tar.gz## or ##.tar.bz2## )

:http://openeuphoria.org/wiki/view/DownloadEuphoria.wc
The distribution specific packages installs Euphoria in locations according to the filesystem location conventions of that particular distribution.
To install this version, you must manually unarchive the tarball.  Then you can move the various files to locations in your filesystem. 
You might need to:
* create an ##eu.cfg## file or 
* set up ##EUINC##.  See the [[:include statement]].




=== DOS

There is DOS support only up to Euphoria 3.1. DOS developers are 
invited to contribute their skills.

== Post Install

The directory maps will help you locate the Euphoria executables, documentation,
and sample programs.

The Windows package installs Euphoria into these directories:

{{{
|
|__ euphoria
     |     file_id.diz
     |     License.txt
     |
     |__ bin           (executables: interpreter, binder, translator, utilities, libraries, ...)
     |
     |__ include 
     |   |             (original include files)
     |   |
     |   |__ std       (standard Euphoria library: io.e, sequence.e, ...)
     |   |
     |   |__ euphoria  (Euphoria specific)
     |
     |
     |__ docs          (html and pdf documentation files)
     |
     |__ tutorial      (small tutorial programs to help you learn Euphoria)
     |
     |__ demo          (generic demo programs that run on all platforms)
     |   |
     |   |__ win32     (Windows specific demo programs (optional) )
     |   |__ unix      (Linux/FreeBSD/OS X specific demo programs (optional))
     |   |__ langwar   (language war game for Linux/FreeBSD/OS X )
     |   |__ bench     (benchmark program )
     |
     |__ source        (the complete source code for: interpreter, translator)
     |
     |__ tests         (unit tests for Euphoria)
     |
     |__ packaging     (software for making installation packages)
}}}


For non Microsoft OSes there are Debian, ArchLinux, Slackware and OSX packages.

The Debian package installs Euphoria into these directories:

{{{
|
|__ usr
|    |__ bin                      (executables: eui, euc, ... )
|    |__ lib                      (executables: interpreter, binder, translator, utilities, libraries, ...)
|    |__ share                    
|         |__ euphoria            
|         |    |                  
|         |    |__ bin            (utility programs)
|         |    |                  
|         |    |__ demo           (general demonstration programs)
|         |    |     |__ win32    (empty)
|         |    |     |__ unix     (Linux/FreeBSD/OS X specific demo programs)
|         |    |     |__ langwar  (language war game for Linux/FreeBSD/OS X )
|         |    |     |__ bench    (benchmark program )
|         |    |__ include        
|         |    |    |             (original include files)
|         |    |    |__ std       (standard Euphoria library: io.e, sequence.e, ...)
|         |    |    |__ euphoria  (Euphoria specific)
|         |    |__ source         (source-code for Euphoria)
|         |    |                  
|         |    |__ tutorial       (tutorial programs for learning Euphoria)
|         |                      
|         |                       
|         |__ doc/euphoria        (html and pdf documentation (optional))
|                               
|                                 
|__ etc/euphoria                  ( eu.cfg )
}}}

The "include", "demo" and "tutorial" directories are the same in
//Windows// and //Unix//.  The //unix// demos are included with Windows but the ##win32## demos are not included in //Linux// distributions. 
{{{
}}}
Additionally, the tar-balls available online have a Windows like layout.  But you can use GNU make to install things to same directories that the Debian package does.

By default using ##/usr/local/## instead of ##/usr/##.
You can change ##/usr/local## to something else by running the following command before building:
{{{
$ ./configure --prefix /some/other/location
}}}

To install
{{{
$ su
# make install
}}}




%%output=configuration
@[:set_up_the_euphoria_configuration_file|]
== Set Up the Euphoria Configuration File (eu.cfg)

Euphoria supports reading command line switches from configuration files. The 
default name for the configuration file is ##eu.cfg##. However you can specify
different ones by using the ##-C## switch.

=== Configuration file format

The configuration file is a text file. Each line in the file is either a command
line switch, a section header, an include path or a comment.
* Comments are lines that begin with a double dash {{{"--"}}}. Everything on the
line is ignored.
* A section header is a //name// enclosed in square brackets. eg. 
##[interpret]##.
** There are a number of predefined sections.
** The lines in a section are only added to the command line switches if they
 apply to the mode that Euphoria is running in.
*** [windows] Applies to Windows platform only.
*** [unix] Applies to any Unix platform only.
*** [interpret] Applies to the interpreter running in any platform.
*** [translate] Applies to the translator running in any platform.
*** [bind] Applies to the binder running in any platform.
*** [interpret:windows] Applies to the interpreter when running under //Windows// 
only.
*** [interpret:unix] Applies to the interpreter when running under //Unix// 
only.
*** [translate:windows] Applies to the translator when running under //Windows// 
only.
*** [translate:unix] Applies to the translator when running under //Unix// only.
*** [bind:windows] Applies to the binder when running under //Windows// only.
*** [bind:unix] Applies to the binder when running under //Unix// only.
*** [all] Applies to all running modes.
** All configuration lines before the first section header are assumed to be the
##[all]## section.
** You can have any number of section headers, but only the predefined ones are
used. All lines in other sections are treated as comments.
* A command line switch is a line that begins with a single dash. The entire 
line is added to the actual command line as if it was originally there.
* An include path is any other line that is not one of the above. The string 
##-I## is prepended to the line and then it is added to the command line.

=== Config File Locations

When Euphoria starts up, it looks for configuration files in the following 
order:
* For //Windows// systems
## ~%ALLUSERSPROFILE~%\euphoria\eu.cfg
## ~%APPDATA~%\euphoria\eu.cfg
## ~%EUDIR~%\eu.cfg
## ~%HOMEDRIVE~%\~%HOMEPATH~%\eu.cfg
## From where ever the executable is run from "<exepath>/eu.cfg"
## Current working directory - "./eu.cfg"
## Command line -C switches
* For //Unix// systems
## /etc/euphoria/eu.cfg
## ${EUDIR}/eu.cfg
## ${HOME}/.eu.cfg
## From where ever the executable is run from "<exepath>/eu.cfg"
## Current working directory - "./eu.cfg"
## Command line -C switches

=== Config File Notes

* Euphoria processes every configuration file found, and in the order described 
above. This means that settings specified in earlier configuration files may be 
overridden by subsequent configuration files. For example, a configuration file 
in the current directory will override the same settings in a configuration file
in the executable's directory.
* If a configuration file contains a ##-C## switch, the new configuration file
specified on that switch is processed before subsequent lines in the old file.
* A configuration file is only ever processed once. Additional references to the
same file are ignored.

%%output=using
= Using Euphoria
<<LEVELTOC level=1 depth=4>>

!!CONTEXT:../docs/using_euphoria.txt
%%output = using_euphoria

%%output=examples
== Example Programs
:<<LEVELTOC level=2 depth=4>>

=== Hello, World ===

The //mandatory// 'Hello World' program is a one-liner in Euphoria.
<eucode>
puts(1, "Hello, World\n")
</eucode>

The built-in routine ##puts## does the job of displaying text on a screen. It
requires two arguments. The first argument, ##1##,  directs the output to 
STDOUT or the console. The second argument, is a string of text that will be 
output.

The result is:
{{{
Hello, World
}}}


=== Sorting ===

The following is an example of a more useful Euphoria program.

<eucode>
include std/console.e
sequence original_list

function merge_sort(sequence x)
-- put x into ascending order using a recursive merge sort
    integer n, mid
    sequence merged, a, b

    n = length(x)
    if n = 0 or n = 1 then
        return x  -- trivial case
    end if

    mid = floor(n/2)
    a = merge_sort(x[1..mid])       -- sort first half of x
    b = merge_sort(x[mid+1..n])     -- sort second half of x

    -- merge the two sorted halves into one
    merged = {}
    while length(a) > 0 and length(b) > 0 do
        if compare(a[1], b[1]) < 0 then
            merged = append(merged, a[1])
            a = a[2..length(a)]
        else
            merged = append(merged, b[1])
            b = b[2..length(b)]
        end if
    end while
    return merged & a & b  -- merged data plus leftovers
end function

procedure print_sorted_list()
-- generate sorted_list from original_list
    sequence sorted_list
    
    original_list = {19, 10, 23, 41, 84, 55, 98, 67, 76, 32}
    sorted_list = merge_sort(original_list)
    for i = 1 to length(sorted_list) do
    	display("Number [] was at position [:2], now at [:2]", 
    	        {sorted_list[i], find(sorted_list[i], original_list), i}
    	    )
    end for
end procedure

print_sorted_list()     -- this command starts the program
</eucode>

The above example contains a number of statements that are processed in order.
; ##include std/console.e## 
: This tells Euphoria that this application needs
access to the public symbols declared in the file
'std/console.e'. This is referred to as a //library//
file. In our case here, the application will be using
the ##display## routine from ##console.e# .

; ##sequence original_list## 
: This declares a variable that is not public but is 
accessible from anywhere in this file. The datatype
for the variable is a ##sequence##, which is a 
variable-length "array," and whose symbol name is
##original_list##.

; ##function merge_sort(sequence x) ... end function## 
: This declares and defines
a function routine. Functions return values when called.
This function must be passed a single parameter when
called ~-- a sequence.

; ##procedure print_sorted_list() ... end procedure##
: This declares and defines
a procedure routine. Procedures never return values when called.
This procedure must not be passed any parameters when
called.

; ##print_sorted_list## 
: This calls the routine called ##print_sorted_list##.

The output from the program will be:
{{{
Number 10 was at position  2, now at  1
Number 19 was at position  1, now at  2
Number 23 was at position  3, now at  3
Number 32 was at position 10, now at  4
Number 41 was at position  4, now at  5
Number 55 was at position  6, now at  6
Number 67 was at position  8, now at  7
Number 76 was at position  9, now at  8
Number 84 was at position  5, now at  9
Number 98 was at position  7, now at 10
}}}

Note that ##merge_sort## will just as easily sort any list of data items~:
<eucode>
{1.5, -9, 1e6, 100}
{"oranges", "apples", "bananas"}
</eucode>

This example is stored as ##euphoria\tutorial\example.ex##. This is not the
fastest way to sort in Euphoria. Go to the ##euphoria\demo## directory and type

<eucode>
eui allsorts
</eucode>

to compare timings on several different sorting algorithms for increasing
numbers of objects.

For a quick tutorial example of Euphoria programming, see
##euphoria\demo\bench\filesort.ex##.


=== What to Do?

Now that you have installed Euphoria, here are some things you can try:

==== Run the Demo Programs

Run each of the demo programs in the ##demo## directory. You just type
##eui <program name>##.
An example of running the demos in a console
{{{
eui buzz
}}}

You can also double-click on a ##.ex## or ##.exw## file from //Windows// as file
associations have been setup during the installation process.

==== Edit Sample Files

You can use any plain text editor for writing Euphoria source-code.

Code-editors provide a syntax highlighter. The wiki lists many editors suitable for Euphoria. Check 
[[wiki:Editors|the wiki for more information about Euphoria editors]].

You can examine the source-code for the demonstration editor ##edx## to see how editors and highlighters work.
Notice the use of colors. You can adjust these colors along with the cursor size and many other 
"user-modifiable" parameters by editing constant declarations in ##edx.ex##. Use 
//Esc q// to quit the editor or //Esc h// for help.


==== Benchmark

Create some new benchmark tests. See ##demo\bench##. Do you get the same speed ratios as we
did in comparison with other popular languages? Report your findings on 
[[http://openeuphoria.org/forum/index.wc|the forum]].

==== Read the Manual

Read the manual in ##html\index.html## by double-clicking it. 
If you have a specific question, type at the console:

{{{
guru word
}}}

The ##guru## program will search all the ##.doc## files, example programs, and other files,
and will present you with a //sorted// list of the most relevant chunks of text that might
answer your enquiry.

==== Visit the EuForum
[[http://openeuphoria.org/forum/index.wc|Euphoria Discussion Forum]]


==== Trace a Demo

Try running a Euphoria program with ##tracing## turned on. Add:

<eucode>
with trace
trace(1)
</eucode>

at the beginning of any Euphoria source file.

==== Run the Tutorial Programs

Run some of the tutorial programs in ##euphoria\tutorial##.

==== Modify the Tutorial Programs

Try modifying some of the demo programs.

First some //simple// modifications (takes less than a minute):

===== Simple

What if there were 100 C~+~+ ships in **Language Wars**? What if ##sb.ex## had to move 1000
balls instead of 125? Change some parameters in ##polygon.ex##. Can you get prettier
pictures to appear? Add some funny phrases to ##buzz.ex##.

===== Harder

Then, some slightly harder ones (takes a few minutes):

Define a new function of x and y in ##plot3d.ex##.

===== Challenging

Then a challenging one (takes an hour or more):

Set up your own customized database by defining the
fields in ##mydata.ex##.

===== Major

Then a major project (several days or weeks):

Write a //smarter// 3D TicTacToe algorithm.

==== Write Your Own

Try writing your own program in Euphoria. A program can be as simple as:

<eucode>
? 2+2
</eucode>

**Remember that after any error you can simply type:** ##edx## to jump into the editor at the
offending file and line.

Once you get used to it, you'll be developing programs //much// faster in Euphoria than you
could in Perl, Java, C/C~+~+ or any other language that we are aware of.


%%output=creating_eu_progs
== Creating Euphoria programs
:<<LEVELTOC level=2 depth=4>>

Euphoria programs can be written with //any// plain text editor. As a
convenience Euphoria comes with ##edx##, an editor written in Euphoria, that
is handy for editing and executing Euphoria programs. Take a look at
##\euphoria\demo## and ##euphoria\tutorial## to see many example programs.

=== Running a Program

To run a Euphoria program you type the name of the interpreter followed by the
filename of the program you want to run. Such as:

<eucode>
eui example.ex
</eucode>

What you just typed is known as the //command-line//.

Depending on the platform you are using the interpreter could be called:

|| Executable || Purpose                                        ||
| ##eui##     | General interpreter on //Windows// and //Unix// variants |
| ##euiw##    | Console-less //Windows// interpreter                 |

The command-line may contain extra information. Following your program filename
you may add extra words (known as //arguments//) that can used in your program
to customize its behavior. These arguments are read within your program by the
built-in function [[:command_line]].

Optionally, you may also use [[:command line switches]] that are typed between
the interpreter name and the program name. Command line switches
customize  how the interpreter itself behaves.

Unlike many other compilers and interpreters, there is no obligation for any
special command-line options for ##eui## or ##euiw##. Only the
name of you Euphoria file is expected, and if you do not supply it, Euphoria
will display all the command line options available.

Euphoria doesn't care about your choice of file extensions. By
convention, however, console-based applications have an extension of ##.ex##,
GUI-based applications have an extension of ##.exw## and include files have an
extension of ##.e##. Note that a GUI application is not necessarily a
//Windows// program. A GUI application can exist on Linux,
OS X, FreeBSD, and so on.

You can redirect standard input and standard output when you run a Euphoria
 program, for example:
<eucode>
eui filesort.ex < raw.txt > sorted.txt
</eucode>
or simply,
<eucode>
eui filesort < raw.txt > sorted.txt
</eucode>

For frequently-used programs under //Windows// you might want to make a
small ##.bat## (batch) file, perhaps called ##myprog.bat##, containing two
statements like:
<eucode>
@echo off
eui myprog.ex %1 %2 %3 %4 %5 %6 %7 %8 %9
</eucode>
The first statement turns off echoing of commands to the screen. The second
runs ##eui myprog.ex## with up to 9 command-line arguments. See
[[:command_line]] for an example of how to read these arguments. Having
a .bat file will save you the minor inconvenience of typing ##eui##
all the time; for example you can just type:
<eucode>
myprog
</eucode>
instead of:
<eucode>
eui myprog
</eucode>

Under modern //Unix// variants, you can use ##~#!/usr/bin/env eui## as the
first line of your script file. On older //Unix// variants, you may need to
use the full path to ##eui##, ##~#!/usr/local/bin/eui##.

If your program is called ##foo.ex##:
<eucode>
#!/usr/bin/env eui

procedure foo()
   ? 2+2
end procedure

foo()
</eucode>

Then if you make your file executable:

<eucode>
chmod +x foo.ex
</eucode>

You can just type:

<eucode>
foo.ex
</eucode>

to run your program. You could even shorten the name to simply "foo". Euphoria
ignores the first line when it starts with **#!**.  Be careful though that
your first line ends with the //Unix//-style ##\n##, and not the
//Windows//-style ##\r\n##, or the unix shell might get confused. If your
file is shrouded, you must give the path to ##eub##, not ##eui##.

You can also run ##bind## to combine your Euphoria program
with the ##eui## interpreter, to make a stand-alone executable file. With a
stand-alone executable, you //can// redirect standard input and output. Binding
is discussed further in [[:Distributing a Program]].

Using the [[:Euphoria To C Translator]], you can also make a stand-alone
executable file, and it will normally run much faster than a bound program.

=== Running under Windows

You can run Euphoria programs directly from the //Windows// environment, or
from a console shell that you have opened from //Windows//. By "associating"
##.ex## files with ##eui.exe## and ##.exw##
files with ##euiw.exe##. You will then be able to double click a Euphoria source
file to run it. The installer will perform this operation for you, if you wish.

%%output=editing_source
== Editing a Program

If you have not selected your "favorite editor," then try ##edx##:

You can use any text editor to edit a Euphoria program. However, Euphoria comes
with its own special editor that is written entirely in Euphoria. Type: ##edx##
followed by the complete name of the file you wish to edit. You can use this
editor to edit any kind of text file. When you edit a Euphoria file some extra
features such as color syntax highlighting and auto-completion of certain
statements are available to make your job easier.

Whenever you run a Euphoria program and get an error message, during
compilation or execution, you can simply type ##edx## with no file name and you
will be automatically positioned in the file containing the error, at the
correct line and column, and with the error message displayed at the top of the
screen.

Under //Windows// you can associate ##edx.bat## with various kinds of text files
that you want to edit. Color syntax highlighting is provided for ##.ex##,
##.exw##, ##.exd##, ##.e## and ##.pro## ([[:Profiling "profile files"]]).

Most keys that you type are inserted into the file at the cursor position. Hit
the ##Esc## key once to get a menu bar of special commands. The arrow keys, and
the ##Insert/Delete/Home/End/PageUp/PageDown## keys are also active. Under
//Linux/FreeBSD// some keys may not be available, and alternate keys are
provided. See [[:Edx Demonstration Code Editor]] for a complete description of
the editing commands.

!! Check links for this

If you need to understand or modify any detail of the editor's operation, you
can edit the file ##edx.ex## in ##euphoria\bin## (be sure to make a backup copy
so you don't lose your ability to edit).  If the name ##edx## conflicts with
some other command on your system, simply rename the file
##euphoria\bin\edx.bat## to something else. Because this editor is written in
Euphoria, it is remarkably concise and easy to understand. The same
functionality implemented in a language like C, would take far more lines of
code.

##edx## is a simple text-mode editor that runs on all platforms and is
distributed with Euphoria. There is a list of other editors at the
[[wiki:Editors|OpenEuphoria web site]], many of which include extra
features such as syntax highlighting.

%%output=distributing
== Distributing a Program

Euphoria provides you with 4 distinct ways of distributing a program.

* "source-code", with the Euphoria "interpreter"
* "shroud" into ##.il## code, with Euphoria "backend"
* "bind" into a Euphoria executable
* "translate" into a C-compiled executable


In the first way you simply ship your users the interpreter along with your
Euphoria source files including any Euphoria includes that may be necessary
from the ##euphoria/include## directory. If the Euphoria source files and the
interpreter are placed together in one directory then your user can run your
program by typing ##eui## followed by the path of your main executable source
file. You might also provide a small ##.bat## file so people will not actually
have to type the interpreter name. This way assumes that you are willing to
share your Euphoria source code with your users.

The Binder gives you two more ways of distribution. You can ##shroud## your
program, or you can ##bind## your program. **Shrouding** combines all of the
Euphoria source code that your program needs to create a single ##.il## file.
**Binding** combines your shrouded program with the Euphoria backend
(##eub## or ##eubw## on Windows) to create a single, stand-alone executable file.
For example, if your program is called "##myprog.ex##" you can create 
"##myprog.exe##"
which will run identically. For more information about shrouding and binding,
see [[:Shrouding and Binding]].

Finally, with the [[:Euphoria To C Translator]], you can translate your
Euphoria program into C and then compile it with a C compiler to get an
executable program.

%%output=command_switches
== Command Line Switches
:<<LEVELTOC level=2 depth=4>>

You can launch Euphoria with some extra command line switches, in order to add
or change configuration elements. When running a GUI, there is always some way
to open a prompt and enter any text with options, arguments and whatever the
program being launched may need for proper, expected operation. Under 
//Windows//,
this is achieved by clicking the ##Start## button and selecting ##Run...##, or hitting 
##Windows-R##.

Command line switches may be changed or added, one at a time.

In the table below, ##(all)## indicates that the given switch applies to the Interpreter,
Translator and Binder. Use of ##(interpreter)##, ##(translator)## and/or ##(binder)##
indicates that the referenced switch applies only to that execution mode.

@[batch_command_line|]
; ##-BATCH## (all)
: Executes the program but if any error occurs, the "Press Enter" prompt is
  not presented. The exit code will be set to 1 on error, 0 on success. This
  option can also be set via the [[:with_batch "with batch"]] directive.

; ##-COM dir## (translator)
; Specifies the include directory for the C compiler once EUPHORIA code is translated.  
; This should be set such that dir/include/euphoria.h exists.  
; Normally, //dir// is detected. So, you don't not normally need to specify the location.

; ##-COPYRIGHT## (all)
: Displays the copyright banner for euphoria.

@[eu.cfg|]
; ##-C config_file## (all)
: Specifies either a file name or the path for where the default file called
  eu.cfg exists. The configuration file which holds a set of additional
  command line switches. See Also [[:Configuration file format]]

; ##-CON## (translator)
: Windows only.  Specifies that the translated program should be a console
  application.  The default is to build a windowed application.

; ##-D word## (all)
: Defines a word as being set. Words are processed by the [[:ifdef statement]].
  Words can also be defined via the [[:with / without define]] directive.

; ##-DEBUG## (translator)
: Enable debug mode for the generated code. 

; ##--DEBUGGER external-debugger## (interpreter)
: An external debugger translated into a .DLL or .so library to be used instead
  of the built-in debugger.

; ##-DLL, -SO## (translator)
: Compiles and links the translated euphoria code into a DLL, SO or DYLIB 
(depending on the platform).

; ##-EUDIR dir## (all)
: This overrides the environment variable EUDIR.

; ##-H, --HELP, -?## (all)
: Displays the list of available command line options.

; ##-I include_path## (all)
: Specifies an extra include path.

; ##-LIB file## (translator)
: Specifies the run-time library to use when translating euphoria programs.

; ##-LIB-PIC file## (translator)
: Specifies the run-time library to use when translating euphoria programs as
  shared objects.  The library should be built using the -fPIC (position independent
  code) flag.  This is meant to be used in a eu.cfg file to be able to specify both
  a non-PIC (using the -lib option) and a PIC option in the same eu.cfg file.

; ##-PLAT word## (translator)
: Specify the target platform for translation.  This allows euphoria code to
  be translated for any supported platform from any other supported platform.
  Supported platforms: FREEBSD, LINUX, NETBSD, OPENBSD, OSX, WINDOWS

; ##-STRICT## (all)
: This turns on all warnings, overriding any with/without warning statement
  found in the source. This option can also be set via the
  [[:with/without warning]] directive.

; ##-TEST## (all)
: Parses the code only and issues any warnings or errors to ##STDOUT##. On
  error the exit code will be 1, otherwise 0. If an error was found, the
  normal "Press Enter" prompt will not be presented when using the ##-TEST##
  parameter which enables many editor/IDE programs to test the syntax of your
  Euphoria source in real time.

; ##-TRACE-LINES n## (all)
: Changes the number of lines that will be used in ctrace.out for lines traced
  under ##trace(3)##.  The default is 500.

; ##-VERSION## (all)
: Displays the version of euphoria that is running.

; ##-W warning_name## (all)
: Resets, or adds to, the current list of warnings that may be emitted. The list
of known names is to be found in the subsection [[:with/without warning]]. A 
name should appear without quotes.
  If the ##warning_name## begins with a plus symbol '##+##', this warning is 
  added to the current
  set of warnings checked for, otherwise the first usage resets the list 
  to the warning being introduced, and each subsequent ##-W## warning_name adds 
  to the list.

; ##-WF file_name## (all)
: Sets the file where the warnings should go instead of the standard error. 
Warnings are written to that file regardless of whether or not there are errors 
in the source. If there are no warnings, the ##-wf## file is not created. If the
##-wf## file cannot be created, a suitable message
 is displayed on STDERR and written to ##ex.err##.
 
; ##-X##;
: Resets, or adds to, the list of warnings that will not be issued. This is 
opposite of the ##-W## switch.

The case of the switches is ignored, so ##-I## and ##-i## are equivalent.

=== Further Notes

* Included files are searched for in all included paths, in the following order:
## The current path
## Paths specified in a ##-I## command line switch, which can also come from any
   configuration files found.
## Paths listed in the ##EUINC## environment variable, in the order in which 
they appear
## Paths listed in the ##EUDIR## environment variable, in the order in which 
they appear
## The interpreter's path
%%output=langref_index
= Language Reference
<<LEVELTOC depth=2>>

!!CONTEXT:../docs/refman_2.txt
%%output = refman_2

%%output=lang_def
== Definition
:<<LEVELTOC level=2 depth=4>>
=== Objects ===
@[predefinedtypes|]

==== Atoms and Sequences

All data **objects** in Euphoria are either **atoms** or **sequences**.  An **atom** is 
a single numeric value.  A **sequence** is a collection of objects, either atoms or sequences
themselves. A sequence can contain any mixture of atom and sequences; a sequence
does not have to contain all the same data type. Because the **objects**
contained in a sequence can be an arbitrary mix of atoms or sequences, it is
an extremely versatile data structure, capable of representing any sort of data.

A sequence is represented by a list of objects in brace brackets **{ }**, separated by 
commas with an optional sequence terminator, ##$##. Atoms can have any integer or 
double-precision floating point value. They can range from approximately -1e300 (minus 
one times 10 to the power 300) to +1e300 with 15 decimal digits of accuracy. Here are
some Euphoria objects:

<eucode>
-- examples of atoms:
0
1000
98.6
-1e6
23_100_000
x
$

-- examples of sequences:
{2, 3, 5, 7, 11, 13, 17, 19}
{1, 2, {3, 3, 3}, 4, {5, {6}}}
{{"jon", "smith"}, 52389, 97.25}
{} -- the 0-element sequence
</eucode>

By default, number literals use //base 10//, but you can have integer literals
written in other bases, namely binary //(base 2)//, octal //(base 8)//, and
hexadecimal //(base 16)//. To do this, the number is prefixed by a 2-character
code that lets Euphoria know which base to use.
|= Code |= Base                |
| 0b    | 2 = **B**inary       |
| 0t    | 8 = Oc**t**al        |
| 0d    | 10 = **D**ecimal     |
| 0x    | 16 = He**x**adecimal |

For example:
<eucode>
0b101 --> decimal 5
0t101 --> decimal 65
0d101 --> decimal 101
0x101 --> decimal 257
</eucode>

Additionally, hexadecimal integers can also be written by prefixing the number with 
the '#' character.

For example:
<eucode>
#FE             -- 254
#A000           -- 40960
#FFFF00008      -- 68718428168
-#10            -- -16
</eucode>

Only digits and the letters A, B, C, D, E, F, in either uppercase or lowercase,
are allowed in hexadecimal numbers.  Hexadecimal numbers are always positive,
unless you add a minus sign in front of the # character. So for instance
#FFFFFFFF is a huge positive number
(4294967295), **not** ##-1##, as some machine-language programmers might expect.

Sometimes, and especially with large numbers, it can make reading numeric
literals easier when they have embedded grouping characters. We are familiar
with using commas (periods in Europe) to group large numbers by three-digit
subgroups. In Euphoria we use the underscore character to achieve the same
thing, and we can group them
anyway that is useful to us.

<eucode>
atom big = 32_873_787   -- Set 'big' to the value 32873787

atom salary = 56_110.66 -- Set salary to the value 56110.66

integer defflags = #0323_F3CD

object phone = 61_3_5536_7733

integer bits = 0b11_00010_1
</eucode>

**Sequences** can be nested to any depth, i.e. you can have sequences within
sequences within sequences and so on to any depth (until you run out of
memory). Brace brackets are used to construct sequences out of a list of
expressions.  These expressions can be constant or evaluated at run-time.
e.g.

<eucode>
{ x+6, 9, y*w+2, sin(0.5) }
</eucode>

All sequences can include a special //end of sequence// marker which is the ##$##
character. This is for convience of editing lists that may change often as development
proceeds.

<eucode>
sequence seq_1 = { 10, 20, 30, $ }
sequence seq_2 = { 10, 20, 30 }

equal(seq_1, seq_2) -- TRUE
</eucode>

The **"Hierarchical Objects"** part of the Euphoria acronym comes from the
hierarchical nature of nested sequences. This should not be confused with the
class hierarchies of certain object-oriented languages.

Why do we call them atoms?  Why not just "numbers"? Well, an ##atom## //is//
just a number, but we wanted to have a distinctive term that emphasizes that
they are indivisible (that's what "atom" means in Greek). In the world of
physics you can 'split' an atom into smaller parts, but you no
longer have an atom~--only various particles. You can 'split' a
number into smaller parts, but you no longer have a number~--only various
digits.

Atoms are the basic building blocks of all the
data that a Euphoria program can manipulate. With this analogy, **sequence**s
might be thought of as "molecules", made from atoms and other molecules. A
better analogy would be that sequences are like directories, and atoms are
like files. Just as a directory on your computer can contain both files and
other directories, a sequence can contain both atoms and other sequences
(and //those// sequences can contain atoms and sequences and so on).

{{{
.          object
.           /  \
.          /    \
.        atom  sequence
}}}

As you will soon discover, sequences make Euphoria very simple //and// very
powerful.  **Understanding atoms and sequences is the key to understanding
Euphoria.**

;**Performance Note~:**
:Does this mean that all atoms are stored in memory as eight-byte floating-point
numbers? No. The Euphoria interpreter usually stores integer-valued atoms as
machine integers (four bytes) to save space and improve execution speed. When
fractional results occur or integers get too big, conversion to IEEE 
eight-byte floating-point format happens automatically.

==== Character Strings and Individual Characters

A **character string** is just a ##sequence## of characters.  It may be
entered in a number of ways ...

* Using double-quotes e.g.

<eucode>
"ABCDEFG"
</eucode>

* Using raw string notation e.g.

<eucode>
-- Using back-quotes
`ABCDEFG`
</eucode>
 or
<eucode>
-- Using three double-quotes
"""ABCDEFG"""
</eucode>

* Using binary strings e.g.

<eucode>
b"1001 00110110 0110_0111 1_0101_1010" -- ==> {#9,#36,#67,#15A}
</eucode>

* Using hexadecimal byte strings e.g.

<eucode>
x"65 66 67 AE" -- ==> {#65,#66,#67,#AE}
</eucode>

When you put too many hex characters together they are split up appropriately for you:

<eucode>
x"656667AE"  -- 8-bit  ==> {#65,#66,#67,#AE}
</eucode>

**The rules for double-quote strings are:**
# They begin and end with a double-quote character
# They cannot contain a double-quote
# They must be only on a single line
# They cannot contain the TAB character
# If they contain the back-slash '\' character, that character must immediately
be followed by one of the special //escape// codes. The back-slash and escape
code will be replaced by the appropriate single character equivalent.
If you need to include double-quote, end-of-line, back-slash, or TAB characters
inside a double-quoted string, you need to enter them in a special manner.

e.g.

<eucode>
"Bill said\n\t\"This is a back-slash \\ character\".\n"
</eucode>
Which, when displayed should look like ...
{{{
Bill said
    "This is a back-slash \ character".
}}}


**The rules for raw strings are:**
# Enclose with three double-quotes  {{{"""..."""}}} or back-quote. {{{`...`}}}
# The resulting string will never have any carriage-return characters in it.
# If the resulting string begins with a new-line, the initial new-line is
removed and any trailing new-line is also removed.
# A special form is used to automatically remove leading whitespace from the
source code text. You might code this form to align the source text for ease of
reading. If the first line after the raw string start token begins
with one or more underscore characters, the number of consecutive underscores
signifies the maximum number of whitespace characters that will be removed from
each line of the raw string text. The underscores represent an assumed left
margin width. **Note**, these leading underscores do not form part of the raw
string text.

e.g.

<eucode>
-- No leading underscores and no leading whitespace
`
Bill said
    "This is a back-slash \ character".
`
</eucode>
Which, when displayed should look like ...
{{{
Bill said
    "This is a back-slash \ character".
}}}

<eucode>
-- No leading underscores and but leading whitespace
`
   Bill said
      "This is a back-slash \ character".
`
</eucode>
Which, when displayed should look like ...
{{{
   Bill said
      "This is a back-slash \ character".
}}}
<eucode>
-- Leading underscores and leading whitespace
`
_____Bill said
         "This is a back-slash \ character".
`
</eucode>
Which, when displayed should look like ...
{{{
Bill said
    "This is a back-slash \ character".
}}}

Extended string literals are useful when the string contains new-lines, tabs,
or back-slash characters because they do not have to be entered
in the special manner. The back-quote form can be used when the string literal
contains a set of three double-quote characters, and the triple quote form can
be used when the text literal contains back-quote characters. If a literal
contains both a back quote and a set of three double-quotes, you will need to
concatenate two literals.

<eucode>
object TQ, BQ, QQ
TQ = `This text contains """ for some reason.`
BQ = """This text contains a back quote ` for some reason."""
QQ = """This text contains a back quote ` """ & `and """ for some reason.`
</eucode>

**The rules for binary strings are...**

# they begin with the pair ##b"## and end with a double-quote (##"##) character
# they can only contain binary digits (0-1), and space, underscore,
 tab, newline, carriage-return. Anything else is invalid.
# an underscore is simply ignored, as if it was never there. It is used to aid
 readability.
# each set of contiguous binary digits represents a single sequence element
# they can span multiple lines
# The non-digits  are treated as punctuation and used to delimit individual
  values.

<eucode>
b"1 10 11_0100 01010110_01111000" == {0x01, 0x02, 0x34, 0x5678}
</eucode>

**The rules for hexadecimal strings are:**
# They begin with the pair ##x"## and end with a double-quote (##"##) character
# They can only contain hexadecimal digits (0-9 A-F a-f), and space, underscore,
 tab, newline, carriage-return. Anything else is invalid.
# An underscore is simply ignored, as if it was never there. It is used to aid
 readability.
# Each pair of contiguous hex digits represents a single sequence element with a
 value from 0 to 255
# They can span multiple lines
# The non-digits are treated as punctuation and used to delimit individual
  values.
<eucode>
x"1 2 34 5678_AbC" == {0x01, 0x02, 0x34, 0x56, 0x78, 0xAB, 0x0C}
</eucode>


Character strings may be manipulated and operated upon just like any other
sequences. For example the string we first looked at "ABCDEFG" is entirely
equivalent to the sequence:

<eucode>
{65, 66, 67, 68, 69, 70, 71}
</eucode>

which contains the corresponding ASCII codes. The Euphoria compiler will
immediately convert "ABCDEFG" to the above sequence of numbers.  In a sense,
there are no "strings" in Euphoria, only sequences of numbers.  A quoted string
is really just a convenient notation that saves you from having to type in all
the ASCII codes.
@[emptyseq|]
It follows that "" is equivalent to {}. Both represent
the sequence of zero length, also known as the **empty sequence**. As
a matter of programming style, it is natural to use "" to suggest a zero length
sequence of characters, and {} to suggest some other kind of sequence.
An **individual character** is an **atom**. It must be entered using single
quotes. There is a difference between an individual character (which is an
atom), and a character string of length 1 (which is a sequence). e.g.

<eucode>
'B'   -- equivalent to the atom 66 - the ASCII code for B
"B"   -- equivalent to the sequence {66}
</eucode>

Again, ##'B'## is just a notation that is equivalent to typing ##66##. There 
are no "characters" in Euphoria, just numbers (atoms). However, it is 
possible to use characters without ever having to use their numerical
representation.

Keep in mind that an atom is //not// equivalent to a one-element sequence
containing the same value, although there are a few built-in routines that
choose to treat them similarly.

====Escaped Characters====

Special characters may be entered using a back-slash:
|=Code     | Meaning|
| \n       | newline |
| \r       | carriage return |
| \t       | tab |
| {{{\\}}} | backslash |
| \"       | double quote |
| \'       | single quote |
| \0       | null |
| \e       | escape |
| \E       | escape |
| \b/d..d/ | A binary coded value, the \b is followed by 1 or more binary digits. \\
             Inside strings, use the space character to delimit or end a binary value.
| \x/hh/   | A 2-hex-digit value, e.g. "\x5F" ==> {95} |
| \u/hhhh/ | A 4-hex-digit value, e.g. "\u2A7C" ==> {10876} |
| \U/hhhhhhhh/ | An 8-hex-digit value, e.g. "\U8123FEDC" ==> {2166619868} |

For example, ##"Hello, World!\n"##, or ##'~\~\'##. The demonstration editor ##edx## displays character
strings in green.

Note that you can use the underscore character ##'_'## inside the 
##\b##, ##\x##, ##\u##, and ##\U##
values to aid readability, e.g. ##"\U8123_FEDC" ==> {2166619868}##

=== Identifiers

An identifier is just the name you give something in your program. This can be
a variable, constant, function, procedure, parameter, or namespace. An identifier
must begin with either a letter or an underscore, then followed by zero or more
letters, digits or underscore characters. There is no theoretical limit to how
large an identifier can be but in practice it should be no more than about 30
characters.

Identifiers are **case-sensitive**. This means that ##"Name"## is a different
identifier from ##"name"##, or ##"NAME"##, etc...

Examples of valid identifiers~:
<eucode>
n
color26
ShellSort
quick_sort
a_very_long_indentifier_that_is_really_too_long_for_its_own_good
_alpha
</eucode>

Examples of invalid identifiers~:
<eucode>
0n         -- must not start with a digit
^color26   -- must not start with a punctuation character
Shell Sort -- Cannot have spaces in identifiers.
quick-sort -- must only consist of letters, digits or underscore.
</eucode>

@[source_comments|]
=== Comments
Comments are ignored by Euphoria and have no effect on execution speed.
For example the ##edx## editor displays comments in red.

There are three forms of comment text:

* The //line// format comment is started by two dashes and extends to the
 end of the current line.

e.g.
<eucode>
-- This is a comment which extends to the end of this line only.
</eucode>

* The //multi-line// format comment is started by ##/*## and extends to the
 next occurrence of ##*/##, even if that occurs on a different line.

e.g.
<eucode>
/* This is a comment which
   extends over a number
   of text lines.
*/
</eucode>

* On the first line only of your program, you can use a special comment
beginning with the two character sequence ###!##. This is mainly used to tell
//Unix// shells which program to execute the 'script' program with.

e.g.
<eucode>
#!/home/rob/euphoria/bin/eui
</eucode>

This informs the Linux shell that your file should be executed by the
Euphoria interpreter, and gives the full path to the interpreter.  If you make
your file executable, you can run it, just by typing its name, and without the
need to type "##eui##". On //Windows// this line is just
treated as a comment (though Apache Web server on //Windows// does
recognize it.). If your file is a shrouded ##.il## file, use ##eub.exe##
instead of ##eui##.

Line comments are typically used to annotate a single (or small section) of
code, whereas multi-line comments are typically used to give larger pieces of
documentation inside the source text.

=== Expressions

Like other programming languages, Euphoria lets you calculate results by
forming expressions. However, in Euphoria you can perform calculations on
entire sequences of data with one expression, where in most other languages you
would have to construct a loop. In Euphoria you can handle a sequence much as
you would a single number. It can be copied, passed to a subroutine, or
calculated upon as a unit. For example,

<eucode>
{1,2,3} + 5
</eucode>

is an expression that adds the sequence ##{1,2,3}## and the ##atom 5## to get
the resulting sequence ##{6,7,8}##.

We will see more examples later.

==== Relational Operators

The relational operators  **##< > <= >= = !=##** each produce a ##1## (true) or 
a ##0## (false) result.

<eucode>
8.8 < 8.7   -- 8.8 less than 8.7 (false)
-4.4 > -4.3 -- -4.4 greater than -4.3 (false)
8 <= 7      -- 8 less than or equal to 7 (false)
4 >= 4      -- 4 greater than or equal to 4 (true)
1 = 10      -- 1 equal to 10 (false)
8.7 != 8.8  -- 8.7 not equal to 8.8 (true)
</eucode>

As we will soon see you can also apply these operators to sequences.

==== Logical Operators

The logical operators ##and##, ##or##, ##xor##, and ##not## are used to
determine the "truth" of an expression. e.g.

<eucode>
1 and 1     -- 1 (true)
1 and 0     -- 0 (false)
0 and 1     -- 0 (false)
0 and 0     -- 0 (false)

1 or  1     -- 1 (true)
1 or  0     -- 1 (true)
0 or  1     -- 1 (true)
0 or  0     -- 0 (false)

1 xor 1     -- 0 (false)
1 xor 0     -- 1 (true)
0 xor 1     -- 1 (true)
0 xor 0     -- 0 (false)

not 1       -- 0 (false)
not 0       -- 1 (true)
</eucode>

You can also apply these operators to numbers other than ##1## or ##0##. The 
rule is: zero means false and non-zero means true. So for instance:

<eucode>
5 and -4    -- 1 (true)
not 6       -- 0 (false)
</eucode>

These operators can also be applied to sequences. See below.

In some cases [[:short_circuit]] evaluation will be used for expressions
containing ##and## or ##or##. Specifically, short circuiting applies inside decision making expressions.  These are found in the [[:if statement]], [[:while statement]] and the [[:loop until statement]].  More on this later.

==== Arithmetic Operators

The usual arithmetic operators are available: add, subtract, multiply, divide,
unary minus, unary plus.

<eucode>
3.5 + 3  -- 6.5
3 - 5    -- -2
6 * 2    -- 12
7 / 2    -- 3.5
-8.1     -- -8.1
+8       -- +8
</eucode>

Computing a result that is too big (i.e. outside of -1e300 to +1e300) will
result in one of the special atoms **+infinity** or **-infinity**.  These appear
as ##inf## or ##-inf## when you print them out. It is also possible to generate
##nan## or ##-nan##.  "nan" means "not a number", i.e. an undefined value (such
as ##inf## divided by ##inf##). These values are defined in the
IEEE floating-point standard. If you see one of these special values in your
output, it usually indicates an error in your program logic, although
generating inf as an intermediate result may be acceptable in some cases. For
instance, ##1/inf## is ##0##, which may be the "right" answer for your
algorithm.

Division by zero, as well as bad arguments to math library routines, e.g.
square root of a negative number, log of a non-positive number etc. cause an
immediate error message and your program is aborted.

The only reason that you might use unary plus is to emphasize to the reader of
your program that a number is positive. The interpreter does not actually
calculate anything for this.

==== Operations on Sequences

All of the relational, logical and arithmetic operators described above, as
well as the math routines described in [[:Language Reference]], can be applied
to sequences as well as to single numbers (atoms).

When applied to a sequence, a unary (one operand) operator is actually applied
to each element in the sequence to yield a sequence of results of the same
length. If one of these elements is itself a sequence then the same rule is
applied again recursively. e.g.

<eucode>
x = -{1, 2, 3, {4, 5}}   -- x is {-1, -2, -3, {-4, -5}}
</eucode>

If a binary (two-operand) operator has operands which are both sequences then
the two sequences must be of the same length. The binary operation is then
applied to corresponding elements taken from the two sequences to get a
sequence of results. e.g.

<eucode>
x = {5, 6, 7, 8} + {10, 10, 20, 100}
-- x is {15, 16, 27, 108}
x = {{1, 2, 3}, {4, 5, 6}} + {-1, 0, 1} -- ERROR: 2 != 3
-- but
x = {{1, 2, 3} + {-1, 0, 1}, {4, 5, 6} + {-1, 0, 1}} -- CORRECT
-- x is {{0, 2, 4}, {3, 5, 7}}
</eucode>

If a binary operator has one operand which is a sequence while the other is a
single number (atom) then the single number is effectively repeated to form a
sequence of equal length to the sequence operand. The rules for operating on
two sequences then apply. Some examples:

<eucode>
y = {4, 5, 6}
w = 5 * y                          -- w is {20, 25, 30}

x = {1, 2, 3}
z = x + y                          -- z is {5, 7, 9}
z = x < y                          -- z is {1, 1, 1}

w = {{1, 2}, {3, 4}, {5}}
w = w * y                          -- w is {{4, 8}, {15, 20}, {30}}

w = {1, 0, 0, 1} and {1, 1, 1, 0}  -- {1, 0, 0, 0}
w = not {1, 5, -2, 0, 0}           -- w is {0, 0, 0, 1, 1}

w = {1, 2, 3} = {1, 2, 4}          -- w is {1, 1, 0}

-- note that the first '=' is assignment, and the
-- second '=' is a relational operator that tests
-- equality
</eucode>

**Note:** When you wish to compare two strings (or other sequences), you
should **not** (as in some other languages) use the '=' operator:

<eucode>
if "APPLE" = "ORANGE" then  -- ERROR!
</eucode>

'##=##' is treated as an operator, just like '##+##', '##*##' etc., so it is
applied to
corresponding sequence elements, and the sequences must be the same length.
When they are equal length, the result is a sequence of ones an zeros. When they
are not equal length, the result is an error. Either way you'll get an error,
since an if-condition must be an atom, not a sequence.  Instead you should use
the ##equal## built-in routine:

<eucode>
if equal("APPLE", "ORANGE") then  -- CORRECT
</eucode>

In general, you can do relational comparisons using the ##compare## built-in
routine:

<eucode>
if compare("APPLE", "ORANGE") = 0 then  -- CORRECT
</eucode>

You can use ##compare## for other comparisons as well:

<eucode>
if compare("APPLE", "ORANGE") < 0 then  -- CORRECT
-- enter here if "APPLE" is less than "ORANGE" (TRUE)
</eucode>

Especially useful is the idiom ##compare(x, "") = 1## to determine whether ##x##
is a non empty sequence. ##compare(x, "") = -1## would test for ##x## being an
atom, but ##atom(x) = 1## does the same faster and is clearer to read.

==== Subscripting of Sequences

A single element of a sequence may be selected by giving the element number in
square brackets. Element numbers start at 1. Non-integer subscripts are rounded
down to an integer.

For example, if ##x## contains ##{5, 7.2, 9, 0.5, 13}## then ##x[2]## is
##7.2##. Suppose we assign something different to ##x[2]##:

<eucode>
x[2] = {11,22,33}
</eucode>

Then ##x## becomes: ##{5, {11,22,33}, 9, 0.5, 13}##. Now if we ask for
##x[2]## we get ##{11,22,33}## and if we ask for ##x[2][3]## we get the
##atom## 33. If you try to subscript with a number that is outside of the range
##1## to the number of elements, you will get a subscript error. For example
##x[0]##,  ##x[-99]## or ##x[6]## will cause errors. So will ##x[1][3]## since
##x[1]## is not a sequence. There is no limit to the number of subscripts that
may follow a variable, but the variable must contain sequences that are nested
deeply enough. The two dimensional array, common in other languages, can be
easily represented with a sequence of sequences:

<eucode>
x = {
    {5, 6, 7, 8, 9},      -- x[1]
    {1, 2, 3, 4, 5},      -- x[2]
    {0, 1, 0, 1, 0}       -- x[3]
}
</eucode>

where we have written the numbers in a way that makes the structure
clearer. An expression of the form x[i][j] can be used to access any element.

The two dimensions are not symmetric however, since an entire "row" can be
selected with x[i], but you need to use [[:vslice]] in the Standard Library
to select an entire column. Other logical structures, such as n-dimensional
arrays, arrays of strings, structures, arrays of structures etc. can also be
handled easily and flexibly:

3-D array:

<eucode>
y = {
    {{1,1}, {3,3}, {5,5}},
    {{0,0}, {0,1}, {9,1}},
    {{-1,9},{1,1}, {2,2}}
}

-- y[2][3][1] is 9
</eucode>

Array of strings:

<eucode>
s = {"Hello", "World", "Euphoria", "", "Last One"}

-- s[3] is "Euphoria"
-- s[3][1] is 'E'
</eucode>

A Structure:

<eucode>
employee = {
    {"John","Smith"},
    45000,
    27,
    185.5
}
</eucode>

To access "fields" or elements within a structure it is good programming style
to make up an enum that names the various fields. This will make your program
easier to read. For the example above you might have:

<eucode>
enum NAME, SALARY, AGE, WEIGHT
enum FIRST_NAME, LAST_NAME

employees = {
    {{"John","Smith"}, 45000, 27, 185.5},   -- a[1]
    {{"Bill","Jones"}, 57000, 48, 177.2},   -- a[2]
    -- .... etc.
}

-- employees[2][SALARY] would be 57000.
</eucode>

The ##length## built-in function will tell you how many elements are in a
sequence.  So the last element of a sequence ##s##, is:

<eucode>
s[length(s)]
</eucode>

A short-hand for this is:

<eucode>
s[$]
</eucode>

Similarly,

<eucode>
s[length(s)-1]
</eucode>

can be simplified to:

<eucode>
s[$-1]
</eucode>

The ##$## may only appear between square braces and it equals the length of the
sequence that is being subscripted. Where there's nesting, e.g.:

<eucode>
s[$ - t[$-1] + 1]
</eucode>

The first ##$## above refers to the length of ##s##, while the second ##$##
refers to the length of ##t## (as you'd probably expect).  An example where
##$## can save a lot of typing, make your code clearer, and probably even faster
is:

<eucode>
longname[$][$] -- last element of the last element
</eucode>

Compare that with the equivalent:

<eucode>
longname[length(longname)][length(longname[length(longname)])]
</eucode>

**Subscripting and function side-effects:**

In an assignment statement,
with left-hand-side subscripts:

<eucode>
lhs_var[lhs_expr1][lhs_expr2]... = rhs_expr
</eucode>

The expressions are evaluated, and any subscripting is performed, from left
to right. It is possible to have function calls in the right-hand-side
expression, or in any of the left-hand-side expressions.  If a function call
has the side-effect of modifying the lhs_var, it is not defined whether those
changes will appear in the final value of the lhs_var, once the assignment has
been completed.  To be sure about what is going to happen, perform the function
call in a separate statement, i.e. do not try to modify the lhs_var in two
different ways in the same statement.  Where there are no left-hand-side
subscripts, you can always assume that the final value of the lhs_var will be
the value of rhs_expr, regardless of any side-effects that may have changed
lhs_var.

**Euphoria data structures are almost infinitely flexible.**

Arrays in many
languages are constrained to have a fixed number of elements, and those
elements must all be of the same type. Euphoria eliminates both of those
restrictions by defining all arrays (sequences) as a list of zero or more
Euphoria objects whose element count can be changed at any time.
You can easily add a new structure to the employee sequence
above, or store an unusually long name in the NAME field and Euphoria will take
care of it for you. If you wish, you can store a variety of different employee
"structures", with different sizes, all in one sequence. However, when you
retrieve a sequence element, it is not guaranteed to be of any type. You, as a
programmer, need to check that the retrieved data is of the type you'd expect,
Euphoria will not. The only thing it will check is whether an assignment is
legal. For example, if you try to assign a sequence to an integer variable,
Euphoria will complain at the time your code does the assignment.

Not only can a Euphoria program represent all conventional data
structures but you can create very useful, flexible structures that would be
hard to declare in many other languages.

Note that expressions in general may not be subscripted, just variables. For
example: ##{5+2,6-1,7*8,8+1}[3]## is //not// supported, nor is something like:
##date()[MONTH]##. You have to assign the sequence returned by ##date## to a
variable, then subscript the variable to get the month.

==== Slicing of Sequences

A sequence of consecutive elements may be selected by giving the starting and
ending element numbers. For example if ##x## is ##{1, 1, 2, 2, 2, 1, 1, 1}##
then ##x[3..5]## is the sequence ##{2, 2, 2}##. ##x[3..3]## is the sequence
##{2}##. ##x[3..2]## is also allowed. It evaluates to the zero length sequence
##{}##.  If ##y## has the value: ##{"fred", "george", "mary"}## then
##y[1..2]## is ##{"fred", "george"}##.

We can also use slices for overwriting portions of variables. After
##x[3..5] = {9, 9, 9}## ##x## would be ##{1, 1, 9, 9, 9, 1, 1, 1}##. We could
also have said ##x[3..5] = 9## with the same effect. Suppose ##y## is
##{0, "Euphoria", 1, 1}##. Then ##y[2][1..4]## is ##"Euph"##. If we say
##y[2][1..4] = "ABCD"## then ##y## will become  ##{0, "ABCDoria", 1, 1}##.

In general, a variable name can be followed by 0 or more subscripts, followed
in turn by 0 or 1 slices. Only variables may be subscripted or sliced, not
expressions.

We need to be a bit more precise in defining the rules for **empty
slices**. Consider a slice ##s[i..j]## where ##s## is of length ##n##. A slice
from ##i## to ##j##, where  ##j = i - 1##  and ##i >= 1## produces the
[[:emptyseq "empty sequence"]],
even if ##i = n + 1##. Thus
##1..0## and ##n + 1..n## and everything in between are legal
**(empty) slices**.  Empty
slices are quite useful in many algorithms. A slice from ##i## to ##j## where
##j < i - 1## is illegal , i.e. "reverse" slices such as ##s[5..3]## are not
allowed.

We can also use the ##$## shorthand with slices, e.g.

<eucode>
s[2..$]
s[5..$-2]
s[$-5..$]
s[$][1..floor($/2)] -- first half of the last element of s
</eucode>

==== Concatenation of Sequences and Atoms - The '&' Operator ====
@[amp concat|]
@[amp_concat|]

Any two objects may be concatenated using the **&** operator. The
result is a sequence with a length equal to the sum of the lengths of the
concatenated objects.
e.g.

<eucode>
{1, 2, 3} & 4              -- {1, 2, 3, 4}

4 & 5                      -- {4, 5}

{{1, 1}, 2, 3} & {4, 5}    -- {{1, 1}, 2, 3, 4, 5}

x = {}
y = {1, 2}
y = y & x                  -- y is still {1, 2}
</eucode>

You can delete element ##i## of any sequence s by concatenating the parts of the
sequence before and after ##i##:

<eucode>
s = s[1..i-1] & s[i+1..length(s)]
</eucode>

This works even when ##i## is ##1## or ##length(s)##, since ##s[1..0]## is a
legal empty slice, and so is ##s[length(s)+1..length(s)]##.

==== Sequence-Formation

Finally, sequence-formation, using braces and commas:

<eucode>
{a, b, c, ... }
</eucode>

is also an operator. It takes n operands, where ##n## is ##0## or more, and
makes an n-element sequence from their values. e.g.

<eucode>
x = {apple, orange*2, {1,2,3}, 99/4+foobar}
</eucode>

The sequence-formation operator is listed at the bottom of the a
[[:precedence chart]].

==== Multiple Assignment

Special sequence notation on the left hand side of an assignment can be made to
assign to multiple variables with a single statement.  This can be useful for
using functions that return multiple values in a sequence, such as ##[[:value]]##.

<eucode>
atom success, val

{ success, val } = value( "100" )

-- success = GET_SUCCESS
-- val = 100
</eucode>

It is also possible to ignore some of the values in the right hand side.  Any
elements beyond the number supplied on the left hand side are ignored.  Other
values can also be ignored by using a question mark ('##?##') instead of a variable
name:

<eucode>
{ ?, val } = value( "100" )
</eucode>

Variables may only appear once on the left hand side, however, they may appear
on both the left and right hand side.  For instance, to swap the values of two
variables:

<eucode>
{ a, b } = { b, a }
</eucode>

==== Other Operations on Sequences

Some other important operations that you can perform on sequences have English
names, rather than special characters. These operations are built-in to
**eui.exe/euiw.exe**, so they'll always be there, and so they'll be fast. They
are described in detail in the [[:Language Reference]], but are
important enough to Euphoria programming that we should mention them here before
proceeding. You call these operations as if they were subroutines, although
they are actually implemented much more efficiently than that.

===== length(sequence s)

Returns the length of a sequence s.

This is the number of elements in s. Some of these elements may be
sequences that contain elements of their own, but ##length## just gives you the
"top-level" count. Note however that the length of an atom is always ##1##.
e.g.

<eucode>
length({5,6,7})             -- 3
length({1, {5,5,5}, 2, 3})  -- 4 (not 6!)
length({})                  -- 0
length(5)                   -- 1
</eucode>

===== repeat(object o1, integer count)

Returns a sequence that consists of an item repeated count times.
e.g.

<eucode>
repeat(0, 100)         -- {0,0,0,...,0}   i.e. 100 zeros
repeat("Hello", 3)     -- {"Hello", "Hello", "Hello"}
repeat(99,0)           -- {}
</eucode>

The item to be repeated can be any atom or sequence.

===== append(sequence s1, object o1)

Returns a sequence by adding an object o1 to the end of a sequence
s1.

<eucode>
append({1,2,3}, 4)         -- {1,2,3,4}
append({1,2,3}, {5,5,5})   -- {1,2,3,{5,5,5}}
append({}, 9)              -- {9}
</eucode>

The length of the new sequence is always 1 greater than the length of
the original sequence. The item to be added to the sequence can be any atom or
sequence.

===== prepend(sequence s1, object o1)

Returns a new sequence by adding an element to the beginning of a
sequence s. e.g.

<eucode>
append({1,2,3}, 4)         -- {1,2,3,4}
prepend({1,2,3}, 4)        -- {4,1,2,3}

append({1,2,3}, {5,5,5})   -- {1,2,3,{5,5,5}}
prepend({}, 9)             -- {9}
append({}, 9)              -- {9}
</eucode>

The length of the new sequence is always one greater than the length of
the original sequence. The item to be added to the sequence can be any atom or
sequence.

These two built-in functions, ##append## and
##prepend##, have some similarities to the concatenate operator,
##&##, but there are clear differences. e.g.

<eucode>
-- appending a sequence is different
append({1,2,3}, {5,5,5})   -- {1,2,3,{5,5,5}}
{1,2,3} & {5,5,5}          -- {1,2,3,5,5,5}

-- appending an atom is the same
append({1,2,3}, 5)         -- {1,2,3,5}
{1,2,3} & 5                -- {1,2,3,5}
</eucode>

===== insert(sequence in_what, object what, atom position)

This function takes a target sequence, in_what, shifts its tail one notch and
plugs the object what in the hole just created. The modified sequence is
returned. For instance:

<eucode>
s = insert("Joe",'h',3)     -- s is "Johe", another string
s = insert("Joe","h",3)     -- s is {'J','o',{'h'},'e'}, not a string
s = insert({1,2,3},4,-0.5)  -- s is {4,1,2,3}, like prepend()
s = insert({1,2,3},4,8.5)   -- s is {1,2,3,4}, like append()
</eucode>

The length of the returned sequence is one more than the one of ##in_what##.
This is the same rule as for ##append## and ##prepend## above, which are
actually special cases of ##insert##.

===== splice(sequence in_what, object what, atom position)

If what is an ##atom##, this is the same as ##insert##. But if what is a
sequence, that sequence is inserted as successive elements into ##in_what##
at ##position##. Example:

<eucode>
s = splice("Joe",'h',3)
    -- s is "Johe", like insert()
s = splice("Joe","hn Do",3)
    -- s is "John Doe", another string
s = splice("Joh","n Doe",9.3)
    -- s is "John Doe", like with the & operator
s = splice({1,2,3},4,-2)
    -- s is {4,1,2,3}, like with the & operator in reversed order
</eucode>

The length of ##splice(in_what, what, position)## always is ##length(in_what)
+ length(what)##, like for concatenation using ##&##.

=== Precedence Chart

When two or more operators follow one another in an expression, there must be
rules to tell in which order they should be evaluated, as different orders
usually lead to different results. It is common and convenient to use a
**precedence order** on operators. Operators with the highest degree of
precedence are evaluated first, then those with highest precedence
among what remains, and so on.

The precedence of operators in expressions is as follows:

**highest precedence**

{{{
**highest precedence**

function/type calls
unary-  unary+  not
*  /
+  -
&
<  >  <=  >=  =  !=
and  or  xor
}}}

**lowest precedence**
{{{
{ , , , }
}}}

Thus ##2+6*3## means ##2+(6*3)## rather than ##(2+6)*3##. Operators on the same
line
above have equal precedence and are evaluated left to right. You can force
any order of operations by placing round brackets ##( )## around an expression.
For instance, ##6/3*5## is ##2*5##, not ##6/15##.

Different languages or contexts may have slightly different precedence rules.
You should be careful when translating a formula from a language to another;
Euphoria is no exception. Adding superfluous parentheses to explicitly denote
the exact order of evaluation does not cost much, and may help either readers
used to some other precedence chart or translating to or from another context
with slightly different rules. Watch out for ##and## and ##or##, or
##*## and ##/##.

The equals symbol ##'='## used in an [[:assignment statement]] is not an
operator, it's just part of the syntax of the language.

%%output=lang_decl
== Declarations
:<<LEVELTOC level=2 depth=4>>
=== Identifiers

**Identifiers**, which encompass all explicitly declared variable, constant
or routine names, may be of any length. Upper and lower case are distinct.
Identifiers must start with a letter or underscore and then be followed by
any combination of letters, digits and underscores. The following
**reserved words** have special meaning in Euphoria and cannot be used
as identifiers:


!! tom ... colored links not working 

!!@@(k <<font color="#0000FF" text=`$(0)`>>)@
!!@@(b <<font color="#9900CC" text=`$(0)`>>)@
!!
!! |$$(k and             )|$$(k export           )|$$(k public )|
!! |$$(k  as              )|$$(k fallthru         )|$$(k retry    )|
!! |$$(k  break           )|$$(k for              )|$$(k return  )|
!! |$$(k by              )|$$(k function         )|$$(k routine  )|
!! |$$(k case            )|$$(k global           )|$$(k switch  )|
!! |$$(k constant        )|$$(k goto             )|$$(k then  )|
!! |$$(k continue        )|$$(k if               )|$$(k to  )|
!! |$$(k do              )|$$(k ifdef            )|$$(k type  )|
!! |$$(k else            )|$$(k include          )|$$(k until  )|
!! |$$(k elsedef         )|$$(k label            )|$$(k while  )|
!! |$$(k elsif           )|$$(k loop             )|$$(k with  )|
!! |$$(k elsifdef        )|$$(k namespace        )|$$(k without  )|
!! |$$(k end             )|$$(k not              )|$$(k xor  )|
!! |$$(k entry           )|$$(k or  )||
!! |$$(k enum            )|$$(k override  )||
!! |$$(k exit            )|$$(k procedure   )||

!!@@(k <<font color="#0000FF" text=`$(0)`>>)@
!!@@(b <<font color="#9900CC" text=`$(0)`>>)@

<eucode>
and             export           public 
as              fallthru         retry  
break           for              return 
by              function         routine
case            global           switch 
constant        goto             then
continue        if               to 
do              ifdef            type 
else            include          until
elsedef         label            while
elsif           loop             with 
elsifdef        namespace        without
end             not              xor 
entry           or
enum            override
exit            procedure
</eucode>





For example, the ##edx## editor displays these words in blue.

The following are Euphoria built-in routines. It is best if you do
not use these for your own identifiers:

<eucode>
abort           getenv          peek4s          system
and_bits        gets            peek4u          system_exec
append          hash            peeks           tail
arctan          head            platform        tan
atom            include_paths   poke            task_clock_start
c_func          insert          poke2           task_clock_stop
c_proc          integer         poke4           task_create
call            length          position        task_list
call_func       log             power           task_schedule
call_proc       machine_func    prepend         task_self
clear_screen    machine_proc    print           task_status
close           match           printf          task_suspend
command_line    match_from      puts            task_yield
compare         mem_copy        rand            time
cos             mem_set         remainder       trace
date            not_bits        remove          xor_bits
delete          object          repeat          ?
delete_routine  open            replace         &
equal           option_switches routine_id      $
find            or_bits         sequence        
find_from       peek            sin             
floor           peek_string     splice          
get_key         peek2s          sprintf
getc            peek2u          sqrt
</eucode>


Identifiers can be used in naming the following:

* procedures
* functions
* types
* variables
* constants
* enums

@[end|]
==== procedures

These perform some computation and may contain a list of parameters, e.g.

<eucode>
procedure empty()
end procedure

procedure plot(integer x, integer y)
    position(x, y)
    puts(1, '*')
end procedure
</eucode>

There are a fixed number of named parameters, but this is not restrictive since
any parameter could be a variable-length sequence of arbitrary objects. In many
languages variable-length parameter lists are impossible.  In C, you must set
up strange mechanisms that are complex enough that the average programmer
cannot do it without consulting a manual or a local guru.

A copy of the value of each argument is passed in. The formal parameter
variables may be modified inside the procedure but this does not affect the
value of the arguments. Pass by reference can be achieved using indexes into
some fixed sequence.

;**Performance Note~:**
:The interpreter does not actually copy sequences or floating-point numbers
unless it becomes necessary. For example,
<eucode>
y = {1,2,3,4,5,6,7,8.5,"ABC"}
x = y
</eucode>
The statement ##x = y## does not actually cause a new copy of ##y## to be 
created. Both ##x## and ##y## will simply "point" to the same sequence. If we 
later perform ##x[3] = 9##, then a separate sequence will be created for ##x## 
in memory (although there will still be just one shared copy of ##8.5## and 
##"ABC"##). The same thing applies to
"copies" of arguments passed in to subroutines.

For a number of procedures or functions~--see below~--some parameters
may have the same value in many cases. The most expected value for any parameter
may be given a default value. To pass the default value, use a question mark ##?##,
or omit the value.  When the parameter is not the last in the list to the routine,
you should use the ##?## for clarity, rather than simply omitting the parameter,
and having consecutive commas.

<eucode>
procedure foo(sequence s, integer n=1)
    ? n + length(s)
end procedure

foo("abc")     -- prints out 4 = 3 + 1. n was not specified, so was set to 1.
foo("abc", ? ) -- prints out 4 = 3 + 1. n was not specified, so was set to 1.
foo("abc", 3)  -- prints out 6 = 3 + 3
</eucode>

This is not limited to the last parameter(s):

<eucode>
procedure bar(sequence s="abc", integer n, integer p=1)
    ? length(s)+n+p
end procedure

bar(?, 2)     -- prints out 6 = 3 + 2 + 1
bar(, 2)      -- prints out 6 = 3 + 2 + 1.  Legal, but considered bad form.
bar(2)        -- errors out, as 2 is not a sequence
bar(?, 2, ?)  -- same as bar(,2)
bar(?, 2, 3)  -- prints out 8 = 3 + 22 + 3
bar({}, 2, ?) -- prints out 3 = 0 + 2 + 1
bar()         -- errors out, second parameter is omitted,
              -- but doesn't have a default value
</eucode>

Any expression may be used in a default value. Parameters that have been
already mentioned may even be part of the expression:

<eucode>
procedure baz(sequence s, integer n=length(s))
    ? n
end procedure

baz("abcd") -- prints out 4
</eucode>

==== functions

These are just like procedures, but they return a value, and can be used in an
expression, e.g.

<eucode>
function max(atom a, atom b)
    if a >= b then
        return a
    else
        return b
    end if
end function
</eucode>

==== return statement

Any Euphoria object can be returned.  You can, in effect, have multiple return
values, by returning a sequence of objects. e.g.

<eucode>
return {x_pos, y_pos}
</eucode>

However, Euphoria does not have variable lists. When you return a sequence, you
still have to dispatch its contents to variables as needed. And you cannot pass
a sequence of parameters to a routine, unless using [[:call_func]] or
[[:call_proc]], which carries a performance penalty.

We will use the general term "subroutine", or simply "routine" when a remark is
applicable to both procedures and functions.

Defaulted parameters can be used in functions exactly as they are in
procedures. See the section above for a few examples.

==== types

These are special functions that may be used in declaring the allowed values
for a variable. A type must have exactly one parameter and should return an
atom that is either true (non-zero) or false (zero).  Types can also be called
just like other functions. See [[:Specifying the Type of a variable]].

Although there are no restrictions to using defaulted parameters with types,
their use is so much constrained by a type having exactly one parameter that
they are of little practical help there.

You cannot use a type to perform any adjustment to the value being checked, if
only because this value may be the temporary result of an expression, not an
actual variable.

==== variables

These may be assigned values during execution e.g.

<eucode>
-- x may only be assigned integer values
integer x
x = 25

-- a, b and c may be assigned *any* value
object a, b, c
a = {}
b = a
c = 0
</eucode>

When you declare a variable you name the variable (which protects you against
making spelling mistakes later on) and you define which sort of values may
legally be assigned to the variable during execution of your program.

The simple act of declaring a variable does not assign any value to it. If you
attempt to read it before assigning any value to it, Euphoria will issue a
run-time error as "variable xyz has never been assigned a value".

To guard against forgetting to initialize a variable, and also because it may
make the code clearer to read, you can combine declaration and assignment:

<eucode>
integer n = 5
</eucode>

This is equivalent to

<eucode>
integer n
n = 5
</eucode>

It is not infrequent that one defines a private variable that bears the same
name as one already in scope. You can reuse the value of that variable when
performing an initialization on declare by using a default namespace for the
current file:

<eucode>
namespace app

integer n
n=5

procedure foo()
    integer n = app:n + 2
    ? n
end procedure

foo() -- prints out 7
</eucode>

==== constants

These are variables that are assigned an initial value that can never change
e.g.

<eucode>
constant MAX = 100
constant Upper = MAX - 10, Lower = 5
constant name_list = {"Fred", "George", "Larry"}
</eucode>

The result of any expression can be assigned to a constant, even one involving
calls to previously defined functions, but once the assignment is made, the
value of the constant variable is "locked in".

Constants may not be declared inside a subroutine.

==== enum

An enumerated value is a special type of constant where the first value
defaults to the number 1 and each item after that is incremented by 1 by default. An
optional ##by## keyword can be supplied to change the increment value. As with sequences,
enums can also be terminated with a ##$## for ease of editing ##enum## lists that may
change frequently during development.

<eucode>
enum ONE, TWO, THREE, FOUR

-- ONE is 1, TWO is 2, THREE is 3, FOUR is 4
</eucode>

You can change the value of any one item by assigning it a numeric value. Enums
can only take numeric values. You cannot set the starting value to an
expression or other variable. Subsequent values are always the previous value
plus one, unless they too are assigned a default value.

<eucode>
enum ONE, TWO, THREE, ABC=10, DEF, XYZ

-- ONE is 1, TWO is 2, THREE is 3
-- ABC is 10, DEF is 11, XYZ is 12
</eucode>

Euphoria sequences use integer indexes, but with ##enum## you may write code
like this:

<eucode>
enum X, Y
sequence point = { 0,0 }
point[X] = 3
point[Y] = 4
</eucode>

By default, unless an enum member is being specifically set to some value, its
value
will be one more than the previous member's value, with the first default value
being ##1##. This default can be overridden. The syntax is:

<eucode>
enum by DELTA member1, member2, ... ,memberN
</eucode>
where ##'DELTA'## is a literal number with an optional operation code 
(##*, +, -, /##) preceding it.

Examples:
<eucode>
enum by 2 A,B,C=6,D      --> values are 1,3,6,8
enum by -2 A=10,B,C,D    --> values are 10,8,6,4
enum by * 2 A,B,C,D,E    --> values are 1,2,4,8,16
enum by / 3 A=81,B,C,D,E --> values are 81,27,9,3,1
</eucode>

Also note that enum members do not have to be integers.
<eucode>
enum by / 2 A=5,B,C --> values are 5, 2.5, 1.25
</eucode>

==== enum type

There is also a special form of ##enum##, an //enum type//. This is a simple way
to write a user-defined type based on the set of values in a specific enum 
group.
The type created this way can be used anywhere a normal user-defined type can be
use.

For example,
<eucode>
enum type RGBA RED, GREEN, BLUE, ALPHA end type

-- Only allow values of RED, GREEN, BLUE, or ALPHA as parameters
procedure xyz( RGBA x, RGBA y)
	-- do stuff...
end procedure
</eucode>

However there is one significant difference when it comes to enum types. For
normal types, when calling the type function, it returns either ##0## or ##1##. 
The enum type function returns ##0## if the argument is not a member of the 
enum set, and it
returns a positive integer when the argument is a member. The value returned is
the ordinal number of
the member in the enum's definition, regardless of what the member's value is.
As an exception to this, if two enums share the same value, then they will
share the same ordinal number. The ordinal numbers of enums surrounding these
will continue to increment as if every enum had a unique ordinal number,
causing some numbers to be skipped.

For example,
<eucode>
enum type color RED=4, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type

? color(RED)   --> 1
? color(GREEN) --> 2
? color(BLACK) --> 3
? color(BLUE)  --> 4
? color(PINK)  --> 5

constant color_names = {"rouge", "vert", "noir", "bleu", "rose"}

puts(1, color_names[color(BLUE)]) --> bleu

</eucode>

But with the exception, 
<eucode>
enum type color RED, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type
? color(RED) --> 1
? color(GREEN) --> 2
? color(BLACK) --> 1
? color(BLUE) --> 4
? color(PINK) --> 5
</eucode>

Note that none of the enums have an ordinal number with a value of 3. This is
simply skipped.


=== Specifying the type of a variable

So far you've already seen some examples of variable types but now we will
define types more precisely.

Variable declarations have a type name followed by a list of the variables
being declared. For example,

<eucode>
object a

global integer x, y, z

procedure fred(sequence q, sequence r)
</eucode>

The types: **object**, **sequence**, **atom** and **integer** are
**predefined**.  Variables of type **object** may take on //any// value.  Those
declared with type **sequence** must always be sequences.  Those declared with
type **atom** must always be atoms.

Variables declared with type **integer** must be atoms with
integer values from ##-1073741824## to ##+1073741823## inclusive. You can 
perform exact
calculations on larger integer values, up to about ##15## decimal digits, but
declare them as **atom**, rather than integer.

;**Note~:**
:In a procedure or function parameter list like the one for ##fred## above, 
a type name may only be followed by a single parameter name.

;**Performance Note~:**
:Calculations using variables declared as integer will usually be somewhat
faster than calculations involving variables declared as atom. If your machine
has floating-point hardware, Euphoria will use it to manipulate atoms that
are not integers. If your machine doesn't have floating-point
hardware (this may happen on old 386 or 486 PCs), Euphoria will call software
floating-point
arithmetic routines contained in **euid.exe** (or in //Windows//). You can force
##eui.exe## to
bypass any floating-point hardware, by setting an environment variable:
<eucode>
SET NO87=1
</eucode>
The slower software routines will be used, but this could be of some advantage
if you are worried about the floating-point bug in some early Pentium
chips.

@[udt|]
==== User-defined types

To augment the [[:predefined types]], you can create **user-defined types**. All
 you have to
do is define a single-parameter function, but declare it with **type ...
end type** instead of **function ... end function**.  For
example,

<eucode>
type hour(integer x)
    return x >= 0 and x <= 23
end type

hour h1, h2

h1 = 10      -- ok
h2 = 25      -- error! program aborts with a message
</eucode>

Variables ##h1## and ##h2## can only be assigned integer values in the range 
##0## to ##23##
inclusive. After each assignment to ##h1## or ##h2## the interpreter will call 
##hour##,
passing the new value.  The value will first be checked to see if it is an
integer (because of "integer x"). If it is, the return statement will be
executed to test the value of ##x## (i.e. the new value of ##h1## or ##h2##).  
If ##hour##
returns true, execution continues normally. If ##hour## returns false then the
program is aborted with a suitable diagnostic message.

"hour" can be used to declare subroutine parameters as well:

<eucode>
procedure set_time(hour h)
</eucode>

##set_time## can only be called with a reasonable value for parameter ##h##,
otherwise the program will abort with a message.

A variable's type will be checked after each assignment to the variable (except
where the compiler can predetermine that a check will not be necessary), and
the program will terminate immediately if the type function returns false.
Subroutine parameter types are checked each time that the subroutine is called.
This checking guarantees that a variable can never have a value that does not
belong to the type of that variable.

Unlike other languages, the type of a variable does not affect any calculations
on the variable, nor the way its contents are displayed. Only the value of the
variable matters
in an expression. The type just serves as an error check to prevent any
"corruption" of the variable.    User-defined types can catch unexpected
logical errors in your program.  They are not designed to catch or correct user
input errors. In particular, they cannot adjust a wrong value to some other,
presumably legal, one.

@[type_check|]
Type checking can be turned off or on between subroutines using the with
##type_check## or ##without type_check## (see [[:specialstatements]]).
It is initially on by default.

;**Note to Bench markers~:**
: When comparing the speed of Euphoria programs against programs written in
other languages, you should specify **without type_check** at the top of
the file.  This gives Euphoria permission to skip run-time type checks, thereby
saving some execution time. All other checks are still performed, e.g.
subscript checking, uninitialized variable checking etc.  Even when you turn
off type checking, Euphoria reserves the right to make checks at strategic
places, since this can actually allow it to run your program //faster// in
many cases.  So you may still get a type check failure even when you have
turned off type checking. Whether type checking is on or off, you will never
get a **//machine-level//** exception.  **You will always get a
meaningful message from Euphoria when something goes wrong**.  (//This
might not be the case when you [[:poke]] directly
!!zzzz-------------------------^^^^^^^^^
into memory, or call routines written in C or machine code.//)

Euphoria's way of defining types is simpler than what you will find in other
languages, yet Euphoria provides the programmer with //greater// flexibility
in defining the legal values for a type of data. Any algorithm can be used to
include or exclude values. You can even declare a variable to be of type object
which will allow it to take on //any// value. Routines can be written to
work with very specific types, or very general types.

For many programs, there is little advantage in defining new types, and you may
wish to stick with the four [[:predefined types]].
Unlike other languages, Euphoria's type mechanism is optional.  You don't need
it to create a program.

However, for larger programs, strict type definitions can aid the process of
debugging.  Logic errors are caught close to their source and are not allowed
to propagate in subtle ways through the rest of the program.  Furthermore, it
is easier to reason about the misbehavior of a section of code when you are
guaranteed that the variables involved always had a legal value, if not the
desired value.

Types also provide meaningful, machine-checkable documentation about your
program, making it easier for you or others to understand your code at a later
date. Combined with the subscript checking,
uninitialized variable checking, and other checking that is always present,
strict run-time type checking makes debugging much easier in Euphoria than in
most other languages. It also increases the reliability of the final program
since many latent bugs that would have survived the testing phase in other
languages will have been caught by Euphoria.

;**Anecdote 1~:**
: In porting a large C program to Euphoria, a number of latent bugs were
discovered. Although this C program was believed to be totally "correct", we
found: a situation where an uninitialized variable was being read; a place
where element number "-1" of an array was routinely written and read; and a
situation where something was written just off the screen. These problems
resulted in errors that weren't easily visible to a casual observer, so they
had survived testing of the C code.

;**Anecdote 2~:**
:The Quick Sort algorithm presented on page 117 of //Writing Efficient
Programs// by Jon Bentley has a subscript error! The algorithm will sometimes
read the element just //before// the beginning of the array to be sorted,
and will sometimes read the element just //after// the end of the array.
Whatever garbage is read, the algorithm will still work - this is probably why
the bug was never caught. But what if there isn't any (virtual) memory just
before or just after the array? Bentley later modifies the algorithm such that
this bug goes away~--but he presented this version as being correct.
**//Even the experts need subscript checking!//**

;**Performance Note~:**
:When typical user-defined types are used extensively, type checking adds only
20 to 40 percent to execution time. Leave it on unless you really need the
extra speed. You might also consider turning it off for just a few
heavily-executed routines.  [[:Profiling]] can help with this decision.

==== integer

An Euphoria ##integer## is a mathematical integer restricted to the range
##-1,073,741,824## to ##+1,073,741,823##.
As a result, a variable of the integer type, while allowing computations as fast
as possible, cannot hold 32-bit machine addresses, even though the latter are
mathematical integers. You must use the [[:atom]] type for this purpose. Also,
even though the product of two integers is a mathematical integer, it may not
fit into an integer, and should be kept in an atom instead.

==== atom

An ##atom## can hold three kinds of data:
* Mathematical integers in the range ##-power(2,53)## to +##power(2,53)##
* Floating point numbers, in the range ##-power(2,1024)+1## to ##+power(2,1024)-1##
* Large mathematical integers in the same range, but with a fuzz that grows
 with the magnitude of the integer.

##power(2,53)## is slightly above 9.10^^15^^, ##power(2,1024)## is in the
10^^308^^ range.

Because of these constraints, which arise in part from common hardware
limitations, some care is needed for specific purposes:
* The sum or product of two integers is an ##atom##, but may not be an
##integer##.
* Memory addresses, or handles acquired from anything non Euphoria, including
the operating system, **must** be stored as an ##atom##.
* For large numbers, usual operations may yield strange results:
<eucode>
integer n = power(2, 27) -- ok
integer n_plus = n + 1, n_minus = n - 1 -- ok
atom a = n * n -- ok
atom a1 = n_plus * n_minus -- still ok
? a - a1 -- prints 0, should be 1 mathematically
</eucode>

//This is not an Euphoria bug//. The IEEE 754 standard for floating point
numbers provides for 53 bits of precision for any real number, and an accurate
computation of ##a-a1## would require 54 of them. Intel FPU chips do have 64 bit
precision registers, but the low order 16 bits are only
used internally, and Intel recommends against using them for high precision
arithmetic. Their SIMD machine instruction set only uses the IEEE 754 defined
format.

==== sequence

A sequence is a type that is a //container//. A sequence has //elements// which
can be accessed through their //index//, like in ##my_sequence[3]##.
##sequence##s are so generic as being able to store all sorts of data
structures: strings, trees, lists, anything. Accesses to sequences are always
bound checked, so that you cannot read or write an element that does not exist,
ever. A large amount of extraction and shape change operations on
sequences is available, both as built-in operations and library routines. The
elements of a sequence can have any type.

##sequence##s are implemented very efficiently. Programmers used to pointers
will soon notice that they can get most usual pointer operations done using
sequence indexes. The loss in efficiency is usually hard to notice, and the gain
in code safety and bug prevention far outweighs it.

==== object

This type can hold any data Euphoria can handle, both atoms and sequences.

The ##object## type returns 0 if a variable is not initialized, else ##1##.

=== Scope

==== Why scopes, and what are they?

The //scope// of an identifier is the portion of the program where its
declaration is in effect, i.e. where that identifier is //visible//.

Euphoria has many pre-defined procedures, functions and types.  These are
defined automatically at the start of any program.  For exmaple, the ##edx## editor shows
them in magenta. These pre-defined names are not reserved. You can override
them with your own variables or routines.

It is possible to use a user-defined identifier before it has been declared,
provided that it will be declared at some point later in the program.

For example, procedures, functions and types can call themselves or one another
//recursively//. Mutual
recursion, where routine A calls routine B which directly or indirectly calls
routine A, implies one of A or B being called before it is defined. This was
traditionally the most frequent situation which required using the
[[:routine_id]] mechanism, but is now supported directly.
See [[:Indirect Routine Calling]] for more details on the [[:routine_id]]
mechanism.

==== Defining the scope of an identifier

The scope of an identifier is a description of what code can 'access' it. Code
in the same scope of an identifier can access that identifier and code not in
the same scope cannot access it.

The scope of a **variable** depends upon where and how it is declared.
* If it is declared within a ##**for**##, ##**while**##, ##**loop**## or
##**switch**##, its scope starts at the declaration and ends at the respective
##**end**## statement.
* In an ##**if**## statement, the scope starts at the declaration and ends
either at the next ##**else**##, ##**elsif**## or ##**end if**## statement.
* If a variable is declared within a routine (known as a private variable) and
outside one of the structures listed above, the scope of the variable starts at
the declaration and ends at the routine's ##**end**## statement.
* If a variable is declared outside of a routine (known as a module variable),
and does not have a scope modifier, its scope starts at the declaration and ends
at the end of the file it is declared in.

The scope of a **constant** that does not have a scope modifier, starts at the
declaration and ends at the end of the file it is declared in.

The scope of a **enum** that does not have a scope modifier, starts at the
declaration and ends at the end of the file it is declared in.

The scope of all **procedures**, **functions** and **types**, which do not have
a scope modifier, starts at the beginning of the source file and ends at the end
of the source file in which they are declared. In other words, these can be
accessed by any code in the same file.

Constants, enums, module variables, procedures, functions and types, which do
not have a scope modifier are referred to as **local**. However, these
identifiers can have a scope modifier preceding their declaration, which causes
their scope to extend beyond the file they are declared in.
* If the keyword **global** precedes the declaration, the scope of these
identifiers extends to the whole application. They can be accessed by code
anywhere in the application files.
* If the keyword **public** precedes the declaration, the scope extends to any
file that explicitly includes the file in which the identifier is declared, or
to any file that includes a file that in turn ##public include##s the file
containing the ##public## declaration.
* If the keyword **export** precedes the declaration, the scope only extends to
any file that directly includes the file in which the identifier is declared.

When you **[[:include]]** a Euphoria file in another file, only the identifiers
!!zzzz-----^^^^^^^^^^^^^^ 
declared using a scope modifier are accessible to the file doing the include.
The other declarations in the included file are invisible to the file doing the
include, and you will get an error message, "##Errors resolving the following
references##", if you try to use them.

There is a variant of the **include** statement, called **public include**,
which will be discussed later and behaves differently on **public** symbols.

Note that **constant** and **enum** declarations must be outside of any
subroutine.

Euphoria encourages you to restrict the scope of identifiers. If all identifiers
were automatically global to the whole program, you might have a lot of naming
conflicts, especially in a large program consisting of files written by many
different programmers. A naming conflict might cause a compiler error message,
or it could lead to a very subtle bug, where different parts of a program
accidentally modify the same variable without being aware of it.  Try to use
the most restrictive scope that you can. Make variables
**private** to one routine where possible, and where that is not
possible, make them **local** to a file, rather than
**global** to the whole program. And whenever an identifier needs to be known
from  a few files only, make it **public** or **export** so as to hide it from
whoever does not need to see it ~-- and might some day define the same
identifier.

For example:
<eucode>
-- sublib.e
export procedure bar()
?0
end procedure

-- some_lib.e
include sublib.e
export procedure foo()
?1
end procedure
bar() -- ok, declared in sublib.e

-- my_app.exw
include some_lib.e
foo() -- ok, declared in some_lib.e
bar() -- error! bar() is not declared here
</eucode>

Why not declare ##foo## as global, as it is meant to be used anywhere? Well,
one could, but this will increase the risks of name conflicts. This is why, for
instance, all public identifiers from the standard library have **public**
scope. **global** should be used rarely, if ever. Because earlier versions of
Euphoria didn't have **public** or **export**, it has to remain there for a
while. One should be very sure of not polluting any foreign file's
symbol table before using **global** scope.
Built-in identifiers act as if declared as **global** ~-- but they are not
declared in any
Euphoria coded file.


==== Using namespaces
@[namespace|]

Euphoria namespaces are used to disambiguate between symbols (routines, variables,
constants, etc) with the same names in different files. They may be declared as
a default namespace in a file for the convenience of the users of that file,
or they may be declared at the point where a file is included. Note that unlike
namespaces in some other languages, this does not provide a sandbox around the
symbols in the file. It is just an easy way to tell euphoria to look for a
symbol in a particular file.

Identifiers marked as ##global##, ##public## or ##export## are known as
//exposed// variables because they can be used in files other than the one they
were declared in.

All other identifiers can only be used within their own file. This information
is helpful when maintaining or enhancing the file, or when learning how to use
the file. You can make changes to the internal routines and variables, without
having to examine other files, or notify other users of the include file.

Sometimes, when using include files developed by others, you will encounter
a naming conflict.  One of the include file authors has used the same name for
a exposed identifier as one of the other authors. One of way of fixing this, if you
have the source, is to simply edit one of the include files to correct
the problem, however then you'd have repeat this process whenever a new version
of the include file was released.

Euphoria has a simpler way to solve this. Using an extension to the
include statement, you can say for example:

<eucode>
include johns_file.e as john
include bills_file.e as bill

john:x += 1
bill:x += 2
</eucode>

In this case, the variable ##x## was declared in two different files, and you
want to refer to both variables in your file.  Using the //namespace
identifier// of either ##john## or ##bill##, you can attach a prefix to ##x## to
indicate which ##x## you are
referring to.  We sometimes say that ##john## refers to one //namespace//, while
##bill## refers to another distinct //namespace//.  You can attach a namespace
identifier to any user-defined variable, constant, procedure or function. You
can do it to solve a conflict, or simply to make things clearer. A namespace
identifier has local scope. It is known only within the file that declares it,
i.e. the file that contains the include statement.  Different files might
define different namespace identifiers to refer to the same included file.

There is a special, reserved namespace, ##**eu**## for referring to built-in
Euphoria routines.  This can be useful when a built-in routine has been
overridden:

<eucode>
procedure puts( integer fn, object text )
    eu:puts(fn, "Overloaded puts says: "& text )
end procedure

puts(1, "Hello, world!\n")
eu:puts(1, "Hello, world!\n")
</eucode>

Files can also declare a default namespace to be used with the file.  When a
file with a default namespace is included, if the include statement did not
specify a namespace, then the default namespace will be automatically declared
in that file.  If the include statement declares a namespace for the newly
included file, then the specified namespace will be available instead of the
default.  No two files can use the same namespace identifier.  If two files
with the same default namespaces are included, at least one will be required to
have a different namespace to be specified.

To declare a default namespace in a file, the first token (whitespace and
comments are ignored) should be 'namespace' followed by the desired name:

<eucode>
-- foo.e :  this file does some stuff
namespace foo
</eucode>

A namespace that is declared as part of an ##include## statement is local to the
file where the ##include## statement is.  A default namespace declared in a file
is considered a public symbol in that file.  Namespaces and other symbols (e.g.,
variables, functions, procedures and types) can have the same name without
conflict. A namespace declared through an ##include## statement will mask a
default namespace declared in another file, just like a normal local variable
will mask a public variable in another file.  In this case, rather than using
the default namespace,
declare a new namespace through the ##include## statement.

Note that declaring a namespace, either through the include statement or as a
default namespace does not **require** that every symbol reference must be
qualified with that namespace.  The namespace simply **allows** the user to
deconflict symbols in different files with the same name, or to
allow the programmer to be explicit about where symbols are coming from
for the purposes of clarity, or to avoid possible future conflicts.

A qualified reference does not absolutely restrict the reference to symbols that
actually reside within the specified file.  It can also apply to symbols
included by that file.  This is especially useful for multi-file libraries.
Programmers can use a single namespace for the library, even though some of the
visible symbols in that library are not declared in the main file:

<eucode>
-- lib.e
namespace lib

public include sublib.e

public procedure main()
...

-- sublib.e
public procedure sub()
...

-- app.ex
include lib.e

lib:main()
lib:sub()
</eucode>

Now, what happens if you do not use 'public include'?

<eucode>
-- lib2.e
include sublib.e
...

-- app2.ex
include lib.e
lib:main()
lib:sub() -- error.  sub() is visible in lib2.e but not in app2.ex
</eucode>

==== The visibility of public and export identifiers
When a file needs to see the public or exported identifiers in another file that
includes the first file, the first file must include that other (including)
file.

For example,
<eucode>
-- Parent file: foo.e --
public integer Foo = 1
include bar.e -- bar.e needs to see Foo
showit() -- execute a routine in bar.e
</eucode>

<eucode>
-- Included file: bar.e --
include foo.e -- included so I can see Foo
constant xyz = Foo + 1

public procedure showit()
? xyz
end procedure
</eucode>

//Public// symbols can only be seen by the file that explicitly includes
the file where those public symbols are declared.

For example,
<eucode>
-- Parent file: foo.e --
include bar.e
showit() -- execute a public routine in bar.e
</eucode>

If however, a file wants a third file to also see the symbols that it can, it
needs to do a ##public include##.

For example,
<eucode>
-- Parent file: foo.e --
public include bar.e
showit() -- execute a public routine in bar.e

public procedure fooer()
   . . .
end procedure
</eucode>

<eucode>
-- Appl file: runner.ex --
include foo.e
showit() -- execute a public routine that foo.e can see in bar.e
fooer()  -- execute a public routine in foo.e
</eucode>

The ##public include## facility is designed to make having a library composed of
multiple files easy for an application to use. It allows the main library file
to expose symbols in files that //it// includes as if the application had
actually included them. That way, symbols meant for the end user can be declared
in files other than the main file, and the library can still be organized
however the author prefers without affecting the end user.

**Another example**\\
Given that we have two files LIBA.e and LIBB.e ...
>
<eucode>
-- LIBA.e --
public constant
    foo1 = 1,
    foo2 = 2

export function foobarr1()
    return 0
end function

export function foobarr2()
    return 0
end function
</eucode>
<
 and
>
<eucode>
-- LIBB.e --
-- I want to pass on just the constants not
-- the functions from LIBA.e.
public include LIBA.e
</eucode>
<
 The export scope modifier is used to limit the extent that symbols can be
 accessed. It works just like ##public## except that ##export## symbols are only
ever passed up one level only. In other words, if a file wants to use an
##export## symbol, that file must include it explicitly.

In this example above, code in LIBB.e can see both the public and export symbols
declared in LIBA.e (##foo1, foo2 foobarr1## and ##foobarr2##) because it
explicitly includes LIBA.e. And by using the ##public## prefix on the
##include## of LIBA.e, it also allows any file that ##includes## LIBB.e to the
##public## symbols from LIBA.e but they will not see any ##export## symbols
declared in LIBA.e.

In short, a ##public include## is used expose ##public## symbols that are
included, up one level but not any ##export## symbols that were include.

==== The complete set of resolution rules

**Resolution** is the process by which the interpreter determines which specific
symbol will actually be used at any given point in the code. This is usually
quite easy as most symbol names in a given scope are unique and so Euphoria
does not have to choose between them. However, when the same symbol name is used
in different but enclosing scopes, Euphoria has to make a decision about which
symbol the coder is referring to.

When Euphoria sees an identifier name being used, it looks for the name's
declaration starting from the current scope and moving outwards through the
enclosing scopes until the name's declaration is found.

The hierarchy of scopes can be viewed like this ...
{{{
global/public/export
  file
     routine
        block 1
           block 2
           ...
              block n
}}}
So, if a name is used at a ##block## level, Euphoria will first check for its
declaration in the same block, and if not found will check the enclosing blocks
until it reaches the routine level, in which case it checks the routine
(including parameter names), and then check the file that the block is declared
in and finally check the global/public/export symbols.

By the way, Euphoria will not allow a name to be declared if it is already
declared in the same scope, or enclosing ##block## or enclosing ##routine##.
Thus the
following examples are illegal...
<eucode>
integer a
if x then
   integer a -- redefinition not allowed.
end if
</eucode>

<eucode>
if x then
   integer a
   if y then
      integer a -- redefinition not allowed.
   end if
end if
</eucode>

<eucode>
procedure foo(integer a)
if x then
  integer a -- redefinition not allowed.
end if
end procedure
</eucode>

But note that this below is valid ...
<eucode>
integer a = 1
procedure foo()
    integer a = 2
    ? a
end procedure
? a
</eucode>
In this situation, the second declaration of 'a' is said to //shadow// the first
one. The output from this example will be ...
>
{{{
2
1
}}}


Symbols all declared in the same file (be they in blocks, routines or at the
file level) are easy to check by Euphoria for scope clashes. However, a problem
can arise when symbol names declared as global/public/export in different files
are placed in the same scope during ##include## processing. As it is quite
possible for these files to come from independent developers that are not aware
of each other's symbol names, the potential for name clashes is high. A name
clash is just when the same name is declared in the same scope but in different
files. Euphoria cannot generally decide which name you were referring to when
this happens, so it needs you help to resolve it. This is where the
##namespace## concept is used.

A namespace is just a name that you assign to an include file so that your code
can exactly specify where an identifier that your code is using actually comes
from. Using a namespace with an identifier, for example:
<eucode>
include somefile.e as my_lib
include another.e
my_lib:foo()
</eucode>
enables Euphoria to resolve the identifier (##foo##) as explicitly coming from
the file associated with the namespace "my_lib". This means that if ##foo## was
also declared as global/public/export in //another.e// then that ##foo## would
be ignored and the ##foo## in //somefile.e// would be used instead. Without that
namespace, Euphoria would have complained (##Errors resolving the following
references:##)

If you need to use both ##foo## symbols you can still do that by using two
different namespaces. For example:
<eucode>
include somefile.e as my_lib
include another.e  as her_ns
my_lib:foo() -- Calls the one in somefile.e
her_ns:foo() -- Calls the one in another.e
</eucode>

Note that there is a reserved namespace name that is always in use. The special
namespace **##eu##** is used to let Euphoria know that you are accessing a
built-in symbol rather than one of the same name declared in someone's file.

For example...
<eucode>
include somefile.e as my_lib
 result = my_lib:find(something) -- Calls the 'find' in somefile.e
 xy = eu:find(X, Y) -- Calls Euphoria's built-in 'find'
</eucode>

The controlling variable used in a [[:for statement]] is special. It is
automatically declared at the beginning of the loop block, and its scope ends at
the end of the for-loop. If the loop is inside a function or procedure, the loop
variable cannot have the same name as any other variable declared in the routine
or enclosing block. When the loop is at the top level, outside of any routine,
the loop variable cannot have the same name as any other file-scoped variable.
You can use the same name in many different for-loops as long as the loops
are not nested. You do not declare loop variables as you would other variables
because they are automatically declared as
atoms. The range of values specified in the for statement defines the
legal values of the loop variable.

Variables declared inside other types of blocks, such as a **loop**, **while**,
**if** or **switch** statement use the same scoping rules as a for-loop index.

@[override|]
==== The override qualifier

There are times when it is necessary to replace a global, public or export
identifier. Typically, one would do this to extend the capabilities of a
routine. Or perhaps to supersede the user defined type of some public, export or
global variable, since the type itself may not be global.

This can be achieved by declaring the identifier as **override**:
<eucode>
override procedure puts(integer channel,sequence text)
    eu:puts(log_file, text)
    eu:puts(channel, text)
end procedure
</eucode>

A warning will be issued when you do this, because it can be very confusing, and
would probably break code, for the new routine to change the behavior of the
former routine. Code that was calling the former routine expects no difference
in service, so there should not be any.

If an identifier is declared global, public or export, but not override, and
there is a built-in of the same name, Euphoria will not assume an override, and
will choose the built-in. A warning will be generated whenever this happens.

@[deprecate|]
=== Deprecation

Beginning in Euphoria 4.1, procedures and functions can be marked as deprecated.
Deprecation is a computer software term that assigns a status to a particular item
to indicate that it should be avoided, typically because it has been superseded.
Deprecated routines remain in the language or library but should be avoided.

The ##deprecate## modifier will cause a warning to appear if that routine is
used. It serves no more purpose but is a powerful way to keep an evolving library
clean, slim and fit for the task. Instead of simply removing an old routine
authors are encouraged to use the ##deprecate## modifier on a routine and leave
it a part of the library for at least one major version increment. It can then
be removed. This allows your users time to upgrade their code to the new
recommended routine. Deprecated routines should be included in your manual, state
when and why they were deprecated and what is the path future for accomplishing
the same task.

<eucode>
--**
-- Say hello to someone
--
-- Parameters:
--   * name - name of person to say hello to
--
-- Deprecated:
--   ##say_hello## has been deprecated in favor of the new greet routine.
--

deprecate public procedure say_hello(sequence name)
    printf(1, "Hello, %s\n", { name })
end procedure

public procedure greet(sequence name="World", sequence greeting="Hello")
    printf(1, "%s, %s\n", { greeting, name })
end procedure
</eucode>

When deprecating a routine, the keyword ##deprecate## should occur before any
scope modifier.

%%output=lang_assignment
== Assignment statement
:<<LEVELTOC level=2 depth=4>>
An **assignment statement** assigns the value of an expression to
a simple variable, or to a subscript or slice of a variable. e.g.

<eucode>
x = a + b
y[i] = y[i] + 1
y[i..j] = {1, 2, 3}
</eucode>

The previous value of the variable, or element(s) of the subscripted or sliced
variable are discarded.  For example, suppose x was a 1000-element sequence
that we had initialized with:

<eucode>
object x

x = repeat(0, 1000)  -- a sequence of 1000 zeros
</eucode>

and then later we assigned an atom to x with:

<eucode>
x = 7
</eucode>

This is perfectly legal since x is declared as an **object**. The
previous value of x, namely the 1000-element sequence, would simply disappear.
Actually, the space consumed by the 1000-element sequence will be automatically
recycled due to Euphoria's dynamic storage allocation.

Note that the equals symbol '=' is used for both assignment and for 
equality testing.  There is never any confusion
because an assignment in Euphoria is a statement only, it can't be used as an
expression (as in C).

=== Assignment with Operator

Euphoria also provides some additional forms of the assignment statement.

To save typing, and to make your code a bit neater, you can combine assignment
with one of the operators:

<eucode>
+ - / * &
</eucode>

For example, instead of saying:

<eucode>
mylongvarname = mylongvarname + 1
</eucode>

You can say:

<eucode>
mylongvarname += 1
</eucode>

Instead of saying:

<eucode>
galaxy[q_row][q_col][q_size] = galaxy[q_row][q_col][q_size] * 10
</eucode>

You can say:

<eucode>
galaxy[q_row][q_col][q_size] *= 10
</eucode>

and instead of saying:

<eucode>
accounts[start..finish] = accounts[start..finish] / 10
</eucode>

You can say:

<eucode>
accounts[start..finish] /= 10
</eucode>

In general, whenever you have an assignment of the form:

{{{
left-hand-side = left-hand-side op expression
}}}

You can say:

{{{
left-hand-side op= expression
}}}

where **//op//** is one of:

<eucode>
+ - * / &
</eucode>

When the left-hand-side contains multiple subscripts/slices, the ##op=##
form will usually execute faster than the longer form. When you get used to it,
you may find the ##op=## form to be slightly more readable than the long
form, since you don't have to visually compare the left-hand-side against the
copy of itself on the right side.

You cannot use assignment with operators while declaring a variable, because
that variable is not initialized when you perform the assignment.

%%output=lang_branch
== Branching Statements
:<<LEVELTOC level=2 depth=4>>
@[then|] @[else|]

 @[elsif|]
=== if statement

An **if statement** tests a condition to see whether it is true or false, and
then depending on the result of that test, executes the appropriate set of
statements.

The syntax of ##if## is
<eucode>
 IFSTMT  ==:  IFTEST [ ELSIF ...] [ELSE] ENDIF
 IFTEST  ==:  if ATOMEXPR [ LABEL ] then [ STMTBLOCK ]
 ELSIF   ==:  elsif ATOMEXPR then [ STMTBLOCK ]
 ELSE    ==:  else [ STMTBLOCK ]
 ENDIF   ==:  end if
</eucode>

**Description of syntax**\\
* An //if statement// consists of the keyword ##**if**##, followed by an
//expression// that evaluates to an atom, optionally followed by a //label//
clause, followed by the keyword ##**then**##.
Next is a set of zero or more statements. This is followed by zero or more
//elsif// clauses.
Next is an optional //else// clause and finally there is the keyword ##**end**##
followed by  the keyword ##**if**##.
* An //elsif// clause consists of the key word ##**elsif**##, followed by  an
//expression// that evaluates to an atom, followed by the keyword ##**then**##.
Next is a set of zero or more statements.
* An //else// clause consists of the keyword ##**else**## followed by a set of
zero or more statements.

In Euphoria, //false// is represented by an atom whose value is zero and
//true// is represented by an atom that has any non-zero value.

* When an //expression// being tested is true, Euphoria executes the statements
immediately following the ##**then**## keyword after the //expression//, up to
the corresponding ##**elsif**## or ##**else**##, whichever comes next, then
skips down to the corresponding ##**end if**##.
* When an //expression// is false, Euphoria skips over any statements until it
comes to the next corresponding ##**elsif**## or ##**else**##, whichever comes
next. If this is an ##**elsif**## then its //expression// is tested otherwise
any statements following the ##**else**## are executed.

For example:
<eucode>
if a < b then
    x = 1
end if

if a = 9 and find(0, s) then
    x = 4
    y = 5
else
    z = 8
end if

if char = 'a' then
    x = 1
elsif char = 'b' or char = 'B' then
    x = 2
elsif char = 'c' then
    x = 3
else
    x = -1
end if
</eucode>

Notice that ##**elsif**## is a contraction of //else if//, but it's cleaner
because it does not require an ##**end if**## to go with it. There is just one
##**end if**## for the entire //if statement//, even when there are many
##**elsif**## clauses contained in it.

The ##**if**## and ##**elsif**## expressions are tested using [[:short_circuit]]
evaluation.

An //if statement// can have a //label clause// just before the first
##**then**## keyword.
See the section on [[:Header Labels]]. Note that an //elsif clause// can not
have a label.

@[case|]   @[do|]
=== switch statement ===
The switch statement is used to run a specific set of statements, depending on
the value of an expression. It often replaces a set of if-elsif statements due
to it's ability to be highly optimized, thus much greater performance. There are
some key differences, however.  A switch statement operates upon the value of a
single expression, and the program
flow continues based upon defined cases.  The syntax of a switch statement:

<eucode>
switch <expr> [with fallthru] [label "<label name>"] do
    case <val>[, <val2>, ...] then
        [code block]
        [[break [label]]|fallthru]
    case <val>[, <val2>, ...] then
        [code block]
        [[break [label]]|fallthru]
    case <val>[, <val2>, ...] then
        [code block]
        [[break [label]]|fallthru]
    ...

    [case else]
        [code block]
        [[break [label]]|fallthru]
end switch
</eucode>

The above example could be written with ##if## statements like this ..
<eucode>
object temp = expression
object breaking = false
if equal(temp, val1) then
    [code block 1]
    [breaking = true]
end if
if not breaking and equal(temp, val2) then
    [code block 2]
    [breaking = true]
end if
if not breaking and equal(temp, val3) then
    [code block 3]
    [breaking = true]
end if
 ...
if not breaking then
    [code block 4]
    [breaking = true]
end if
</eucode>

The <val> in a ##case## must be either an atom, literal string, constant or
enum.  Multiple values for a single ##case## can be specified by separating the
values by commas. The same symbol (or literal) may not be used multiple times as
a ##case## for the same ##switch##. If two different symbols used as ##case## values
happen to have the same value, they must be in the same ##case...then## statement,
or an error will occur. If the parser can determine all values when the ##switch##
is parsed, then a compile time error will be thrown. Otherwise, the error will occur
the first time that the switch is encountered. Likewise, when translating code, if
the parser cannot determine all values at the time when the ##case## values are parsed,
the compilation will fail due to mulitple ##case## values in the emitted C code (it is
assumed that the programmer should work out this sort of bug in interpreted mode).

By default, control flows to the end of the ##switch## block
when the next ##case## is encountered.  The default behavior can be modified in
two ways.  The default for a particular ##switch## block can be changed so that
control passes to the next executable statement whenever a new case is
encountered by using ##with fallthru## in the ##switch## statement:
<eucode>
switch x with fallthru do
    case 1 then
        ? 1
    case 2 then
        ? 2
        break
    case else
        ? 0
end switch
</eucode>
Note that when ##with fallthru## is used, the ##break## statement can be used
to jump out of the ##switch## block.  The behavior of individual ##case##s can
be changed by using the ##fallthru## statement:
<eucode>
switch x do
    case 1 then
        ? 1
        fallthru
    case 2 then
        ? 2
    case else
        ? 0
end switch
</eucode>
Note that the ##break## statement before ##case else## was omitted, because
the equivalent action is taken automatically by default.
<eucode>
switch length(x) do
    case 1 then
        -- do something
        fallthru
    case 2 then
        -- do something extra
    case 3 then
        -- do something usual

    case else
        -- do something else
end switch
</eucode>

The ##label "name"## is optional and if used it gives a name to the switch
block. This name can be used in nested switch ##break## statements to break out
of an enclosing switch rather than just the owning switch. \\
Example:
<eucode>
switch opt label "LBLa" do
    case 1, 5, 8 then
        FuncA()


    case 4, 2, 7 then
        FuncB()
        switch alt label "LBLb" do
           case "X" then
                FuncC()
                break "LBLa"

           case "Y" then
                FuncD()

           case else
                FuncE()
       end switch
       FuncF()

    case 3 then
       FuncG()
       break

    case else
        FuncH()
end switch
FuncM()
</eucode>
In the above, if opt is 2 and alt is "X" then it runs...\\
::
FuncB()
FuncC()
FuncM()

But if opt is 2 and alt is "Y" then it runs ...\\
::
FuncB()
FuncD()
FuncF()
FuncG()
FuncM()

In other words, the ##break "LBLa"## skips to the end of the switch called
"LBLa" rather than the switch called "LBLb".

 @[elsedef|]  @[elsifdef|]
=== ifdef statement

The ##ifdef## statement has a similar syntax to the ##if## statement.
<eucode>
ifdef SOME_WORD then
 --... zero or more statements
elsifdef SOME_OTHER_WORD then
 --... zero or more statements
elsedef
 --... zero or more statements
end ifdef
</eucode>
Of course, the ##elsifdef## and ##elsedef## clauses are optional, just like
##elsif## and ##else## are option in an ##if## statement.

The major differences between and ##if## and ##ifdef## statement are that
##ifdef## is executed at parse time not runtime, and ##ifdef## can only test for
the existence of a defined word whereas ##if## can test any boolean expression.

**Note** that since the ##ifdef## statement executes at parse time, run-time
values cannot be checked, only words defined by the ##-D## command line switch,
or by the ##with define## directive, or one of the special predefined words.

The purpose of ##ifdef## is to allow you to change the way your program operates
in a very efficient manner. Rather than testing for a specific condition
repeatedly during the running of a program, ##ifdef## tests for it once during
parsing and then generates the precise IL code to handle the condition.

For example, assume you have some debugging code in your application that
displays information to the screen. Normally you would not want to see this
display so you set a condition so it only displays during a 'debug' session. The
first example below shows how would could do this just using the ##if##
statement, and the second example shows the same thing but using the ##idef##
statement.
<eucode>
-- Example 1. --
if find("-DEBUG", command_line()) then
    writefln("Debug x=[], y=[]", {x,y})
end if
</eucode>

<eucode>
-- Example 1. --
ifdef DEBUG then
    writefln("Debug x=[], y=[]", {x,y})
end ifdef
</eucode>

As you can see, they are almost identical. However, in the first example,
everytime the program gets to this point in the code, it tests the command line
for the -DEBUG switch before deciding to display the information or not. But in
the second example, the existence of DEBUG is tested //once// at parse time, and
if it exists then, Euphoria generates the IL code to do the display. Thus when
the program is running then everytime it gets to this point in the code, it does
**not** check that DEBUG exists, instead it already knows it does so it just
does the display. If however, DEBUG did not exist at parse time, then the IL
code for the display would simply be omitted, meaning that during the running of
the program, when it gets to this point in the code, it does not
recheck for DEBUG, instead it already knows it doesn't exist and the IL code to
do the display also doesn't exist so nothing is displayed. This can be a much
needed performance boost for a program.

Euphoria predefines some words itself:

==== Euphoria Version Definitions

* **EU4** - Major Euphoria Version
* **EU4_1** - Major and Minor Euphoria Version
* **EU4_1_0** - Major, Minor and Release Euphoria Version

Euphoria is released with the common version scheme of Major, Minor and Release
version identifiers in the form of major.minor.release. When 4.1.1 is
released, ##EU4_1_1## will be defined and ##EU4_1## will still be defined, but ##EU4_1_0## will no longer be defined.  When 4.2 is released, ##EU4_1## will no longer be defined, but ##EU4_2## will be defined. Finally, when 5.0 is released, ##EU4## will no longer be
defined, but ##EU5## will be defined.

==== Platform Definitions

* **CONSOLE** - Euphoria is being executed
  with the Console version of the interpreter (on windows, eui.exe, others are eui)
* **GUI** - Platform is Windows and is being executed with
  the GUI version of the interpreter (euiw.exe)
* **WINDOWS** - Platform is Windows (GUI or Console)
* **LINUX** - Platform is Linux
* **OSX** - Platform is Mac OS X
* **FREEBSD** - Platform is FreeBSD
* **OPENBSD** - Platform is OpenBSD
* **NETBSD** - Platform is NetBSD
* **BSD** - Platform is a BSD variant (FreeBSD, OpenBSD, NetBSD and OS X)
* **UNIX** - Platform is any Unix

==== Architecture Definitions

Chip architecture:
* **X86**
* **X86_64**
* **ARM**

Size of pointers and euphoria objects.  This information can be derived from
the chip architecture, but is provided for convenience.
* **BITS32**
* **BITS64**

Size of long integers.  On Windows, long integers are always 32 bits.  On other
platforms, long integers are the same size as pointers.  This information can
also be derived from a combination of other architecture and platform ifdefs,
but is provided for convenience.
* **LONG32**
* **LONG64**

==== Application Definitions

* **EUI** - Application is being interpreted by ##eui##.
* **EUC** - Application is being translated by ##euc##.
* **EUC_DLL** - Application is being translated by ##euc## into a //DLL// file.
* **EUB** - Application is being converted to a bound program by ##eub##.
* **EUB_SHROUD** - Application is being converted to a shrouded program by
##eub##.
* **CONSOLE** - Application is being translated, or converted to a bound //console// program by
 ##euc## or ##eub##, respectively.
* **GUI** - Application is being converted to a bound //Windows GUI//
program by ##eub##.

==== Library Definitions

* **DATA_EXECUTE** - Application will always get executable memory from
##allocate## even when the system has Data Execute Protection enabled for the
Euphoria Interpreter.
* **SAFE** - Enables safe runtime checks for operations for routines found in
##machine.e## and ##dll.e##
* **UCSTYPE_DEBUG** - Found in ##include/std/ucstypes.e##
* **CRASH** - Found in ##include/std/unittest.e##

More examples
<eucode>
-- file: myproj.ex
puts(1, "Hello, I am ")
ifdef EUC then
    puts(1, "a translated")
end ifdef
ifdef EUI then
    puts(1, "an interpreted")
end ifdef
ifdef EUB then
    puts(1, "a bound")
end ifdef
ifdef EUB_SHROUD then
    puts(1, ", shrouded")
end ifdef
puts(1, " program.\n")
</eucode>

{{{
C:\myproj> eui myproj.ex
Hello, I am an interpreted program.
C:\myproj> euc -con myprog.ex
... translating ...
... compiling ...
C:\myproj> myprog.exe
Hello, I am a translated program.
C:\myproj> bind myprog.ex
...
C:\myproj> myprog.exe
Hello, I am a bound program.
C:\myproj> shroud myprog.ex
...
C:\myproj> eub myprog.il
Hello, I am a bound, shrouded program.
}}}

It is possible for one or more of the above definitions to be true at the same
time. For instance, ##EUC## and ##EUC_DLL## will both be true when the source
file has been translated to a DLL. If you wish to know if your source file is
translated and not a DLL, then you can

<eucode>
ifdef EUC and not EUC_DLL then
    -- translated to an application
end ifdef
</eucode>



==== Using ifdef

You can define your own words either in source:

<eucode>
with define MY_WORD       -- defines
without define OTHER_WORD -- undefines
</eucode>

or by command line:

{{{
eui -D MY_WORD myprog.ex
}}}

This can handle many tasks such as change the behavior of your application
when running on //Linux// vs. //Windows//, enable or disable debug style code or
possibly work differently in demo/shareware applications vs. registered
applications.

You should surround code that is not portable with ##ifdef## like:
<eucode>
ifdef WINDOWS then
   -- Windows specific code.
elsedef
   include std/error.e
   crash("This program must be run with the Windows interpreter.")
end ifdef
</eucode>

When writing **include files** that you cannot run on some platform, issue a
crash call in the **include file**. **Yet** make sure that public constants and
procedures are defined for the unsupported platform as well.

<eucode>
ifdef UNIX then
     include std/bash.e
end ifdef

-- define exported and public constants and procedures for
-- OSX as well
ifdef WINDOWS or OSX then
    -- OSX is not supported but we define public symbols for it anyhow.
</eucode>

The reason for doing this is so that the user that includes your include file
sees an "OS not supported" message instead of an "undefined reference" message.


Defined words must follow the same character set of an identifier, that is,
it must start with either a letter or underscore and contain any mixture of
letters, numbers and underscores. It is common for defined words to be in
all upper case, however, it is not required.

A few examples:

<eucode>
for a = 1 to length(lines) do
    ifdef DEBUG then
        printf(1, "Line %i is %i characters long\n", {a, length(lines[a])})
    end ifdef
end for

sequence os_name
ifdef UNIX then
    include unix_ftp.e
elsifdef WINDOWS then
    include win32_ftp.e
elsedef
    crash("Operating system is not supported")
end ifdef

ifdef SHAREWARE then
  if record_count > 100 then
     message("Shareware version can only contain 100 records. Please register")
     abort(1)
  end if
end ifdef
</eucode>

The ##ifdef## statement is very efficient in that it makes the decision only
once during parse time and only emits the ##TRUE## portions of code to the
resulting interpreter. Thus, in loops that are iterated many times there is
zero performance hit when making the decision. Example:

<eucode>
while 1 do
    ifdef DEBUG then
        puts(1, "Hello, I am a debug message\n")
    end ifdef
    -- more code
end while
</eucode>

If ##DEBUG## is defined, then the interpreter/translator actually sees the code
as being:

<eucode>
while 1 do
    puts(1, "Hello, I am a debug message\n")
    -- more code
end while
</eucode>

Now, if ##DEBUG## is not defined, then the code the interpreter/translator sees
is:

<eucode>
while 1 do
    -- more code
end while
</eucode>

Do be careful to put the numbers after the platform names for //Windows//:

<eucode>
-- This puts() routine will never be called
-- even when run by the Windows interpreter!
ifdef WINDOWS then
     puts(1,"I am on Windows\n")
end ifdef
</eucode>

%%output=lang_loop
== Loop statements
:<<LEVELTOC level=2 depth=4>>

An iterative code block repeats its own execution zero, one or more times.
There are several ways to specify for how long the process should go on, and
how to stop or otherwise alter it.  An iterative block may be informally called
a loop, and each execution of code in a loop is called an iteration of the
loop.

Euphoria has three flavors of loops. They all may harbor a
[[:Header Labels]], in order to make exiting or resuming them
more flexible.

=== while statement

A **while statement** tests a condition to see if it is non-zero
(true), and if so, a body of statements is executed. The condition is re-tested
after when the statements are run, and if still true the statements are
run again, and so on.

Syntax Format:
>##**while** //expr// //[//**with entry**//]// //[//**label** //"name"// //]// **do**##
>>##//statements//##
>##//[//**entry**//]//##
>>##//statements//##
>##**end while**##

Example 1
<eucode>
while x > 0 do
    a = a * 2
    x = x - 1
end while
</eucode>

Example 2
<eucode>
while sequence(Line) with entry do
    proc(Line)
entry
    Line = gets(handle)
end while
</eucode>

Example 3
<eucode>
while true label "main" do
   res = funcA()
   if res > 5 then
       if funcB() > some_value then
          continue "main" -- go to start of loop
       end if
       procC()
   end if
   procD(res)
   for i = 1 to res do
       if i > some_value then
          exit "main" -- exit the "main" loop, not just this 'for' loop.
       end if
       procF(i,res)
   end if

   res = funcE(res, some_value)
end while
</eucode>

=== loop until statement

A **loop** statement tests a condition to see if it is
non-zero (true), and until it is true a loop is executed.

Syntax Format:
>##**loop** //[//**with entry**//]// //[//**label** //"name"// //]// **do**##
>>##//statements//##
>>##**until** //expr//##
>##end loop##

<eucode>
loop do
    a = a * 2
    x = x - 1
    until x<=0
end loop
</eucode>

<eucode>
loop with entry do
    a = a * 2
  entry
    x = x - 1
    until x<=0
end loop
</eucode>

<eucode>
loop label "GONEXT" do
    a = a * 2
    y += 1
    if y = 7 then continue "GONEXT" end if
    x = x - 1
    until x<=0
end loop
</eucode>

A ##while## statement differs from a ##loop## statement because the body of a
loop is executed at least once, since testing takes place **after** the body
completes.  However in a ##while## statement, the test is taken **before** 
the body is executed.


@[to|] @[by|]
=== for statement

Syntax Format:
>##**for** **loopvar** = **startexpr** to **endexpr** //[//**by delta**//]// **do**##
>>##//statements//##
>##end for##

A **for** statement sets up a special loop that has its own **loop variable**.
The **loop variable** starts with the specified initial value and increments or
decrements it to the specified final value. The **for** statement is used when
you need to repeat a set of statements a specific number of times.\\
Example:
<eucode>
-- Display the numbers 1 to 6 on the screen.
puts(1, "1\n")
puts(1, "2\n")
puts(1, "3\n")
puts(1, "4\n")
puts(1, "5\n")
puts(1, "6\n")
</eucode>

This block of code simply starts at the first line and runs each in turn. But it
could be written more simply and flexibly by using a **for** statement.

<eucode>
for i = 1 to 6 do
    printf(1, "%d\n", i)
end for
</eucode>
Now it's just three lines of code rather than six. More importantly, if we
needed to change the program to print the numbers from 1 to 100, we only have to
change one line rather than add 94 new lines.

<eucode>
for i = 1 to 100 do -- One line change.
    printf(1, "%d\n", i)
end for
</eucode>

Or using another way ...

<eucode>
for i = 1 to 10 do
    ? i   -- ? is a short form for print()
end for

-- fractional numbers allowed too
for i = 10.0 to 20.5 by 0.3 do
    for j = 20 to 10 by -2 do    -- counting down
        ? {i, j}
    end for
end for
</eucode>

However, adding together floating point numbers that are not the ratio of an
integer by a power of 2 ~--// 0.3 is not such a ratio//~--leads to
some "fuzz" in the value of the index. In some cases, you might get unexpected
results because of this fuzz, which arises
from a common hardware limitation. For instance, ##floor(10*0.1)## is ##1## as
expected, but ##floor(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)## is ##0##.

The **loop variable** is declared automatically and exists until
the end of the loop. Outside of the loop the variable has no value and is not
even declared.  If you need its final value, copy it into another variable
before leaving the loop. The compiler will not allow any assignments to a loop
variable. The initial value, loop limit and increment must all be atoms. If no
increment is specified then +1 is assumed. The limit and increment values are
established only on entering the loop, and are not affected by anything that
happens during the execution of the loop.

%%output=lang_flow
== Flow control statements
:<<LEVELTOC level=2 depth=4>>

Program execution flow refers to the order in which program statements are run
in. By default, the next statement to run after the current one is the next
statement //physically// located after the current one.\\
Example:
<eucode>
a = b + c
printf(1, "The result of adding %d and %d is %d", {b,c,a})
</eucode>

In that example, ##b## is added to ##c##, assigning the result to ##a##, and
then the information is displayed on the screen using the ##printf## statement.

However, there are many times in which the order of execution needs to be
different from the default order, to get the job done. Euphoria has a number of
//flow control statements// that you can use to arrange the execution order of
statements.

A set of statements that are run in their order of appearance is called a
//block//. Blocks are good ways to organize code in easily identifiable chunks.
However it can be desirable to leave a block before reaching the end, or
slightly alter the default course of execution.\\

The following flow control keywords are available.

<eucode>
break retry entry exit continue return goto end
</eucode>

=== exit statement

Exiting a loop is done with the keyword **exit**. This causes flow
to immediately leave the current loop and recommence with the first statement
after the end of the loop.
<eucode>
for i = a to b do
    c = i
    if doSomething(i) = 0 then
        exit -- Stop executing code inside the 'for' block.
    end if
end for

-- Flow restarts here.
if c = a then ...
</eucode>

But sometimes you need to leave a block that encloses the current one. Euphoria
has two ways available for you to do this. The safest way, in terms of
future maintenance, is to name the block you want to exit from and use that name
on the exit statement. The other way is to use a number on the exit statement
that refers to the depth that you want to exit from.

A block's name is always a string literal and only a string literal. You cannot
use a variable that contains the block's name on an exit statement. The name
comes after the ##label## keyword, just before the ##do## keyword.\\
Example:
<eucode>
integer b
  b = 0
  for i = 1 to 20 label "main" do
    for j = 1 to 20 do
      b  += i + j
      ? {i, j, b}
      if b > 50 then
        b  = 0
        exit "main"
      end if
    end for
  end for
  ? b
</eucode>

The output from this is ...

<eucode>
{1, 1,  2}
{1, 2,  5}
{1, 3,  9}
{1, 4, 14}
{1, 5, 20}
{1, 6, 27}
{1, 7, 35}
{1, 8, 44}
{1, 9, 54}
0
</eucode>

The **exit "main"** causes execution flow to leave the **for** block named
//main//.

The same thing could be achieved using the **exit N** format...

<eucode>
integer b
  b = 0
for i = 1 to 20 do
    for j = 1 to 20 do
        b  += i + j
        ? {i, j, b}
        if b > 50 then
            b  = 0
            exit 2 -- exit 2 levels of depth
        end if
    end for
end for

? b
</eucode>

But using this way means you have to take more care when changing the program
so that if you change the depth, you also need to change the //exit// statement.

;Note~:
:A special form of **exit N** is ##exit 0##. This leaves all levels of loop,
regardless of the depth. Control continues after the outermost loop block.
Likewise, ##exit -1## exits the second outermost loop, and so on.

For easier and safer program maintenance, the explicit label form is to be
preferred. Other forms are variously sensitive to changes in the program
organization. Yet, they may prove more convenient in short, short lived
programs, and are provided mostly for this purpose.

For information on how to associate a string to a block of code, see the section
[[:Header Labels]].

An **exit** without any label or number in a [[:while statement]] or a
[[:for statement]] causes immediate termination of that loop, with control
passing to the first statement after the loop.\\
Example:
<eucode>
for i = 1 to 100 do
    if a[i] = x then
        location = i
        exit
    end if
end for
</eucode>

It is also quite common to see something like this:

<eucode>
constant TRUE = 1

while TRUE do
    ...
    if some_condition then
        exit
    end if
    ...
end while
</eucode>

i.e. an "infinite" while-loop that actually terminates via an **exit
statement** at some arbitrary point in the body of the loop.

;**Performance Note~:**
:Euphoria optimizes this type of loop.  At run-time, no test is performed at the
top of the loop. There's just a simple unconditional jump from **end while**
back to the first statement inside the loop.

=== break statement

Works exactly like the **exit statement**, but applies to
**if statements** or **switch statements** rather than to loop statements of any
kind. Example:

<eucode>
if s[1] = 'E' then
    a = 3
    if s[2] = 'u' then
        b = 1
        if s[3] = 'p' then
            break 0 -- leave topmost if block
        end if
        a = 2
    else
        b = 4
    end if
else
    a = 0
    b = 0
end if
</eucode>

This code results in:

* "Dur" -> a=0 b=0
* "Exe" -> a=3 b=4
* "Eux" ->  a=2 b=1
* "Eup" ->  a=3 b=1

The same optional parameters can be used with the **break** statement as with
the **exit** statement, but of course apply to if and switch blocks only,
instead of loops.

=== continue statement

Likewise, skipping the rest of an iteration in a single
code block is done using a single keyword, **continue**.
The **continue statement** continues execution of the loop it
applies to by going to the next iteration now. Going to the next iteration
means testing a condition (for **while** and **loop** constructs, or changing
the **for** construct variable index and checking
whether it is still within bounds.

<eucode>
for i = 3 to 6 do
    ? i
    if i = 4 then
        puts(1,"(2)\n")
        continue
    end if
    ? i * i
end for
</eucode>

This will print 3, 9, 4, (2), 5 25, 6 36.

<eucode>
integer b
  b = 0
for i = 1 to 20 label "main" do
    for j = 1 to 20 do
        b  += i + j
        if b > 50 then
            printf(1, "%d ", b)
            b  = 0
            continue "main"
        end if
    end for
end for

? b
</eucode>

The same optional parameters that can be used in an **exit** statement can apply
to a **continue** statement.

=== retry statement

The **retry statement** retries executing the current iteration of the loop it
applies to. The statement branches to the first statement of the designated
loop, without testing anything nor incrementing the for loop index.

Normally, a sub-block which contains a **retry statement** also contains another
flow control keyword, since otherwise the iteration would be endlessly executed.

<eucode>
errors = 0
for i = 1 to length(files_to_open) do
    fh = open(files_to_open[i], "rb")
    if fh=-1 then
        if errors > 5 then
            exit
        else
            errors += 1
            retry
        end if
    end if
    file_handles[i] = fh
end for
</eucode>

Since **retry** does not change the value of i and tries again
opening the same file, there has to be a way to break from the loop, which the
**exit statement** provides.

The same optional parameters that can be used in an **exit** statement can apply
to a **retry** statement.

@[entry|]
=== with entry statement

It is often the case that the first iteration of a loop is somehow special.
Some things have to be done before the loop starts~--they are done before
the statement starting the loop.  Now, the problem is that, just as often, some
things do not need to, or should not, be done at this initialization stage. The
**entry keyword** is an alternative to setting flags relentlessly
and forgetting to update them. Just add the **entry** keyword at
the point you wish the first iteration starts.

<eucode>
public function find_all(object x, sequence source, integer from)
    sequence ret = {}

    while from > 0 with entry do
        ret &= from
        from += 1
    entry
        from = find_from(x, source, from)
    end while

    return ret
end function
</eucode>

Instead of performing an initial test, which may crash because from has not
been assigned a value yet, the first iteration jumps at the point where from is
being computed. The following iterations are normal. To emphasize the fact that
the first iteration is not normal, the entry clause must be added to the loop
header, after the condition.

The entry statement is not supported for ##for## loops, because they have a more
rigid nature structure than while or loop constructs.

; Note on infinite loops.
: With **eui.exe** or **eui**, control-c will always stop your program
immediately, but with the ##euiw.exe## that has not produced any console output,
you will have to use the //Windows// process monitor to end the application.

=== goto statement

##goto## instructs the computer to resume code execution at a place which does
not follow the statement.
The place to resume execution is called the //target// of the statement. It is
restricted to lie in the current routine, or the current file if outside any
routine.

Syntax is:
<eucode>
goto "label string"
</eucode>

The target of a ##goto## statement can be any accessible ##label## statement:
<eucode>
label "label string"
</eucode>

Label names must be double quoted constant strings. Characters that would be
illegal in an Euphoria identifier may appear in a label name, since it is a
regular string.

[[:Header Labels]] do not count as possible goto targets.

Use ##goto## in production code when all the following applies:
* you want to proceed with a statement which is not the following one;
* the various structured constructs wouldn't do, or very awkwardly;
* you contemplate a significant gain in speed/reliability from such a direct
move;
* the code flow remains understandable for an outsider nevertheless.

During early development, it may be nice to have while the code is not firmly
structured. But most instances of ##goto## should melt into structured
constructs as soon as possible as code matures. You may find out that modifying
a program that has goto statements is usually trickier than if it had not had
them.

The following may be situations where ##goto## can help:
* A routine has several return statements, and some processing must be done
before returning, no matter from where. It may be clearer to goto a single
return point and perform the processing only at this point.
* An exit statement in a loop corresponds to an early exit, and the normal
processing that immediately follows the loop is not relevant. Replacing an exit
statement followed by various flag testing by a single goto can help.

Explicit label names will tremendously help maintenance. Remember that there is
no limit to their contents.

goto-ing into a scope (like an if block, a for loop,...) will just do that. Some
variables may be defined only in that scope, and they may or may not have
sensible values. It is up to the programmer to take appropriate action in this
respect.

=== Header Labels ===

As shown in the above section on control flow statements, most can have their
own label. To label a flow control statement, use a ##label## clause immediately
preceding the flow control's terminator keyword (##then## / ##do##).

A ##label## clause consists of the keyword **##label##** followed by a string
literal. The string is the label name.

Examples:
<eucode>
if n=0 label "an_if_block" then
    ...
end if

while TRUE label "a_while_block" do
    ...
end while

loop label "a_loop_block" do
    ...
   until TRUE
end loop

switch x label "a_switch_block" do
   ...
end switch
</eucode>

**Note**: If a flow control statement has both an ##entry## clause and a
##label## clause, the ##entry## clause must come before the ##label## clause:

<eucode>
while 1 label "top" with entry do -- WRONG

while 1 with entry label "top" do -- CORRECT
</eucode>

%%output=lang_short_circuit
== Short-Circuit Evaluation ==
@[short_circuit|]
:<<LEVELTOC level=2 depth=4>>

When the condition tested by if, elsif, until, or while contains ##and## or
##or## operators, [[:short_circuit]] evaluation will be used.  For example,

<eucode>
if a < 0 and b > 0 then ...
</eucode>

If a < 0 is false, then Euphoria will not bother to test if b is greater
than 0. It will know that the overall result is false regardless. Similarly,

<eucode>
if a < 0 or b > 0 then ...
</eucode>

if a < 0 is true, then Euphoria will immediately decide that the result is true,
without testing the value of b, since the result of this test would be
irrelevant.

In general, whenever we have a condition of the form:

<eucode>
A and B
</eucode>

where A and B can be any two expressions, Euphoria will take a short-cut when A
is false and immediately make the overall result false, without even looking at
expression B.

Similarly, with:

<eucode>
A or B
</eucode>

when A is true, Euphoria will skip the evaluation of expression B, and declare
the result to be true.

If the expression B contains a call to a function, and that function has
possible **side-effects**, i.e. it might do more than just return a value,
you will get a compile-time warning. Older versions (pre-2.1) of Euphoria did
not use [[:short_circuit]] evaluation, and it's possible that some old
code will no longer work correctly, although a search of the Euphoria
archives did not turn up any programs that depend on side-effects in
this way, but other Euphoria code might do so.

The expression, B, could contain something that would normally cause a run-time
error. If Euphoria skips the evaluation of B, the error will not be discovered.
For instance:

<eucode>
if x != 0 and 1/x > 10 then  -- divide by zero error avoided

while 1 or {1,2,3,4,5} do    -- illegal sequence result avoided
</eucode>

B could even contain uninitialized variables, out-of-bounds subscripts
etc.

This may look like sloppy coding, but in fact it often allows you to write
something in a simpler and more readable way. For instance:

<eucode>
if length(x) > 1 and x[2] = y then
</eucode>

Without short-circuiting, you would have a problem when x contains less than 2
items. With short-circuiting, the assignment to x[2] will only be done when x
has at least 2 items. Similarly:

<eucode>
-- find 'a' or 'A' in s
i = 1
while i <= length(s) and s[i] != 'a' and s[i] != 'A' do
     i += 1
end while
</eucode>

In this loop the variable i might eventually become greater than length(s).
Without short-circuit evaluation, a subscript out-of-bounds error will occur
when s[i] is evaluated on the final iteration. With short-circuiting, the loop
will terminate immediately when i <= length(s) becomes false. Euphoria will not
evaluate s[i] != 'a' and will not evaluate s[i] != 'A'. No subscript error will
occur.

**Short-circuit** evaluation of ##and## and ##or## takes place inside decision 
making expressions.  These are found in the [[:if statement]], [[:while statement]] 
and the [[:loop until statement]].  It is not used in other contexts. For
example, the assignment statement:

<eucode>
x = 1 or {1,2,3,4,5}  -- x should be set to {1,1,1,1,1}
</eucode>

If short-circuiting were used here, we would set x to 1, and not even look
at {1,2,3,4,5}. This would be wrong. Short-circuiting can be used in
if/elsif/until/while conditions because we only care if the result is true or
false, and conditions are required to produce an atom as a result.

%%output=lang_toplevel
== Special Top-Level Statements ==
@[specialstatements|]
:<<LEVELTOC level=2 depth=4>>

Before any of your statements are executed, the Euphoria front-end quickly
reads your entire program. All statements are syntax checked and converted to a
low-level intermediate language (IL).  The interpreter immediately executes the
IL after it is completely generated. The translator converts the IL to C.
The binder/shrouder saves the IL on disk for later execution. These three
tools all share the same front-end (written in Euphoria).

If your program contains only routine and variable declarations, but no
top-level executable statements, then nothing will happen when you run it
(other than syntax checking). You need a top-level statement to call your main
routine (see [[:Example Programs]]).  It's quite
possible to have a program with nothing but top-level executable statements and
no routines. For example you might want to use Euphoria as a simple calculator,
typing just a few [[:print]] or [[:? -> q_print]] statements into a file, and
then executing it.

As we have seen, you can use any Euphoria statement, including
[[:for statement]], [[:while statement]], [[:if statement]], etc... (but not
[[:return statement|return]]),
at the top level i.e. //outside// of any [[:function ->functions]] or
[[:procedure ->procedures]]. In addition, the
following special statements may //only// appear at the top level:

* ##include##
* ##with## / ##without##


=== include statement

When you write a large program it is often helpful to break it up into
logically separate files, by using **include statements**.
Sometimes you will want to reuse some code that you have previously written, or
that someone else has written. Rather than copy this code into your main
program, you can use an **include statement** to refer to the file
containing the code. The first form of the include statement is:

; ##include //filename//##
: This reads in (compiles) a Euphoria source file.

Some Examples:

<eucode>
include std/graphics.e
include /mylib/myroutines.e
public include library.e
</eucode>

Any top-level code in the included file will be executed at start up time.

Any ##global## identifiers that are declared in the file doing the including
will also be visible in the file being included. However the situation is
slightly different for an identifier declared as **public** or **export**. In
these cases the file being included will **not** see ##public/export## symbols
declared in the file doing the including, unless the file being included also
explicitly includes the file doing the including. Yes, you would better read
that again because its not that obvious. Here's an example...

We have two files, a.e and b.e ...
<eucode>
-- a.e --
? c -- declared as global in 'b.e'
</eucode>

<eucode>
-- b.e --
include a.e
global integer c = 0
</eucode>

This will work because being ##global## the symbol 'c' in b.e can be seen by all
files in this //include tree//.

However ...
<eucode>
-- a.e --
? c -- declared as public in 'b.e'
</eucode>

<eucode>
-- b.e --
include a.e
public integer c = 0
</eucode>
Will not work as public symbols can only be seen when their declaring file is
explicitly included. So to get this to work you need to write a.e as ...
<eucode>
-- a.e --
include b.e
? c -- declared as public in 'b.e'
</eucode>

----

**N.B.** Only those symbols declared as ##global##
in the included file will be visible (accessible) in the
remainder of the including file. Their visibility in other included files or in
the main program file depends on other factors. Specifically, a global symbols
can only be accessed by files in the same //include tree//. For example...

If we have danny.e declare a global symbol called 'foo', and bob.e includes danny.e,
then code in bob.e can access danny's 'foo'. Now if we also have cathy.e declare
a global symbol called 'foo', and anne.e includes cathy.e, then code in ann.e can
access cathy's 'foo'. Nothing unusual about that situation. Now, if we have a program
that includes both bob.e and anne.e, the code in bob.e and anne.e should still
work even though there are now two global 'foo' symbols available. This is because
the include tree for bob.e //only// contains danny.e and likewise the include tree
for anne.e //only// contains cathy.e. So as the two 'foo' symbols are in separate
include trees (from bob.e and anne.e perspective) code in those files continues
to work correctly. A problem can occur if the main program (the one that includes
both bob.e and anne.e) references 'foo'. In order for Euphoria to know which one
the code author meant to use, the coder must use the namespace facility.
<eucode>
--- mainprog.ex ---
include anne.e as anne
include bob.e  as bob

anne:foo() -- Specify the 'foo' from anne.e.
</eucode>
If the above code did not use namespaces, Euphoria would not have know which
'foo' to use ~-- the one from bob.e or the one in anne.e.


If public precedes the include statement, then all public identifiers from the
included file will also be visible to the including file, and visible to any
file that includes the current file.

If an absolute //filename// is given, Euphoria will open it and start
parsing it. When a relative //filename// is given, Euphoria will try to open
the file relative to the following directories, in the following order:

# The directory containing the current source file.  i.e. the source file that
  contains the include statement that is being processed.
# The directory containing the main file given on the interpreter, translator or
  binder ~-- see [[:command_line]].
# If you've defined an environment variable named ##EUINC##, Euphoria will
  check each directory listed in ##EUINC## (from left to right).
  ##EUINC## should be a list of directories, separated by semicolons
  (colons on //Linux// / //FreeBSD//), similar
  in form to your ##PATH## variable. ##EUINC## can be added to your
  set of //Linux// / //FreeBSD// or //Windows// environment  variables.
  (Via ##Control Panel / Performance & Maintenance / System / Advanced##
  on //XP//, or ##AUTOEXEC.BAT## on older versions of
  //Windows//).  e.g. ##SET EUINC=C:\EU\MYFILES;C:\EU\WINDOWSLIB##
  ##EUINC## lets you organize your include files according to application
  areas, and avoid adding numerous unrelated files to ##euphoria\include##.
# Finally, if it still hasn't found the file, it will look in
  ##euphoria\include##.  This directory contains the standard Euphoria
  include files. The environment variable ##EUDIR## tells Euphoria where
  to find your ##euphoria## directory.

An included file can include other files. In fact, you can "nest" included
files up to 30 levels deep.

Include file names typically end in ##.e##, or sometimes ##.ew## or ##.eu##
(when they are intended for use with //Windows// or //Unix//).  This is just a
convention. It is not required.

If your filename (or path) contains blanks or escape-able characters , you must
enclose it in double-quotes, otherwise quotes are optional. When a filename is
enclosed in double-quotes, you can also use the standard escape character
notation to specify filenames that have non-ASCII characters in them.

Note that under Windows, you can also use the forward slash '/' instead
of the usually back-slash '\'. By doing this, the file paths are compatible with
//Unix// systems and it means you don't have to 'escape' the back-slashes. \\
For example:

<eucode>
include "c:/program files/myfile.e"
</eucode>

Other than possibly defining a new namespace identifier (see below), an include
statement will be quietly ignored if the same file has already been
included.

An include statement must be written on a line by itself.  Only a comment can
appear after it on the same line.

@[as|]
The second form of the include statement is:

; ##include** **//filename// as //namespace_identifier//##:
: This is just like the simple include, but it also defines a
//namespace identifier// that can be attached to global identifiers in the
included file that  you want to refer to in the main file. This might be
necessary to disambiguate references to those identifiers, or you might feel
that it makes your code more readable. This ##as identifier## namespace exists
in the current file, along with
  any ##namespace identifier## the included file may define.

>
  See Also:
   [[:Using namespaces]].
<

=== with / without

These special statements affect the way that Euphoria translates your program
into internal form. Options to the ##with## and ##without## statement come
in two flavors. One simply turns an option on or off, while the others have
multiple states.

==== On / Off options

|| Default || Option                      ||
| without  | [[:Profiling "profile"]]      |
| without  | [[:Profiling "profile_time"]] |
| without  | [[:trace]]                    |
| without  | [[:with_batch "batch"]]       |
| with     | [[:type_check]]               |
| with     | [[:indirect_includes]]        |
| with     | [[:with_inline "inline"]]     |


##with## turns **on** one of the options and ##without## turns
**off** one of the options.

For more information on the ##profile##, ##profile_time## and ##trace##
options, see [[:Debugging and Profiling]]. For more information on the
##type_check## option, see [[:Performance Tips]].

There is also a rarely-used special ##with## option where a code
number appears after ##with##.  In previous releases this code was
used by RDS to make a file exempt from adding to the statement count in the old
"Public Domain" Edition. This is not used any longer, but does not cause an
error.

You can select any combination of settings, and you can change the settings,
but the changes must occur //between// subroutines, not within a subroutine.
The only exception is that you can only turn on one type of profiling for a
given run of your program.

An **included file** inherits the **with/without** settings in
effect at the point where it is included.  An included file can change these
settings, but they will revert back to their original state at the end of the
included file.  For instance, an included file might turn off warnings for
itself and (initially) for any files that it includes, but this will not turn
off warnings for the main file.

**@[indirect_includes]**,
This ##with/without## option changes the way in which global symbols are
resolved.  Normally, the parser uses the way that files were included to
resolve a usage of a global symbol.  If ##without indirect_includes## is
in effect, then only direct includes are considered when resolving global
symbols.

This option is especially useful when a program uses some code that was
developed for a prior version of Euphoria that uses the pre-4.0 standard
library, when all exposed symbols were global.  These can often clash
with symbols in the new standard library.  Using ##without indirect_includes##
would not force a coder to use namespaces to resolve symbols that clashed
with the new standard library.

Note that this setting does not propagate down to included files, unlike
most ##with/without options##.  Each file begins with ##indirect_includes##
turned on.

**@[with_batch|with batch]**,
Causes the program to not present the "Press Enter" prompt if an error
occurs. The exit code will still be set to 1 on error. This is helpful
for programs that run in a mode where no human may be directly interacting
with it. For example, a CGI application or a CRON job.

You can also set this option via a
[[:batch_command_line "command line parameter"]].

==== Complex with / without options

===== with / without warning

Any warnings that are issued will appear on your screen after your program
has finished execution. Warnings indicate minor problems.  A warning will
never terminate the execution of your program. You will simply have to hit
the Enter key to keep going ~-- which may stop the program on an unattended
computer.


The forms available are ...

; ##with warning##
: enables all warnings

; ##without warning##
: disables all warnings

; ##with warning {//warning name list//}\\
  with warning = {//warning name list//}##
: enables only these warnings, and disables all other

; ##without warning {//warning name list//}\\
  without warning = {//warning name list//}##
: enables all warnings except the warnings listed

; ##with warning &= {//warning name list//}\\
  with warning += {//warning name list//}##
: enables listed warnings in addition to whichever are enabled already

; ##without warning &= {//warning name list//}\\
  without warning += {//warning name list//}##
: disables listed warnings and leaves any not listed in its current state.

; ##with warning save##
: saves the current warning state, i.e. the list of all enabled
  warnings. This destroys any previously saved state.

; ##with warning restore##
: causes the previously saved state to be restored.

; ##without warning strict##
: overrides some of the warnings that the -STRICT command line option tests for,
  but only until the end of the next function or procedure. The warnings overridden
  are
  * default_arg_type
  * not_used
  * short_circuit
  * not_reached
  * empty_case
  * no_case_else


The **with/without warnings** directives will have no effect if the
##-STRICT## command line switch is used. The latter turns on all warnings
and ignores any **with/without warnings** statement. However, it can be
temporarily affected by the "##without warning strict##" directive.

----

 **Warning Names**

----

|= Name |= Meaning
| ##none##     | When used with the ##with## option, this turns off all
                 warnings. When used with the ##without## option, this turns on
                 all warnings.
| ##resolution## | an identifier was used in a file, but was defined in
                   a file this file doesn't (recursively) include.
| ##short_circuit## | a routine call may not take place because of short circuit
                       evaluation in a conditional clause.
| ##override## | a built-in is being overridden
| ##builtin_chosen## | an unqualified call caused Euphoria to choose between a
                         built-in and another global which does not override it.
                         Euphoria chooses the built-in.
| ##not_used## |  A variable has not been used and is going out of scope.
| ##no_value## | A variable never got assigned a value and is going out of scope.
| ##custom## |  Any warning that was defined using the ##warning## procedure.
| ##not_reached## | After a keyword that branches unconditionally, the only
                    thing that should appear is an end of block keyword, or
                    possibly a label that a goto statement can target.
                    Otherwise, there is no way that the statement can be
                    reached at all. This warning notifies this condition.
| ##translator## | An option was given to the translator, but this option is
                   not recognized as valid for the C  compiler being used.
| ##cmdline## | A command line option was not recognized.
| ##mixed_profile## | For technical reasons, it is not possible to use
                      both ##with profile## and ##with profile_time## in the
                      same section of code. The profile statement read
                      last is ignored, and this warning is issued.
| ##empty_case## | In ##switch## that have ##without fallthru##, an empty case
                   block will result in no code being executed within the switch
                   statement.
| ##default_case## | A ##switch## that does not have a ##case else## clause.
| ##default_arg_type## | Reserved (not in use yet)
| ##deprecated## | Reserved (not in use yet)
| ##all## | Turns all warnings on. They can still be disabled by
               with/without warning directives.

**Example**
<eucode>
with warning save
without warning &= (builtin_chosen, not_used)
 . . . -- some code that might otherwise issue warnings
with warning restore
</eucode>

Initially, only the following warnings are enabled:

* ##resolution##
* ##override##
* ##builtin_chosen##
* ##translator##
* ##cmdline##
* ##mixed_profile##
* ##not_reached##
* ##custom##

This set can be changed using -W or -X command line switches.

@[with_define|]
===== with / without define

As mentioned about [[:ifdef statement]], this top level statement is used to
define/undefine tags which the ifdef statement may use.

The following tags have a predefined meaning in Euphoria:

* WINDOWS:    platform is any version of Windows (tm) from '95 on to Vista and beyond
* WINDOWS:  platform is any kind of Windows system
* UNIX:     platform is any kind of Unix style system
* LINUX:    platform is Linux
* FREEBSD:  platform is FreeBSD
* OSX:      platform is OS X for Macintosh
* SAFE:     turns on a slower debugging version of ##memory.e## called
            ##safe.e## when defined. Switching mode by renaming files **//no longer works//**.
* EU4:      defined on all versions of the version 4 interpreter
* EU4_0:    defined on all versions of the interpreter from 4.0.0 to 4.0.X
* EU4_0_0:  defined only for version 4.0.0 of the interpreter

The name of a tag may contain any character that is a valid
identifier character, that is ##A-Za-z0-9_##. It is not required, but
by convention defined words are upper case.

@[with_inline|]
==== with / without inline

This directive allows coders some flexibility with inlined routines. The default
is for inlining to be on.  Any routine that is defined when ##without inline##
is in effect will never be inlined.

##with inline## takes an optional integer parameter that defines the largest
routine (by size of IL code) that will be considered for inlining.  The default
is 30.
%%output=syntax_toc
= Formal Syntax
<<LEVELTOC level=1 depth=2>>

!!CONTEXT:../docs/syntax.txt
%%output = syntax

== Formal Syntax

=== Basics

The syntax of Euphoria is described using a form of BNF notation.

{{{
ALPHA ==: ('a' - 'z') | ('A' - 'Z')
DIGIT ==: ('0' - '9')
USCORE ==: '_'
EOL ==: new line character

IDENTIFIER ==: ( ALPHA | USCORE ) [(AlPHA | DIGIT | USCORE) ... ]

EXPRESSION ==: NUMEXPR | STREXPR | SEQEXPR | BOOLEXPR

NUMEXPR ==: (an expression that evaluates to an atom)

STREXPR ==: (an expression that evaluates to a string sequence)

SEQEXPR ==: (an expression that evaluates to an sequence)

BOOLEXPR ==: (an expression that evaluates to an atom in which zero represents 
              falsehood and non-zero represents truth)
              
BINARYEXPR ==: [ EXPRESSION BINOP EXPRESSION ]

BINOP ==: 'and' | 'or' | 'xor' | '+' | '-' | '*' | '/' 

UNARYEXPR ==: [ UNARYOP EXPRESSION ]

UNARYOP ==: 'not' | '-'

STATEMENT ==: 

STMTBLK ==: STATEMENT [STATEMENT ...]

LABEL       ==:  'label' STRINGLIT

LISTDELIM   ==:  ','

STRINGLIT   ==: SIMPLESTRINGLIT | RAWSTRINGLIT

SIMPLESTRINGLIT ==: SSLITSTART [ (CHAR | ESCCHAR) ... ] SSLITEND
SSLITSTART  ==: '"'
SSLITEND    ==: '"'
CHAR        ==: (any byte value)
ESCCHAR     ==: ESCLEAD ( 't' | 'n' | 'r' | '\' | '"' \ ''')
ESCLEAD     ==: '\'

RAWSTRINGLIT ==: DQRAWSTRING | BQRAWSTRING
DQRAWSTRING ==: '"""' [ MARGINSTR ] [CHAR ...] '"""'
BQRAWSTRING ==: '`' [ MARGINSTR ] [CHAR ...] '`'
MARGINSTR  ==: '_' ...

SCOPETYPE ==: 'global' | 'public' | 'export' | 'override'

DATATYPE ==: 'atom' | 'integer' | 'sequence' | 'object' | IDENTIFER
}}}

=== Statements

==== Directives

[[:INCLUDESTMT]]\\
[[:WITHSTMT]]\\
[[:NAMESPACE]]\\

==== Variables, Constants, Enums
[[:VARDECLARE]]\\
[[:CONSTDECLARE]]\\
[[:ENUMDECLARE]]\\
[[:SLICING]]\\

==== Flow Control

[[:IFSTMT]]\\
[[:SWITCHSTMT]]\\
[[:BREAKSTMT]]\\
[[:CONTINUESTMT]]\\
[[:RETRYSTMT]]\\
[[:EXITSTMT]]\\
[[:FALLTHRUSTMT]]\\
[[:FORSTMT]]\\
[[:WHILESTMT]]\\
[[:LOOPSTMT]]\\
[[:GOTOSTMT]]\\
[[:CALL]]\\
[[:IFDEFSTMT]]\\

==== Routines

[[:PROCDECLARE]]\\
[[:FUNCDECLARE]]\\
[[:TYPEDECLARE]]\\
[[:RETURN]]\\

==== include

@[INCLUDESTMT]
{{{
 INCLUDESTMT  ==:  'include' FILEREF [ 'as' NAMESPACEID ] EOL
 FILEREF  ==:  A file path that may be enclosed in double-quotes. 
 NAMESPACEID ==: IDENTIFIER  
}}}
**NOTE** that after the file reference, the only text allowed is the keyword 
'as' or the start of a comment. Nothing else is permitted on the same text line.

    See Also: [[:include statement]]

=== Sequence Slice
@[SLICING]

{{{
SLICE      ==: SLICESTART INTEXPRESSION SLICEDELIM INTEXPRESSION SLICEEND
SLICESTART ==: '['
SLICEDELIM ==: '..'
SLICEEND   ==: ']'
}}}
    See Also: [[:Slicing of Sequences]]

=== if
@[IFSTMT]

{{{
 IFSTMT  ==:  IFTEST [ ELSIF ...] [ELSE] ENDIF 
 IFTEST  ==:  'if' ATOMEXPR [ LABEL ] 'then' [ STMTBLOCK ] 
 ELSIF   ==:  'elsif' ATOMEXPR 'then' [ STMTBLOCK ] 
 ELSE    ==:  'else' [ STMTBLOCK ] 
 ENDIF   ==:  'end' 'if' 
}}}
    See Also: [[:if statement]]

=== ifdef
@[IFDEFSTMT]

{{{
 IFDEFSTMT  ==:  IFDEFTEST [ ELSDEFIF ...] [ELSEDEF] ENDDEFIF 
 IFDEFTEST  ==:  'ifdef' DEFEXPR 'then' [ STMTBLOCK ] 
 ELSDEFIF   ==:  'elsifdef' DEFEXPR 'then' [ STMTBLOCK ] 
 ELSEDEF    ==:  'elsedef' [ STMTBLOCK ] 
 ENDDEFIF   ==:  'end' 'ifdef' 
 DEFEXPR    ==:  DEFTERM [ DEFOP DEFTERM ]
 DEFTERM    ==:  [ 'not' IDENTIFIER ]
 DEFOP      ==:  'and' | 'or'
}}}
    See Also: [[:ifdef statement]]

==== switch
@[SWITCHSTMT]

{{{
 SWITCHSTMT  ==:  SWITCHTEST CASE [ CASE ...] [ CASEELSE ] [ ENDSWITCH ]
 SWITCHTEST  ==:  'switch' EXPRESSION [ WITHFALL ] [ LABEL ] 'do'
 WITHFALL    ==:  ('with' | 'without') 'fallthru'
 CASE        ==:  'case' CASELIST 'then' [ STMTBLOCK ]
 CASELIST    ==:  EXPRESSION [(LISTDELIM EXPRESSION) ...]
 CASEELSE    ==:  'case' 'else'
 ENDSWITCH   ==:  'end' 'switch'
}}}
    See Also: [[:switch statement]]

=== break
@[BREAKSTMT]

{{{
 BREAKSTMT       ==:  'break' [ STRINGLIT ]
}}}
    See Also: [[:break statement]]

=== continue
@[CONTINUESTMT]

{{{
 CONTINUESTMT       ==:  'continue' [ STRINGLIT ]
}}}
    See Also: [[:continue statement]]

=== retry
@[RETRYSTMT]

{{{
 RETRYSTMT       ==:  'retry' [ STRINGLIT ]
}}}
    See Also: [[:retry statement]]

=== exit
@[EXITSTMT]

{{{
 EXITSTMT       ==:  'exit' [ STRINGLIT ]
}}}
    See Also: [[:exit statement]]

=== fallthru
@[FALLTHRUSTMT]

{{{
 FALLTHRUSTMT       ==:  'fallthru'
}}}
    See Also: [[:switch statement]]

=== for
@[FORSTMT]

{{{
 FORSTMT ==: 'for' FORIDX [ LABEL ] 'do' [STMTBLK] 'end' 'for'
 FORIDX  ==: IDENTIFIER '=' NUMEXPR 'to' NUMEXPR ['by' NUMEXPR]
}}}
    See Also: [[:for statement]]

=== while
@[WHILESTMT]

{{{
WHILESTMT ==: 
        'while' BOOLEXPR [WITHENTRY] [LABEL] 'do' STMTBLK [ENTRY] 'end' 'while'
WITHENTRY ==: 'with' 'entry'
ENTRY ==: 'entry' [STMTBLK]
}}}
   See Also: [[:while statement]]

=== loop
@[LOOPSTMT]

{{{
LOOPSTMT ==: 
   'loop' [WITHENTRY] [LABEL] 'do' STMTBLK [ENTRY] 'until' BOOLEXPR 'end' 'loop'
}}}
   See Also: [[:loop until statement]]

=== goto
@[GOTOSTMT]

{{{
 GOTOSMT ==: 'goto' LABEL
}}}
  See Also: [[:goto statement]]

=== declare a variable
@[VARDECLARE]
{{{
VARDECLARE ==: [SCOPETYPE] DATATYPE IDENTLIST
IDENTLIST ==: IDENT [',' IDENTLIST]
IDENT ==: IDENTIFIER [ '=' EXPRESSION ]
}}}
Notes:
* The type of the ##EXPRESSION## must be compatable with the ##DATATYPE##.

=== declare a constant
@[CONSTDECLARE]
{{{
CONSTDECLARE ==: [SCOPETYPE] 'constant' IDENTLIST
}}}

=== declare an enumerated value
@[ENUMDECLARE]
{{{
ENUMDECLARE ==: [SCOPETYPE] [ ENUMVAL | ENUMTYPE ]
ENUMVAL ==: 'enum' ['by' ENUMDELTA ] IDENTLIST
ENUMDELTA ==: [ '+' | '-' | '*' | '/' ] NUMEXPR
ENUMTYPE ==: 'enum' 'type' ['by' ENUMDELTA ] IDENTLIST 'end' 'type'
}}}

  
=== call a procedure or function
@[CALL]
Used to call (invoke) either a procedure or a function.
{{{
CALL ==: IDENTIFIER '(' [ARGLIST] ')'
ARGLIST ==: ARGUMENT [',' ARGLIST]
}}}
  See Also: [[:procedures]] [[:functions]]
  
=== declare a procedure
@[PROCDECLARE]
{{{
PROCDECLARE ==: [SCOPETYPE] 'procedure' IDENTIFIER '(' [PARMLIST] ')' [STMTBLK] 'end' 'procedure'
PARMLIST ==: PARAMETER [',' PARMLIST]
PARAMETER ==: DATATYPE IDENTIFER
}}}
Notes:
* The ##procedure## statement block **must not** contain a ##return## statememt.

  See Also: [[:procedures]]
  
=== declare a function
@[FUNCDECLARE]
{{{
FUNCDECLARE ==: [SCOPETYPE] 'function' IDENTIFIER '(' [PARMLIST] ')' [STMTBLK] 'end' 'function'
PARMLIST ==: PARAMETER [',' PARMLIST]
PARAMETER ==: DATATYPE IDENTIFER
}}}
Notes:
* The ##function## statement block **must** contain a ##return## statememt.

  See Also: [[:functions]]
  
=== declare a user defined type
@[TYPEDECLARE]
{{{
TYPEDECLARE ==: [SCOPETYPE] 'type' IDENTIFIER '(' PARAMETER ')' [STMTBLK] 'end' 'type'
PARAMETER ==: DATATYPE IDENTIFER
}}}
Notes:
* The ##type## statement block **must** contain a ##return## statememt.
* It must return an integer; 0 means that the supplied argument is not of the correct type.

  See Also: [[:types]]
  
=== return the result of a function
@[RETURN]
{{{
RETURN ==: 'return' EXPRESSION
}}}

  See Also: [[:types]]
  
=== default namespace
{{{
NAMESPACE ==: 'namespace' IDENTIFIER EOL
}}}

  See Also: [[:Using namespaces]]
  
=== with options
@[WITHSTMT]
{{{
WITHSTMT ==: [ "with" | "without" ] WITHOPTION
WITHOPTION ==: [ "profile" | "profile_time" | "trace" | "batch" |
                 "type_check" | "indirect_includes" | "inline" | WITHWARNING ]
WITHWARNING ==: "warning" [ WARNOPT]
WARNOPT ==: SETWARN | ADDWARN | SAVEWARN | RESTOREWARN | STRICTWARN
SETWARN ==: ['='] '{' WARNLIST '}'
ADDWARN ==: ['+=' | '&='] '{' WARNLIST '}'
SAVEWARN ==: 'save'
RESTOREWARN ==: 'restore'
STRICTWARN ==: 'strict'
}}}

  See Also: [[:with / without]]

!!CONTEXT:../docs/internals.txt
%%output = internals

== Euphoria Internals ==

The interpreter has four binary components:
* Interpreter
* Translator
* Backend  
* Library

The Euphoria interpreter has two parts: the frontend and the backend. The
**frontend** is a parser that converts source-code into a set of
**Intermediate Language** (IL) instructions. The **backend** then takes the
IL instructions and executes the program.

When the //interpreter// executes source-code, the frontend parses and prepares
the code, and then the backend executes the code.

When the //shrouder// executes source-code, only the frontend is run producing
an ##.il## file. This ##.il## file may be run by the backend as an
independent step to execute the program.

When the //binder// executes source-code, the ##.il## instructions produced
by the frontend are combined with the backend to produce a stand-alone
executable program. The executable program may then be run independetly at any
time.

When the //translator// executes source-code, the ##.il## instructions are
translated into C-code. This C-code is compiled with an installed C compiler
producing an executable program.

The //library// is called by the backend for the many builtins included in 
Euphoria.

=== The Euphoria Data Structures ===

==== The Euphoria representation of a Euphoria Object =====

Every Euphoria object is stored as-is.  A special unlikely floating point value 
is used for ##NOVALUE##.  ##NOVALUE## signifies that a variable has not been 
assigned a value or the end of a sequence.

==== The C Representation of a Euphoria Object =====

Every Euphoria object is either stored as is, or as an encoded pointer.  A 
Euphoria ##integer## is stored in a 32-bit signed integer.  If the number is too
big for a Euphoria ##integer##, it is assigned to a 64-bit double float in a 
structure and an encoded pointer to that structure is stored in the said 32-bit 
memory space.  Sequences are stored in a similar way.

{{{

 32 bit number range:
  0X8      0XA      0XC      0XE      0X0      0X2      0X4      0X6      0X8
-4*2^29  -3*2^29  -2*2^29-1  -2^29   0*2^29   1*2^29   2*2^29   3*2^29 4*2^29 
   *--------*--------*--------*--------*--------*--------*--------*--------o
                     o NOVALUE = -2*2^29-1
		     o<-----------ATOM_INT---------[-2*2^29..4*2^29)------>o
	    |<----------------ATOM_DBL-------[-3*2^29..4*2^29)------------>o
-->|        |<-- IS_SEQUENCE [-4*2^29..-3*2^29)
-->|                 o<--- IS_DBL_OR_SEQUENCE [-4*2^29..-2*2^29-1)
-->|sequence|<-------
            |<------------------  atom   --------------->|
    ------->| double |<--------  
                     |<--------     integer    --------->|
   |<--------------------- object ---------------------->|		     

}}}


Euphoria integers are stored in object variables as-is.  An object variable is a
four byte signed integer.  Legal integer values for Euphoria integers are 
between -1,073,741,824 ( -2^^30^^ ) and +1,073,741,823 ( 2^^30^^-1 ).
Unsigned hexadecimal numbers from C000_0000 to FFFF_FFFF are the negative 
integers and numbers from 0000_0000 to 3FFF_FFFF are the positive integers.  The
hexadecimal values not used as integers are thus 4000_0000 to BFFF_FFFF.  Other 
values are for encoded pointers.  Pointers are always 8 byte aligned.  So a 
pointer is stored in 29-bits instead of 32 and can fit in a hexadecimal range 
0x2000_0000 long. The pointers are encoded in such a way that their encoded values 
will never be in the range of the integers. Pointers to sequence structures 
(struct s1) are encoded into a range between 8000_0000 to 9FFF_FFFF.  Pointers 
to structures for doubles (struct d) are encoded into a range between A000_0000 
to BFFF_FFFF. A special value NOVALUE is at the end of the range of encoded 
pointers is BFFF_FFFF and it signifies that there is no value yet assigned to a 
variable and it also signifies the end of a sequence.  In C, values of this type
are stored in the 'object' type.  The range 4000_0000 to 7FFF_FFFF is unused.

A double structure 'struct d' could indeed contain a value that is legally in 
the range of a Euphoria integer.  So the encoded pointer to this structure is 
recognized by the interpreter as an 'integer' but in this internals document 
when we say Euphoria integer we mean it actually is a C integer in the legal 
Euphoria integer range.


=== The C Representations of a Euphoria Sequence and a Euphoria Atom =====

{{{
// Sequence Header 
struct s1
{
 object_ptr base;     // base is such that base[1] is the first element
 long length;         // this is the sequence length
 long ref;            // ref is the number of as virtual copies of this sequence
 long postfill;       // is how many extra objects could fit at the end of base
 cleanup_ptr cleanup; // this is a pointer to a Euphoria routine that is run 
                      // just before the sequence is freed.
}

}}}

However, we allocate more than this structure.  Inside the allocated data but past the structure,
there also is 
an area of 'pre free space'; sequence data pointed to by base[1] to base[$], $ being the length;
a NOVALUE terminator for the sequence, 
and an area of post fill space.  In memory, immediately following the structure there is the following data stored:

{{{
 object pre_fill_space[]; // could have 0 (not exist) or more elements before used data
 object base[1..$];       // sequence members pointed to by base
 object base[$+1];        // a magic number terminating the sequence members (NOVALUE)
 object post_fill_space[];// could have 0 (not exist) or more elements after used data
}}} 

Taken together these are what get represented in memory.
|  base  | length |   ref  |postfill| cleanup|  pre fill space | base[1..$] | ##NOVALUE## | post fill space  |

By their nature, sequences are variable length, dynamic entities and so the C structure needs to
cater for this. When a sequence is created, we allocate enough RAM for the combined header and the
initial storage for the elements. 

|= Field    |= Description |
|  base     | This contains the address of the first element less the
              length of one element. Thus ##base[1]## points to the first
              element and ##base[0]## points to a fictitious element just
              before the first one, which is never used.\\
              Initially, ##base## contains the address of the last member of
              the sequence header but 
              as the sequence is resized, it can point to the last member or anywhere after.
|  length   | Contains the current number of elements in the sequence.
|  ref      | Contains the count of references to this sequence. Only when
              this is zero, can the RAM used by the sequence be returned to
              the system for reuse. 
|  postfill | The size of 'post fill space' in element spaces.  Rather than using bytes,
              postfill is measured in objects which are each address wide elements.  
              If this is non-zero, we can append to
              the sequence with at most ##postfill## new elements before needing
              to reallocate RAM.\\
|  cleanup  | If not null, it points to a routine that is called immediately before
              the sequence is deleted.\\
| pre fill space | There are 0 or more spaces before base[1].  We can calculate
              the free space in *objects* at the front of a sequence, s1, in C by\\ 
              ##(&s1.base[1] - (object_ptr)(1+&s1))##.\\  
              In EUPHORIA, you will have to divide by the size of a C_POINTER on the difference.
              When elements are removed from the front of a sequence, we simply
              adjust the address in ##base## to point to the new //first// element
              and reduce the ##length## count.  
              If we want to prepend and this pre fill space has some positive size, then we make room by decrementing ##base## and increment the ##length##.  The new data is then assigned to ##base##[1].
| base[1]..base[length] sequence data |      This is actual data.
| base[$+1]  |      This is always set to ##NOVALUE##.
| post fill space | There are 0 or more spaces after ##base##[##length##+1].  The number of spaces is stored in 
                    ##postfill##.  If ##postfill## is non-zero we can append by incrementing the ##length##, decrementing ##postfill## and assigning the new data to ##base##[$].
                    When we remove from the end of the sequence, we increment ##postfill## and
                    decrement the ##length##.


{{{
// Atom Header
struct d
{
 double dbl;          // the actual value of a double number.
 long ref;            // ref is the number of virtual copies of this double
 cleanup_ptr cleanup; // this is a pointer to a Euphoria routine that is run 
                      // just before the sequence is freed.
}
}}}


Now offset of the 'ref' in struct d must be the same as the offset of the 'ref' 
in struct s1.  To this end, the 64bit implementation of 4.1 has these members in a different order.

=== The Euphoria Object Macros and Functions ===

==== Description

The macros are imperfect.  For example, ##IS_SEQUENCE(NOVALUE)## returns 
##TRUE## and ##IS_ATOM_DBL## will return ##TRUE## for integer values as well 
as encoded pointers to
'struct d's.   This is why there is an order that these tests are made: We test 
##IS_ATOM_INT## and if that fails we can use ##IS_ATOM_DBL## and then that will 
only be true if we pass an encoded pointer to a double.  We must be sure that 
something is not ##NOVALUE## before we use ##IS_SEQUENCE## on it.

// Often we know foo is not NOVALUE before getting into this://

{{{
// object foo
if (IS_ATOM_INT(foo)) {
 // some code for a Euphoria integer
} else if (IS_ATOM_DBL(foo)) {
 // some code for a double
} else {
 // code for a sequence foo
}
}}}

A sequence is held in a 'struct s1' type and a double is contained in a 
'struct d'.


=== Type Value Functions and Macros

@[:internals:IS_ATOM_INT|]
==== IS_ATOM_INT
<eucode>
<internal> int IS_ATOM_INT( object o )
</eucode>

===== Returns
true if object is a Euphoria integer and not an encoded pointer.

===== Note
##IS_ATOM_INT## will return true even though the argument is out of the 
Euphoria integer range when the argument is positive.  These values 
are not possible encoded pointers.


@[:internals:IS_ATOM_DBL|]
==== IS_ATOM_DBL
<eucode>
<internal> int IS_ATOM_DBL( object o )
</eucode>

===== Returns
true if the object is an encoded pointer to a double struct.

===== Assumption
//o// must not be a Euphoria integer.




@[:internals:IS_ATOM|]
==== IS_ATOM
<eucode>
<internal> int IS_ATOM( object o )
</eucode>

===== Returns
true if the object is a Euphoria integer or an encoded pointer to a 
##'struct d'##. 


@[:internals:IS_SEQUENCE|]
==== IS_SEQUENCE
<eucode>
<internal> int IS_SEQUENCE( object o )
</eucode>

===== Returns
true if the object is an encoded pointer to a ##'struct s1'##.

===== Assumption
//o// is not NOVALUE.


@[:internals:IS_DBL_OR_SEQUENCE|]
==== IS_DBL_OR_SEQUENCE
<eucode>
<internal> int IS_DBL_OR_SEQUENCE( object o )
</eucode>

===== Returns
true if the object is an encoded pointer of either kind of structure.


=== Type Conversion Functions and Macros


@[:internals:MAKE_INT|]
==== MAKE_INT
<eucode>
<internal> object MAKE_INT( signed int x )
</eucode>

===== Returns
an object with the same value as x.  x must be with in the integer range of a 
legal Euphoria integer type.

@[:internals:MAKE_UINT|]
==== MAKE_UINT
<eucode>
<internal> object MAKE_UINT( unsigned int x )
</eucode>

===== Returns
an object with the same value as x.  

===== Assumption
x must be an **unsigned** integer with in the integer range of a C unsigned 
int type.

===== Example
MAKE_UINT(4*1000*1000*1000) will make a Euphoria value of four billion by 
creating a double.

@[:internals:MAKE_SEQ|]
==== MAKE_SEQ
<eucode>
<internal> object MAKE_SEQ( struct s1 * sptr )
</eucode>

===== Returns
an object with an argument of a pointer to a ##'struct s1'##
The pointer is encoded into a range for sequences and returned.

@[:internals:NewString|]
==== NewString
<eucode>
<internal> object NewString(char *s)
</eucode>

===== Returns
an object representation of a Euphoria byte string s.  The returned encoded 
pointer is a sequence with all of the bytes from s copied over.

@[:internals:MAKE_DBL|]
==== MAKE_DBL
<eucode>
<internal> object MAKE_DBL( struct d * dptr )
</eucode>

===== Returns
an object with an argument of a pointer to a ##'struct d'##
The pointer is encoded into a range for doubles and returned.


@[:internals:NewDouble|]
==== NewDouble
<eucode>
<internal> object NewDouble( double dbl )
</eucode>

===== Returns
an object with an argument a double ##dbl##.  A ##struct d## is allocated and 
dbl is assigned to the value part of that structure.  The pointer is encoded 
into the  range for doubles and returned.


@[:internals:DBL_PTR|]
==== DBL_PTR
<eucode>
<internal> struct d * DBL_PTR( object o )
</eucode>

===== Returns
The pointer to a 'struct d' from the object o.

===== Assumption
IS_ATOM_INT(o) is FALSE and IS_ATOM_DBL(o) is TRUE.


@[:internals:SEQ_PTR|]
==== SEQ_PTR
<eucode>
<internal> struct s1 * SEQ_PTR( object o )
</eucode>

===== Returns
The pointer to a ##'struct s1'## from the object o.

===== Assumption
IS_SEQUENCE(o) is TRUE and //o// is not NOVALUE.

@[:internals:get_pos_int|]
===== get_pos_int
<eucode>
#include be_machine.h
<internal> uintptr_t get_pos_int(char *where, object x)
</eucode>

===== Returns
a unsigned long value by truncating what x's value is to an integer

===== Comment
Any object may be passed.  A sequence results in a runtime failure.
There may be a cast of a double to a smaller ranged long type.


=== Creating Objects

@[:internals:NewS1|]
==== NewS1
<eucode>
<internal> object NewS1 ( long size )
</eucode>

===== Returns
A sequence object with size members which are not yet set to a value.



=== Object Constants

Use MAXINT and MININT to check for overflow and underflow, NOVALUE to check if a 
variable has not
been assigned, and use NOVALUE to terminate a sequence.

@[:internals:NOVALUE|]
==== NOVALUE
<eucode>
<internal> object NOVALUE
</eucode>

Indicates that a variable has not been assigned and also terminates a sequence.

@[:internals:MININT|]
==== MININT
<eucode>
<internal> signed int MININT
</eucode>

The minimal Euphoria integer.  This is -(2^^30^^).


@[:internals:MAXINT|]
==== MAXINT
<eucode>
<internal> signed int MAXINT
</eucode>

The maximal Euphoria integer.  This is 2^^30^^-1.

@[:internals:HIGH_BITS|]
==== HIGH_BITS
<eucode>
<internal> signed int HIGH_BITS
</eucode>

HIGH_BITS is an integer value such that if another integer value c lies outside of the range 
between MININT and MAXINT, c+HIGH_BITS will be non-negative.

===== Proof that HIGH_BITS is #C000_0000 on 32-bit version of EUPHORIA.
   *In the following expressions powers have higher precedence than unuary minus.*
   if c is a non-ATOM-INT value, then
   
   c belongs to the set  [-2^^31^^,-2^^30^^-1(=NOVALUE)] U [2^^30^^,2^^31^^].
   
   c+-2^^30^^ belongs to the set  [-2^^31^^-2^^30^^,-2^^30^^-1-2^^30^^] U [2^^30^^-2^^30^^,2^^30^^]
    which is [-3*2^^30^^,-2^^31^^-1] U [0,2^^30^^].  However the lower values wrap around 
    to non-negative numbers:
    
   -2^^31^^-1 wraps to 2^^31^^-1.  -3*2^^30^^ wraps around to 2^^30^^.
   
   c+-2^^30^^ belongs to the set  [2^^30^^,2^^31^^-1] U [0,2^^30^^] = [0,2^^31^^-1]
   
   This is the set of all non-negative numbers that can fit into 32-bit signed
   longs.  -2^^30^^ is the unsigned version of #C000_0000.  QED.
   
   A visual way of looking at it is, adding #C000_0000 to the set of non-ATOM_INTS 
   rotates the set to the negative side by -MININT (2^30).  The already negative ones wrap 
   around to the positive; the positive numbers stay positive and hug the zero.  
   Since adding #C000_0000 on registers is 1-1 and onto, we also know that ATOM_INTs
   will all be mapped to negative signed longs.
   
   
===== Testing for Overflow:
    There are two ways to test for overflow:
    	# (c > MAXINT) || (c < MININT)
        # (c + HIGH_BITS) >= 0
        
==== Parser

Inserting tokens into the token buffer is the easiest way to add features to the EUPHORIA parser.
The tokens are two-element sequences one of the class of token and the other the token's value:
 
 {<class>,<value>}
 
Each of the class values are capitalized words for some keyword or VARIABLE.  
The list of constants is in reswords.e.  Often it is enough to only examin the class.
In the case of variables, it is important to know which variable.
In this case the second element, comes into play.

You can use ##putback## to put tokens into the token buffer.  The tokens will be pulled out
by the parser in a filo manner, like a stack.  

==== Backend Instructions

After the Parser processes the instructions.  It creates Backend instructions that
are easily translated or interpreted.  The system uses opcodes and some parameters which
are put on a stack.  This backend language is similar to assembler.  You have
opcodes (instructions) and parameters.  These parameters must be integers themselves but
some may serve as pointers to arbitrary EUPHORIA objects.  As a developer of EUPHORIA itself,
rather than a developer that uses EUPHORIA, it is important to know exactly what these
opcodes do and what they are for.  In this section we will document what they are for,
and how they manipulate the instruction pointer, and stack.


IF instruction:

The IF instruction is used for making runtime branch statements.  The IF instruction takes
the top of the stack as the condition value, if the condition is 0, it passes control to
the address stored just below the top of the stack.  If the condition is non-zero and
an atom the instruction pointer just past the failure address.

[ IF instruction ] [ test value ] [ failure address ]


INTEGER_CHECK instruction:

The INTEGER_CHECK is used to ensure that something has a value considered to be
'integer' to the EUPHORIA language definition.  The instruction takes the next argument as
a pointer to a value and determines whether this value is in the legal integer range,
regardless of how that number is represented.  If not in legal range, then 
the program ends execution in a type-check failure error message.

[ INTEGER_CHECK instruction ] [ test pointer ]

ATOM_CHECK instruction:

The ATOM_CHECK is used to determine whether something has a numeric value rather than
a sequence.  The instruction takes an argument as a pointer to a value and
determines whether the value is an atom.  If it is not an atom, then the program
ends execution in a type-check failure error message.

[ ATOM_CHECK instruction ] [ test pointer ]

IS_AN_INTEGER instruction:

The IS_AN_INTEGER instruction is used to determine whether something has a value considered to
be 'integer' to the EUPHORIA language definition.  The instruction takes the argument as 
a pointer to a value and determines whether this value is in the legal integer range, 
regardless of how that number is represented.  If it is in the 'integer' range then 
the value pointed by the second argument will be 1 otherwise it will be 0.

[ IS_AN_INTEGER instruction ] [ test pointer ][ return value pointer ]
%%output=miniguide
= Mini-Guides
<<LEVELTOC level=1 depth=2>>
%%output=demos
== Bundled Demos
<<LEVELTOC level=2 depth=3>>

!!CONTEXT:../demo/allsorts.ex
%%output = allsorts

=== allsorts.ex
Comparison of different sorting algorithms.

==== Notes

The slower sorts will be omitted after a while.

Bucket sort looks really good, but remember that the other sorts are
generic, and can handle integers, floating-point numbers, strings, etc.
Bucket sort can only sort integers, and the integers need to be
in a reasonably small, well-defined range, as is the case in this
benchmark. It also uses more memory than some of the other sorts.



@[:quick_sort|]
==== quick_sort
<eucode>
include allsorts.ex
global function quick_sort(sequence x)
</eucode>



@[:hybrid_sort|]
==== hybrid_sort
<eucode>
include allsorts.ex
global function hybrid_sort(sequence x)
</eucode>



@[:great_sort|]
==== great_sort
<eucode>
include allsorts.ex
global function great_sort(sequence a)
</eucode>



@[:merge_sort|]
==== merge_sort
<eucode>
include allsorts.ex
global function merge_sort(sequence x)
</eucode>




!!CONTEXT:../demo/animal.ex
%%output = animal

=== animal.ex

Guess the Animal game. It learns as you play.

==== How it Works

animal.ex builds up a tree structure that tells it what
question to ask, and which branch to follow in the tree
depending on whether the answer is Yes or No.


@[:animal|]
==== animal
<eucode>
include animal.ex
global procedure animal()
</eucode>




!!CONTEXT:../demo/ascii.ex
%%output = ascii

=== ascii.ex

Display ASCII / code page chart in 50 lines-per-screen mode



!!CONTEXT:../demo/buzz.ex
%%output = buzz

=== buzz.ex

Buzzword Generator. Try adding your own phrases!

==== How it Works

buzz has lists of parts of sentences that it matches up at random.
It will always make a grammatically correct sentence.




!!CONTEXT:../demo/callmach.ex
%%output = callmach

=== callmach.ex

Examples of calling a machine code routine from Euphoria



!!CONTEXT:../demo/color.ex
%%output = color

=== color.ex

Test terminal colours

==== Note

Seems to be working on some terminals, but not others



!!CONTEXT:../demo/csort.ex
%%output = csort

=== csort.ex

Demo of custom_sort(), routine_id() The Euphoria custom_sort routine is passed the
routine id of the comparison function to be used when sorting.




!!CONTEXT:../demo/dep.exw
%%output = dep

=== dep.exw

Perform a simple DEP test on your system




!!CONTEXT:../demo/eprint.ex
%%output = eprint

=== eprint.ex

Print a Euphoria program

This works with HP PCL printers.
You can change control codes (bold, italics etc) for other printers.
If you have a color printer you can choose colors,
otherwise you will simply get keywords in bold, comments in italics.
You can print non-Euphoria files too.

==== Usage
{{{
eprint filename
}}}

You will be asked if you want to print in color,
and if you want to print in condensed mode.

==== Note

Doesn't yet work under Linux



@[:NORMAL_COLOR|]
==== NORMAL_COLOR
<eucode>
include eprint.ex
global constant NORMAL_COLOR
</eucode>





@[:COMMENT_COLOR|]
==== COMMENT_COLOR
<eucode>
include eprint.ex
global constant COMMENT_COLOR
</eucode>





@[:KEYWORD_COLOR|]
==== KEYWORD_COLOR
<eucode>
include eprint.ex
global constant KEYWORD_COLOR
</eucode>





@[:BUILTIN_COLOR|]
==== BUILTIN_COLOR
<eucode>
include eprint.ex
global constant BUILTIN_COLOR
</eucode>





@[:STRING_COLOR|]
==== STRING_COLOR
<eucode>
include eprint.ex
global constant STRING_COLOR
</eucode>





@[:BRACKET_COLOR|]
==== BRACKET_COLOR
<eucode>
include eprint.ex
global constant BRACKET_COLOR
</eucode>






!!CONTEXT:../demo/eused.ex
%%output = eused

=== eused.ex

A sed-like utility for Euphoria.

==== Usage

{{{
eui eused.ex <pattern> <replacement> [input file]
eui eused.ex -e <pattern 1> <replacement 1> \
[-e <pattern n> <replacement n>...] [input file]
}}}




!!CONTEXT:../demo/guru.ex
%%output = guru

=== guru.ex

Searches for the best articles that contain the words that you type.
Each word can contain * and ? wildcard characters.
The articles are given a score and presented to you sorted by score.
The scoring system strongly favors articles that contain several of
your words, rather than just several occurrences of one of your words.
Some very common words are ignored (see noise_words).
e.g.
{{{
guru sequence* atom *pend g?r?
}}}

Results are displayed on screen and also saved in "c:\guru.out"
or $HOME/guru.out (Linux).

==== Hints
* remember to add * to words that can be pluralized or have many different endings.
* enter an important word twice to double the value of that word
* If you get a "Critical Error", type 'i' for ignore. It just
means that a file is currently locked by another application.

==== Usage

===== to search EUPHORIA directories:
{{{
guru word1 word2 word3 ...
}}}

Euphoria .doc and other files are searched. .htm files are skipped.

===== To search the current directory and all subdirectories:
{{{
cdguru word1 word2 word3 ...
}}}




!!CONTEXT:../demo/hash.ex
%%output = hash

=== hash.ex

Hash Table Demo written by Junko C. Miura, RDS

This reads a text file and builds a hash table containing all of
the unique words plus a count of how many times each word occurred.
It outputs the words to and a bunch of hash table
statistics to "hash.out".

==== Example
{{{
eui hash \euphoria\doc\library.doc
}}}

hash.ex (hash table) is faster than tree.ex (binary tree),
but does not produce a sorted list of words.

==== How it Works

hashing is generally much faster than searching a long linear list for a
word. Instead of searching one big list, we create hundreds of small
lists, and then use a "hash function" to tell us which small list (or
"bucket") to search. For each word, the hash function will return an
integer. For a given word, the hash function must always return the same
integer. That integer is used as the index into a sequence of small
word-lists. We can quickly search the selected small list for the word.




!!CONTEXT:../demo/key.ex
%%output = key

=== key.ex

Find out what numeric key code is generated by any key on the keyboard

==== Usage
{{{
eui key [keybindfile]
}}}
If you supply a valid file containing key bindings, they will be set prior to
testing the keycodes returned.



!!CONTEXT:../demo/loaddb.ex
%%output = loaddb

=== loaddb.ex




!!CONTEXT:../demo/mydata.ex
%%output = mydata

=== mydata.ex

This program uses the Euphoria Database System (EDS) to create and
maintain a simple database. You can customize this program by modifying
the FIELDS variable (below). You'll have to delete or rename the
"mydata.edb" database file if you change the number of fields.




!!CONTEXT:../demo/news.ex
%%output = news

=== news.ex

Search news pages

All this demo does is read several Web pages in parallel
and report on the number of occurrences of a word or phrase.
Each page is handled by a separate Euphoria task running
in parallel with several other tasks.

==== Usage
{{{
eui news.ex string
}}}

===== or:

{{{
eui news.ex "a multi-word phrase"
}}}

Search is case insensitive.

This demo uses Euphoria's multitasking feature. It can run without change on all
platforms supported by OpenEuphoria.

A Euphoria task is assigned to each instance URL query, searching the
Web page text as it arrives. In this way, when a task is blocked due
to a delayed response from a particular server, the program can easily
switch to another task that is not blocked. The program quits after a
period of 10-15 seconds with no progress made on any page.




!!CONTEXT:../demo/pipes.ex
%%output = pipes

=== pipes.ex

Starts a sub-process and communicates to it via piped io.
The sub process is ##pipe_sub.ex##




!!CONTEXT:../demo/queens.ex
%%output = queens

=== queens.ex

solves the N queens problem - how to place N queens on an NxN
chess board so they do not attack each other




!!CONTEXT:../demo/regexps.ex
%%output = regexps

=== regexps.ex

Shows off some simple regular expression operations




!!CONTEXT:../demo/sanity.ex
%%output = sanity

=== sanity.ex

this program tests hundreds of features of Euphoria, in a quick,
self-test. If this program reports "PASSED" then Euphoria is
working on your machine.

This was the old "unit testing" program for Euphoria pre 4.x, for an
updated unit test system, please see the [[:Unit Testing Framework]]
and look in your ##euphoria/tests## directory.

==== Usage
{{{
eui sanity.ex
}}}



@[:sorted|]
==== sorted
<eucode>
include sanity.ex
global type sorted(sequence x)
</eucode>



@[:sanity|]
==== sanity
<eucode>
include sanity.ex
global procedure sanity()
</eucode>




!!CONTEXT:../demo/search.ex
%%output = search

=== search.ex

This program searches for a string in files of the current directory
and subdirectories.


==== Usage
{{{
search [string]
}}}

If you don't supply a string on the command line you will be prompted
for it. The string may contain * and ? wildcard characters and so may
the list of file specifications. Lines containing the string are
displayed on the screen, and also recorded in %EUDIR%/SEARCH.OUT
(DOS/Windows), or in $HOME/search.out (Linux).
Some statistics are printed at the end.

==== Example
{{{
C:\> search
string: p?oc*re
match case? (n)
file-spec (*.*): *.e *.ex
scan subdirectories? (y)
}}}

==== Note

If you just hit Enter instead of supplying a string to search for,
the program will simply print any file names that match your file-spec.
This is a good way to search for a file, when you can't remember which
directory you put it in.




!!CONTEXT:../demo/tree.ex
%%output = tree

=== tree.ex

Count frequencies of words in standard input.
Uses a binary tree to speed lookups and write
an alphabetic listing to standard output.

==== Usage
{{{
eui tree < file1
}}}

You can direct standard output to a file with '>'

==== How it Works

tree.ex reads in words from a text file and inserts them
alphabetically into a Euphoria sequence that is being used
as a "tree". The tree data structure is created by nesting
sequences inside one another to whatever depth is required.
Looking up a word in a tree is generally faster than searching
through a linear list, since unless the tree is very lop-sided,
we should have fewer comparisons to make.




!!CONTEXT:../demo/where.ex
%%output = where

=== where.ex

search the PATH for all occurrences of a file

==== Usage
{{{
where filename
}}}

(give complete file name including .exe .bat etc.)




!!CONTEXT:../demo/bench/sieve8k.ex
%%output = bench_sieve8k

=== bench/sieve8k.ex

Prime sieve benchmark "Shootout" version

==== Usage
{{{
eui sieve8k <iterations> <largest>
}}}

default is 1 iteration with 8192 as largest allowable prime


==== Interpreter Benchmark Results

The Euphoria interpreter seems to be the world's fastest!

Although it provides subscript checking, uninitialized variable checking,
full dynamic storage allocation, flexible generic data types,
and integer overflow checking, it still manages to "blow away" all other
programming language interpreters that we know of.

The results below are based on the prime sieve benchmark from the
Great Computer Language Shootout by Doug Bagley. The numbers are taken
from the WIN32 version of the Shootout at

http://dada.perl.it/shootout

We chose sieve because it was CPU-intensive, and less trivial than some
of the other benchmarks. It's also integer-based, as most real programs are.
Naturally, you should perform your own benchmarks, based on the type of
programs that are important to you.

==== Our Methodology:

We measured the speed of Euphoria on the version of sieve used in the
Shootout. We measured both the Euphoria interpreter, and the
Euphoria To C Translator. The machine used in the WIN32 Shootout
was a Pentium-4 1.6GHz running Windows XP. Our machine for the Euphoria
measurements was a Pentium-4 1.8GHz, also running Windows XP. We thus
adjusted our times upward by 1.8/1.6, i.e. we added 12.5%. As a check,
we downloaded Python 2.1 and ran sieve with N=900 on our machine. Python
was only about 3% faster on our machine, probably because CPU speed is
not the only factor. Level-2 cache access time may also be important.
To be fair, we nevertheless scaled up all of our Euphoria times by the
full 12.5%.

We ran the Euphoria sieves with N=90000 to get accurate timings. For
comparison, we divided by 100 to match the N=900 used on the WIN32 shootout,
and we added 12.5%.

The Shootout used an external timer on the programs, that necessarily
included start-up times. We used an internal timer in the Euphoria programs,
because it's more accurate, and because we lacked a good external timing
mechanism. To eliminate the start-up times of the other languages,
we subtracted their time for N=1 from their time for N=900. In most cases
the N=1 start-up time was just a tiny percentage of the full N=900 time.
(So we were actually only timing 899 iterations for the other languages.)

==== The Results

Euphoria interpreter, eui.exe:
{{{
For N=90000 on 1.8GHz machine: 41.39 seconds

scaled to N=900 (divide by 100): .4139 seconds

adjusted +12.5% to compare with 1.6 GHz: .4656
}}}

Euphoria To C Translator (with C compilation by Watcom for WIN32):
{{{
For N=90000 on 1.8GHz machine: 11.28 seconds

scaled to N=900 (divide by 100): .1128 seconds

adjusted +12.5% to compare with 1.6 GHz: .1269
}}}

From dada.perl.it/shootout/
prime sieve benchmark (interpreted languages)

N=900 iterations. Start-up time (N=1) was subtracted out
Pentium-4 1.6 GHz

Interpreters, sorted by seconds taken:
(EtoC added for comparison)

|=Lang    |=Score |=Notes                                            |
| Euphoria|  0.13 | EtoC Translator / Watcom                         |
| Euphoria|  0.47 | Interpreted with eui.exe                         |
| pliant  |  0.68 |                                                  |
| gforth  |  0.75 |                                                  |
| parrot  |  2.98 |                                                  |
| ocamlb  |  3.21 |                                                  |
| poplisp |  3.34 |                                                  |
| eu in eu|  7.15 | PD source Euphoria translated/compiled to eu.exe |
| erlang  |  7.16 |                                                  |
| lua     |  8.70 |                                                  |
| pike    | 10.36 |                                                  |
| python  | 14.33 |                                                  |
| icon    | 15.12 |                                                  |
| perl    | 16.36 |                                                  |
| elastic | 16.88 |                                                  |
| guile   | 18.64 |                                                  |
| cygperl | 19.22 |                                                  |
| ruby    | 27.59 |                                                  |
| mawk    | 28.00 |                                                  |
| vbscript| 32.02 |                                                  |
| php     | 67.32 |                                                  |
| jscript | 77.43 |                                                  |
| tcl     | 83.10 |                                                  |
| gawk    | 158.49|                                                  |
| rexx    | 166.85|                                                  |

==== Conclusions

# Euphoria (interpreted) beats all of the other interpreted languages
in the Shootout. All of the well-known languages are beaten by a huge
margin. For instance, Perl is 16.36/.4656 = 35 times slower than
interpreted Euphoria. Python is 31 times slower.
# If you want even greater speed, the Euphoria to C Translator can give
you a factor of .4656/.1269 = 3.7 versus the already-fast interpreter.
In fact, EtoC easily beats many compiled languages such as Java and
C-Sharp (C#) on this benchmark, and it comes close to hand-coded,
fully-optimized C. This is remarkable, since Euphoria code is *much*
easier to write and debug than C. EtoC beats both Perl and Python by
a factor of more than 100!
# Observe that even the version of Euphoria written in pure Euphoria
can run twice as fast as Python or Perl which are both written in C.




!!CONTEXT:../demo/win32/dsearch.exw
%%output = win32_dsearch

=== win32/dsearch.exw

search for a .DLL that contains a given routine
==== Usage
{{{
eui dsearch [routine]
}}}

If you don't supply a string on the command line you will be prompted
for it.




!!CONTEXT:../demo/win32/taskwire.exw
%%output = win32_taskwire

=== win32/taskwire.exw

3-D Wire Frame Picture. Windows Multitasking Version

Run in a window or in full screen.

In a window, just close the window to stop it.

When running in Full Screen, press any key to stop.




!!CONTEXT:../demo/win32/window.exw
%%output = win32_window

=== win32/window.exw

A Standard Windows Window coded at the primitive API level
Most Euphoria programmers should simply use Win32Lib, wxWidgets, EuGTK or EuIUP!




!!CONTEXT:../demo/win32/winwire.exw
%%output = win32_winwire

=== win32/winwire.exw

3-D Wire Frame Picture, Windows Version

Run in a window or in full screen.

In a window, just close the window to stop it.



@[:BLACK|]
==== BLACK
<eucode>
include winwire.exw
global constant BLACK
</eucode>





@[:BLUE|]
==== BLUE
<eucode>
include winwire.exw
global constant BLUE
</eucode>





@[:GREEN|]
==== GREEN
<eucode>
include winwire.exw
global constant GREEN
</eucode>





@[:CYAN|]
==== CYAN
<eucode>
include winwire.exw
global constant CYAN
</eucode>





@[:RED|]
==== RED
<eucode>
include winwire.exw
global constant RED
</eucode>





@[:MAGENTA|]
==== MAGENTA
<eucode>
include winwire.exw
global constant MAGENTA
</eucode>





@[:BROWN|]
==== BROWN
<eucode>
include winwire.exw
global constant BROWN
</eucode>





@[:WHITE|]
==== WHITE
<eucode>
include winwire.exw
global constant WHITE
</eucode>





@[:GRAY|]
==== GRAY
<eucode>
include winwire.exw
global constant GRAY
</eucode>





@[:BRIGHT_BLUE|]
==== BRIGHT_BLUE
<eucode>
include winwire.exw
global constant BRIGHT_BLUE
</eucode>





@[:BRIGHT_GREEN|]
==== BRIGHT_GREEN
<eucode>
include winwire.exw
global constant BRIGHT_GREEN
</eucode>





@[:BRIGHT_CYAN|]
==== BRIGHT_CYAN
<eucode>
include winwire.exw
global constant BRIGHT_CYAN
</eucode>





@[:BRIGHT_RED|]
==== BRIGHT_RED
<eucode>
include winwire.exw
global constant BRIGHT_RED
</eucode>





@[:BRIGHT_MAGENTA|]
==== BRIGHT_MAGENTA
<eucode>
include winwire.exw
global constant BRIGHT_MAGENTA
</eucode>





@[:YELLOW|]
==== YELLOW
<eucode>
include winwire.exw
global constant YELLOW
</eucode>





@[:BRIGHT_WHITE|]
==== BRIGHT_WHITE
<eucode>
include winwire.exw
global constant BRIGHT_WHITE
</eucode>





@[:VC_COLOR|]
==== VC_COLOR
<eucode>
include winwire.exw
global constant VC_COLOR
</eucode>





@[:VC_MODE|]
==== VC_MODE
<eucode>
include winwire.exw
global constant VC_MODE
</eucode>





@[:VC_LINES|]
==== VC_LINES
<eucode>
include winwire.exw
global constant VC_LINES
</eucode>





@[:VC_COLUMNS|]
==== VC_COLUMNS
<eucode>
include winwire.exw
global constant VC_COLUMNS
</eucode>





@[:VC_XPIXELS|]
==== VC_XPIXELS
<eucode>
include winwire.exw
global constant VC_XPIXELS
</eucode>





@[:VC_YPIXELS|]
==== VC_YPIXELS
<eucode>
include winwire.exw
global constant VC_YPIXELS
</eucode>





@[:VC_NCOLORS|]
==== VC_NCOLORS
<eucode>
include winwire.exw
global constant VC_NCOLORS
</eucode>





@[:VC_PAGES|]
==== VC_PAGES
<eucode>
include winwire.exw
global constant VC_PAGES
</eucode>






!!CONTEXT:../demo/unix/callc.ex
%%output = unix_callc

=== unix/callc.ex

Calls to C routines in standard shared libraries




!!CONTEXT:../demo/unix/mylib.ex
%%output = unix_mylib

=== unix/mylib.ex

Call a C routine in a shared library that you created.
Also read and write the value of a C variable.




!!CONTEXT:../demo/unix/qsort.ex
%%output = unix_qsort

=== unix/qsort.ex

Calling a Euphoria routine from a C routine under Linux

In this demo, the C qsort() library routine calls the
Euphoria qcompare() routine to compare any two items.



!!CONTEXT:../demo/net/chat_client.ex
%%output = net_chat_client

=== net/chat_client.ex

socket example that connects to the multi-user chat_server.ex application.




!!CONTEXT:../demo/net/chat_server.ex
%%output = net_chat_server

=== net/chat_server.ex

socket example that shows off using non-blocking sockets and a multi-user server
w/no threads needed.



!!CONTEXT:../demo/net/google_tts.ex
%%output = net_google_tts

=== net/google_tts.ex

Use the Google TTS service to create an MP3 file
of the text given on the command line

==== Usage
{{{
eui google_tts.ex Hello World
}}}

Then open in your MP3 player the resulting ##google_tts.mp3## file.




!!CONTEXT:../demo/net/httpd.ex
%%output = net_httpd

=== net/httpd.ex

Simple web server written in Euphoria

Try accessing http://localhost:8080/httpd.ex or add a few
HTML and Image files to the current directory and access
those.

You can change what IP and Port are bound to for the server
===== by specifying it on the command line:

{{{
eui httpd.ex 0.0.0.0:9090
}}}

==== Notes

This is not designed to be used in production, nor is
it designed to ever be completed. It is a simple example of
the socket routines that are part of the standard library.




!!CONTEXT:../demo/net/pastey.ex
%%output = net_pastey

=== net/pastey.ex

This demo sends a euphoria source code file to
http://euphoria.pastey.net for discussion on IRC
or other Internet means.

Program originally written by Kathy Smith (Kat) modified
for inclusion of a demo program by Jeremy Cowgar.




!!CONTEXT:../demo/net/sock_client.ex
%%output = net_sock_client

=== net/sock_client.ex

Simple example of how to connect to a socket. Be sure to launch ##sock_server.ex##
first.




!!CONTEXT:../demo/net/sock_server.ex
%%output = net_sock_server

=== net/sock_server.ex

Very simple socket server. Launch and then execute ##sock_client.ex## to see it in
action.




!!CONTEXT:../demo/net/udp_client.ex
%%output = net_udp_client

=== net/udp_client.ex

Simple UDP client. Be sure to launch ##udp_server.ex## first!




!!CONTEXT:../demo/net/udp_server.ex
%%output = net_udp_server

=== net/udp_server.ex

simple UDP server. Use ##udp_client.ex## to see it work.




!!CONTEXT:../demo/net/wget.ex
%%output = net_wget

=== net/wget.ex

WGet clone, a URL downloaded.

==== Usage

{{{
eui wget http://openeuphoria.org
}}}




!!CONTEXT:../docs/debug.txt
%%output = debug

== Debugging and Profiling

<<LEVELTOC level=2 depth=4>>

=== Debugging

Extensive run-time checking provided by the Euphoria interpreter catches many
bugs that in other languages might take hours of your time to track down. When
the interpreter catches an error, you will always get a brief report on your
screen, and a detailed report in a file called ##ex.err##. These reports include
a full English description of what happened, along with a call-stack traceback.
The file ##ex.err## will also have a dump of all variable values, and
optionally a list of the most recently executed statements. For extremely large
sequences, only a partial dump is shown. If the name ##ex.err## is not 
convenient, or if a nondefault path is required, you can choose another file 
name, anywhere on your system, by calling [[:crash_file]].

In addition, you are able to create [[:udt "user-defined types"]] that precisely
determine the set of legal values for each of your variables. An error report 
will occur the moment that one of your variables is assigned an illegal value.

Sometimes a program will misbehave without failing any run-time checks. In any
programming language it may be a good idea to simply study the source code and
rethink the algorithm that you have coded. It may also be useful to insert
print statements at strategic locations in order to monitor the internal logic
of the program. This approach is particularly convenient in an interpreted
language like Euphoria since you can simply edit the source and rerun the
program without waiting for a re-compile/re-link.
@[trace|]

==== Trace Directives: with, without 

The interpreter provides you with additional powerful tools for debugging.
Using ##trace(1)## you can **//trace//** the execution of your program on one
screen while you witness the output of your program on another.  ##trace(2)## is
the same as ##trace(1)## but the trace screen will be in monochrome. Finally, 
using ##trace(3)##, you can log all executed statements to a file called 
##ctrace.out##.

The **with/without trace** special statements select the parts
of your program that are available for tracing. Often you will simply insert a
with trace statement at the very beginning of your source code to make it all
traceable. Sometimes it is better to place the first with trace after all of
your [[:udt "user-defined types"]], so you don't trace into
these routines after each assignment to a variable.  At other times, you may
know exactly which routine or routines you are interested in tracing, and you
will want to select only these ones. Of course, once you are in the trace
window, you can  skip viewing the execution of any routine by pressing
down-arrow on the keyboard rather than Enter. However, once inside a routine, 
you must step through till it returns, even if stepping in was an mistake.

Only traceable lines can appear in ##ctrace.out## or in ##ex.err## as "Traced
lines leading up to the failure", should a run-time error occur.  If you want
this information and didn't get it, you should insert a with trace and then
rerun your program.  Execution will be slower when lines compiled with trace
are executed, especially when ##trace(3)## is used.

After you have predetermined the lines that are traceable, your program must
then dynamically cause the trace facility to be activated by executing a 
[[:trace]] statement.  You could simply say:

<eucode>
with trace
trace(1)
</eucode>

However, you cannot dynamically set or free breakpoints while tracing. You must 
abort program, edit, change setting, save, and run again.

At the top of your program, so you can start tracing from the beginning of
execution. More commonly, you will want to trigger tracing when a certain
routine is entered, or when some condition arises. e.g.

<eucode>
if x < 0 then
    trace(1)
end if
</eucode>

You can turn off tracing by executing a ##trace(0)##
statement. You can also turn it off interactively by typing 'q' to quit
tracing. Remember that with trace must appear **//outside//** of any routine,
whereas ##trace## can appear **//inside//** a routine **//or outside//**.

You might want to turn on tracing from within a [[:type -> types]]. Suppose you 
run your program and it fails, with the ##ex.err## file showing that one of your
variables has been set to a
strange, although not illegal value, and you wonder how it could have happened.
Simply create a type for that variable that
executes ##trace(1)## if the value being assigned to the variable is the strange
one that you are interested in.  e.g.

<eucode>
type positive_int(integer x)
    if x = 99 then
        trace(1) -- how can this be???
        return 1 -- keep going
    else
        return x > 0
    end if
end type
</eucode>

When ##positive_int## returns, you will see the exact statement that caused 
your variable to be set to the strange value, and you will be able to check the
values of other variables.  You will also be able to check the output screen to
see what has happened up to this precise moment. If you define ##positive_int##
so it returns zero for the strange value (99) instead of one, you can force a
diagnostic dump into ##ex.err##.

Remember that the argument to ##trace## does not need to be a constant. It 
only needs to be 0, 1, 2 or 3, but these values may be the result from any 
expression passed to ##trace##.
Other values will cause ##trace## to fail.


=== Trace Screen

When a ##trace(1)## or ##trace(2)## statement is
executed by the interpreter, your main output screen is saved and a **trace
screen** appears.  It shows a view of your program with the statement that will
be executed next highlighted, and several statements before and after showing
as well. You cannot scroll the window further up or down though. Several lines 
at the bottom of the screen are reserved for displaying variable names and 
values. The top line shows the commands that you can enter at this point:

|= Command |= Action |
| | |
| F1 | display main output screen \\ take a look at your program's output so far |
| F2 | redisplay trace screen. Press this key while viewing the main output screen \\ to return to the trace display. |
| Enter | execute the currently-highlighted statement only |
| down-arrow | continue execution and break when any statement coming after \\this one in the source listing is about to be executed. \\This lets you skip over subroutine calls. It also lets you stop on the first statement following the end of a loop\\ without having to witness all iterations of the loop. |
| ? | display the value of a variable. After hitting **?** you will be prompted for the name of the variable.\\ Many variables are displayed for you automatically as they are assigned a value. If a variable is not currently being displayed, or is only partially displayed, you can ask for it.\\ Large sequences are limited to one line on the trace screen, but when you ask for the value of\\ a variable that contains a large sequence, the screen will clear, and you can scroll through\\ a pretty-printed display of the sequence. You will then be returned to the trace screen, \\where only one line of the variable is displayed. Variables that are not defined at this point\\ in the program cannot be shown. Variables that have not yet been initialized will have \\"< NO VALUE >" beside their name. Only variables, not general expressions, can be displayed.\\ As you step through execution of the program, the system will update any values showing\\ on the screen. Occasionally it will remove variables that are no longer in scope, or\\ that haven't been updated in a long time compared with newer, recently-updated variables. |
| q | quit tracing and resume normal execution. Tracing will start again when the next trace(1) is executed. |
| Q | quit tracing and let the program run freely to its normal completion. ##trace## statements will be ignored. |
| !| this will abort execution of your program. A traceback and dump of variable values will go to ##ex.err##. |

As you trace your program, variable names and values appear automatically in
the bottom portion of the screen. Whenever a variable is assigned to, you will
see its name and new value appear at the bottom. This value is always kept
up-to-date. Private variables are automatically cleared from the screen when
their routine returns. When the variable display area is full, least-recently
referenced variables will be discarded to make room for new variables. The
value of a long sequence will be cut off after 80 characters.

For your convenience, numbers that are in the range of printable ASCII
characters (32-127) are displayed along with the ASCII character itself. The
ASCII character will be in a different color (or in quotes in a mono display).
This is done for all variables, since Euphoria does not know in general whether
you are thinking of a number as an ASCII character or not. You will also see
ASCII characters (in quotes) in ##ex.err##. This can make for a rather "busy"
display, but the ASCII information is often very useful.

The trace screen adopts the same graphics mode as the main output screen.  This
makes flipping between them quicker and easier.

When a traced program requests keyboard input, the main output screen will
appear, to let you type your input as you normally would. This works fine for a
[[:gets]] (read one line) input.  When a 
[[:get_key]] (quickly sample the keyboard) is
called you will be given 8 seconds to type a character, otherwise it is 
assumed that there is no input for this call to ##get_key##. This allows you 
to test the case of input and also the case of no input for ##get_key##.

=== Trace File

When your program calls ##trace(3)##, tracing to a file is activated.  The file,
##ctrace.out## will be created in the current directory.  It contains the last
500 Euphoria statements that your program executed.  It is set up as a circular
buffer that holds a maximum of 500 statements. Whenever the end of
##ctrace.out## is reached, the next statement is written back at the beginning.
The very last statement executed is always followed by "=== THE END ===".
Because it's circular, the last statement executed could appear anywhere in
##ctrace.out##.  The statement coming after "=== THE END ===" is the
500th-last.

This form of tracing is supported by both the interpreter and the the Euphoria
to C translator.  It is particularly useful when a machine-level error occurs
that prevents Euphoria from writing out an ##ex.err## diagnostic file. By
looking at the last statement executed, you may be able to guess why the
program crashed. Perhaps the last statement was a ##poke## into an 
illegal area
of memory. Perhaps it was a call to a C routine. In some cases it might be a
bug in the interpreter or the translator.

The source code for a statement is written to ##ctrace.out##, and flushed, just
//before// the statement is performed, so the crash will likely have happened
//during// execution of the final statement that you see in ##ctrace.out##.

=== Profiling

If you specify a ##with profile## or ##with profile_time## (//Windows// only) 
directive,
then a special listing of your program, called a
**profile**, will be produced by the interpreter when your program finishes
execution.  This listing is written to the file **##ex.pro##** in the current
directory.

There are two types of profiling available: execution-count profiling, and
time profiling.  You get **execution-count** profiling when you specify with
profile. You get **time profiling** when you specify with ##profile_time##.  You can
not mix the two types of profiling in a single run of your program.  You need to
make two separate runs.

We ran the ##sieve8k.ex## benchmark program in ##demo\bench## under both types
of profiling. The results are in ##sieve8k.pro## (execution-count profiling)
and ##sieve8k.pro2## (time profiling).

@[profile|] Execution-count profiling shows precisely how many times
each statement in your program was executed. If the statement was never
executed the count field will be blank.

Time profiling shows an estimate of the total time spent executing
each statement. This estimate is expressed as a percentage of the time spent
profiling your program. If a statement was never sampled, the percentage field
will be blank. If you see 0.00 it means the statement was sampled, but not
enough to get a score of 0.01.

Only statements compiled ##with profile## or ##with profile_time## are shown in 
the listing. Normally you will specify either ##with profile## or 
##with profile_time## at
the top of your main ##.ex##* file, so you can get a complete listing.

Profiling can help you in many ways:

* It lets you see which statements are heavily executed, as a clue to speeding 
up your program
* It lets you verify that your program is actually working the way you intended
* It can provide you with statistics about the input data
* It lets you see which sections of code were never tested ~-- don't let your 
users be the first!

Sometimes you will want to focus on a particular action performed by your
program. For example, in the **Language War** game, we found that the game in
general was fast enough, but when a planet exploded, shooting 2500 pixels off
in all directions, the game slowed down. We wanted to speed up the explosion
routine. We did not care about the rest of the code. The solution was to call 
##profile(0)##
at the beginning of Language War,
just after ##with profile_time##, to turn off profiling, and then to call
##profile(1)## at the beginning of the explosion routine and ##profile(0)## at 
the end
of the routine. In this way we could run the game, creating numerous
explosions, and logging a lot of samples, just for the explosion effect. If
samples were charged against other lower-level routines, we knew that those
samples occurred during an explosion. If we had simply profiled the whole
program, the picture would not have been clear, as the lower-level routines
would also have been used for moving ships, drawing phasors etc. ##profile## 
can help in the same way when you do execution-count profiling.

=== Time Profiling

With each click of the system clock, an interrupt is generated. When you
specify ##with profile_time## Euphoria will sample your program to see which
statement is being executed at the exact moment that each interrupt occurs.

Each sample requires four bytes of memory and buffer space is normally reserved
for 25000 samples. If you need more than 25000 samples you can request it:

<eucode>
with profile_time 100000
</eucode>

will reserve space for 100000 samples (for example). If the buffer overflows
you'll see a warning at the top of **ex.pro**.  At 100 samples per second your
program can run for 250 seconds before using up the default 25000 samples.
It's not feasible for Euphoria to dynamically enlarge the sample buffer during
the handling of an interrupt. That's why you might have to specify it in your
program. After completing each top-level executable statement, Euphoria will
process the samples accumulated so far, and free up the buffer for more
samples. In this way the profile can be based on more samples than you have
actually reserved space for.

The percentages shown in the left margin of ##ex.pro##, are calculated by
dividing the number of times that a particular statement was sampled, by the
total number of samples taken. e.g. if a statement were sampled 50 times out of
a total of 500 samples, then a value of 10.0 (10 per cent) would appear in the
margin beside that statement. When profiling is disabled with ##profile(0)##,
interrupts are ignored, no samples are taken and the total number of samples
does not increase.

By taking more samples you can get more accurate results. However, one
situation to watch out for is the case where a program synchronizes itself to
the clock interrupt, by waiting for ##[[:time]]## to
advance. The statements executed just after the point where the clock advances
might //never// be sampled, which could give you a very distorted picture. e.g.

<eucode>
while time() < LIMIT do
end while
x += 1 -- This statement will never be sampled
</eucode>

Sometimes you will see a significant percentage beside a ##return## statement.
This is usually due to time spent deallocating storage for temporary and
private variables used within the routine. Significant storage deallocation
time can also occur when you assign a new value to a large sequence.

If disk swapping starts to happen, you may see large times attributed to
statements that need to access the swap file, such as statements that access
elements of a large swapped-out sequence.


!!CONTEXT:../docs/bind.txt
%%output = bind

== Shrouding and Binding
:<<LEVELTOC level=2 depth=4>>

=== The eushroud Command

==== Synopsis

{{{
eushroud [-full_debug] [-list] [-quiet] [-out shrouded_file] filename.ex[w/u]
}}}

The **##eushroud##** command converts a Euphoria program, typically consisting of a 
main file plus many include files, into a single, compact file. A single file is
easier to distribute, and it allows you to distribute your program to others without 
releasing your source code.

A shrouded file does not contain any Euphoria source code statements. Rather,
it contains a low-level **Intermediate Language** (IL) that is executed by the
back-end of the interpreter. A shrouded file does not require any parsing. It
starts running immediately, and with large programs you will see a quicker
start-up time. Shrouded files must be run using the interpreter back-end:

##eubw.exe## (//Windows//) or ##eub.exe##
(//Unix//).  

This backend is freely available, and you can give it to
any of your users who need it. It is stored in ##.../euphoria/bin## in the Euphoria
interpreter package. You can run your ##.il## file with:

On //Windows// use:

{{{
eub myprog.il
eubw myprog.il
}}}

On //Unix// use:

{{{
eub myprog.il
}}}

Although it does not contain any source statements, a ##.il## file will generate a 
useful ##ex.err## dump in case of a run-time error.

The shrouder will remove any routines and variables that your program doesn't 
use. This will give you a smaller ##.il## file. There are often a great number of 
unused routines and unused variables. For example, your program might include 
several third party include files, plus some standard files from 
##.../euphoria/include##, but only use a few items from each file. The unused items 
will be deleted.

==== Options

* **-full_debug**: Make a somewhat larger ##.il## file that contains enough debug 
information to provide a full ##ex.err## dump when a crash occurs. Normally, 
variable names and line-number information is stripped out of the ##.il## file, so 
the ##ex.err## will simply have "no-name" where each variable name should be, 
and line numbers will only be accurate to the start of a routine or the start of
a file. Only the private variable values are shown, not the global or local 
values. In addition to saving space, some people might prefer that the shrouded
file, and any ##ex.err## file, not expose as much information.
* **-list**: Produce a listing in **deleted.txt** of the routines and constants 
that were deleted.
* **-quiet**: Suppress normal messages and statistics. Only report errors.
* **-out shrouded_file**: Write the output to ##shrouded_file##.

The Euphoria interpreter will not perform tracing on a shrouded file. You must
trace your original source.

On //Unix//, the shrouder will make your shrouded file executable,
and will add a ##!## line at the top, that will run ##eub.exe.## You
can override this ##!## line by specifying your own ##!##
line at the top of your main Euphoria file.

Always keep a copy of your original source. There is no way to recover it from a 
shrouded file.

=== The Bind Command

==== Synopsis:

{{{
eubind [-c config-file] [-con] [-copyright] [-eub path-to-backend] 
       [-full_debug] [-i dir] [-icon file] [-list] [-quiet] 
       [-out executable_file] [-shroud_only [filename.ex]
}}}


##eubind## does the same thing as ##eushroud##, and
includes the same options. It then combines your shrouded ##.il## file with the
interpreter backend (##eub.exe##, ##eubw.exe## or ##eub##) to make
a **single, stand-alone executable** file that you can conveniently use and
distribute. Your users need not have Euphoria installed.  Each time your
executable file is run, a quick integrity check is performed to detect any
tampering or corruption. Your program will start up very quickly since no
parsing is needed.

The Euphoria interpreter will not perform tracing on a bound file since the
source statements are not there.

==== Options:

* **-c config-file**: A Euphoria config file to use when binding.
* **-con**: **(//Windows// only)**: This option will create a //Windows// 
console program instead of a //Windows// GUI program. Console programs can 
access standard input and output, and they work within the current console 
window, rather than popping up a new one.
* **-eub path-to-backend** Allows specification of the backend runner to use
instead of the default, installed version.
* **-full_debug**: Same as ##eushroud## above. If Euphoria detects an error, your 
executable will generate either a partial, or a full, ##ex.err## dump, according
to this option.
* **-i dir**: A directory to add to the paths to use for searching for included 
files.
* **-icon filename[.ico]**: **(//Windows// only)** When you bind a program, you 
can patch in your own customized icon, overwriting the one in ##euiw.exe##. 
##eui.exe## contains a 32x32 icon using 256 colors. It resembles an **E)** 
shape. //Windows// will display this shape beside ##euiw.exe##, and beside your 
bound program, in file listings. You can also load this icon as a resource, 
using the name "euiw" (see ##...\euphoria\demo\win32\window.exw## for an example). 
When you bind your program, you can substitute your own 32x32 256-color icon 
file of size 2238 bytes or less. Other dimensions may also work as long as the 
file is 2238 bytes or less. The file must contain a single icon image 
(//Windows// will create a smaller or larger image as necessary). The default 
##euphoria.ico##, is included in the ##...\euphoria\bin## directory.
* **-list**: Same as ##shroud## above.
* **-quiet**: Same as ##shroud## above.
* **-out executable_file**: This option lets you choose the name of the 
executable file created by the binder. Without this option, ##eubind## will 
choose a name based on the name of the main Euphoria source file.

A one-line Euphoria program will result in an executable file as large as the
back-end you are binding with, but the size increases very slowly as you add to
your program. **When bound, the entire Euphoria editor,
##ed.ex##, adds only 27K to the size of the back-end.** 

The first two items returned by [[:command_line]] will be
slightly different when your program is bound. See the procedure description for
the details.

A **bound executable** file //can// handle standard input and output 
redirection as with this syntax:

{{{
myprog.exe < file.in > file.out
}}}

If you were to write a small ##.bat## file, say ##myprog.bat##, that contained 
the line "##eui myprog.ex##" you would //not// be able to redirect input and 
output. The following will not work:

{{{
myprog.bat < file.in > file.out
}}}

You //could// however use redirection on individual lines //within// the 
##.bat## file.

!!CONTEXT:../docs/e2c.txt
%%output = e2c

== Euphoria To C Translator
:<<LEVELTOC level=2 depth=4>>

=== Introduction

The **Euphoria to C Translator** (translator) will translate any Euphoria 
program into equivalent C source code.

There are versions of the translator for //Windows// and //Unix// 
operating Systems. After translating a Euphoria program to C, you
can compile and link using one of the supported C compilers. This will give
you an executable file that will typically run much faster than if you used
the Euphoria interpreter.

The translator can translate and then compile //itself// into an executable file
for each platform. The translator is also used in translating/compiling the
front-end portion of the interpreter. The source code for the translator is in
##euphoria\source##. It is written 100% in Euphoria.

=== Supported Compilers

The **Translator** currently works with GNU C on //Unix// OSes,
GNU C on //Windows// from  [[http://www.mingw.org|MinGW]]  
or [[http://en.wikipedia.org/wiki/Cygwin|Cygwin]] using the ##-gcc## option
and with [[http://www.openwatcom.org|Watcom C]] (the default) on //Windows//.
These are all **free** compilers.

GNU C will exist already on your //Unix// system. The others can be
downloaded from their respective Web sites.

==== Notes:

* Warnings are turned off when compiling directly or with makefiles. If you turn them 
  on, you may see some harmless messages about variables declared but not used, labels defined 
  but not used, function prototypes not declared etc.
* For the ##-gcc## option on //Windows// you will need a ##eu.a## compiled 
  with //MinGW// or //Cygwin//. The official distribution may only contain 
  ##eu.lib## compiled with //Watcom//. Also, the ##-stack## and ##-con## options 
  may not produce the expected result with //GCC C//.
* Currently, only 32-bit compilers are supported on 64-bit platforms.

=== Run the Translator

Running the **Translator** is similar to running the **Interpreter**:

{{{
euc -con allsorts.ex
}}}

Note: that on //Unix// the demos might be installed to ##/usr/share/euphoria/demo##

Instead of running the ##allsorts.ex## program, the **Translator** will
create several C source files in a temporary build directory, compile them
and result in a native executable file. For this to work, you have to have a 
supporting compiler installed (mentioned above). The optional parameter used in this
example, ##-con##, will be explained in full detail below.

When the C compiling and linking is finished, you will have a file called ##allsorts.exe##
or simply ##allsorts## on *nix systems. The C source files will have been removed to avoid 
clutter.

When you run the ##allsorts## executable, it should run the same as if you had typed:

{{{
eui allsorts
}}}

to run it with the **Interpreter**, except that it should run faster, showing
reduced times for the various sorting algorithms in 
##euphoria\demo\allsorts.ex##.

After creating your executable file, the translator removes all the C files that were
created. If you want to look at these files, you'll need to run the translator again,
using either the ##-keep## or ##-makefile## options.

=== Command-Line Options

==== -arch - Set architecture

The translator generally produces cross platform code.  However, the euphoria
source code may have different code for different architectures.  The default
is to use the architecture of the translator binary that is being used.  To
target a different architecture, you can use one of three supported architectures:

* X86
* X86_64
* ARM

==== -build-dir dir

Use the specified directory to write translated C files and compiled objects. The final
executable is still output by default to the current directory (or however the ##-o## flag
specifies). When not specified, euphoria will create a temporary, randomly named build
directory.

The specified directory cannot contain any wildcards ('*', '?') or be an existing file.

{{{
$ euc -build-dir temp_dir myapp.ex
}}}

==== -cc-prefix - Compiler prefix

Some compilers, especially MinGW (the Windows version of gcc) may prefix their
normal names with platform prefixes.  The -cc-prefix switch allows the developer
to specify this special prefix.  This can also be useful for having a system
with both the 32bit and 64bit versions installed.  Cross compilers generally require this.

For example, on Windows, to build with MinGW installed as i6856-w64-mingw32:

{{{
euc -gcc -cc-prefix i686-w64-mingw32- pretend.exw
}}}

==== -cflags FLAGS - Compiler Flags

Specifies the flags to pass to the compiler.

==== -com DIR - Compiler directory

Tells the translator where to find include/euphoria.h, which is the header file required
when translating code.

==== -con - Console based program

To make a //Windows// console program instead of a //Windows// GUI program,
add ##-con## to the command line. e.g.

{{{
euc -con myprog.exw
}}}

When creating a Windows GUI program, if the ##-con## option is used, when running
your Windows program, you will have a blank console window appear and remain the duration
of your application. By default, a GUI program is assumed.

==== -debug - Debug mode

To compile your program with debugging information, usable with a debugger
compatible with your compiler, use the ##-debug## option:

{{{
euc -debug myapp.ex
}}}

==== -dll / -so - Shared Library

To make a shared dynamically loading library, just
add ##-dll## to the command line. e.g.

{{{
euc -dll mylib.ew
}}}

Note: On *nix systems, you can also use ##-so##. Both will produce a *nix
shared library.

Please see [[:Dynamic Link Libraries]]

==== -extra-cflags - Extra Compiler Flags

Supply extra compiler flags to suplement the flags used automatically by the translator or
supplied via the -cflags option.

==== -extra-lflags - Extra Linker Flags

Supply extra linker flags to suplement the flags used automatically by the translator or
supplied via the -lflags option.


==== -gcc, -wat

If you happen to have more than one C compiler for a given platform, you can
select the one you want to use with a command-line option:

{{{
-wat  -- Watcom compiler
-gcc  -- GCC compiler (MinGW on Windows)
}}}

For example, to compile with GCC (or MinGW on Windows):

{{{
euc -gcc pretend.exw
}}}

Note: //Watcom// is the default on //Windows// and -wat is assumed.

==== -keep

Normally, after building your ##.exe## file, the translator will delete
all C files and object files produced by the Translator. If you want it
to keep these files, add the ##-keep## option to the Translator command-line.
e.g.

{{{
euc -keep sanity.ex
}}}

==== -lflags FLAGS - Linker Flags

Specifies the flags to pass to the linker.

==== -lib - User defined library

It is sometimes useful to link your translated code to a Euphoria runtime
library other than the default supplied library. This ability is probably
mostly useful for testing and debugging the runtime library itself, or to give
additional debugging information when debugging translated Euphoria code. Note
that only the default library is supplied. Use the ##-lib {library}## option:

{{{
euc -lib decu.a myapp.ex
}}}


==== -lib-pic - User defined library for PIC mode

Some platforms and architectures (e.g., x86-64) require that shared libraries be built in
Position Independent Code mode, which requires that the euphoria run time
library also be built with PIC. This option is similar to the [[:-lib - User defined library]]
option, except that it specifies the library to use for PIC code:

{{{
euc -lib-pic euso.a myapp.ex
}}}

==== -makefile / -makefile-partial - Using makefiles

You can optionally have the translator create a makefile that you can use
to build your program instead of building directly.  Using a makefile like
this can be convenient if you want or need to alter the translated C code,
or change compiling or linking options before building your program.  To
do so:

{{{
$ euc -makefile myapp.ex
Translating code, pass: 1 2 3 4  generating

3.c files were created.
To build your project, type make -f myapp.mak
}}}

Then, as the message indicates, simply type:
{{{
$ make -f myapp.mak
}}}

On Windows, when using Watcom, the message will refer to wmake, the Watcom
version of make.  On BSD platforms, you may need to use ##gmake##, as the
generated makefiles are in GNU format, not BSD.

You can also get a partial makefile using the ##-makefile-partial## switch.
This generates a makefile that you can use to include into another makefile
for a larger project.  This is useful for including the file dependencies
for your code into the larger project.

==== -maxsize NUMBER

Specifies the maximum number of C statements to go into a single file before
the translated file is split into multiple C files.


==== -plat - Set platform

The translator has the capability of translating Euphoria code to C code for a platform
other than the host platform. This can be done with the ##-plat## option. It takes
one parameter, the platform code:
* FREEBSD
* LINUX
* OSX
* WINDOWS
* NETBSD
* OPENBSD

Use one of these options to translate code into C for the specified platform.
The default will always be the host platform of the translator that is executed,
so ##euc.exe## will default to //Windows//, and ##euc## will default to the platform
upon which it was built.

The resulting output can be compiled by the appropriate compiler on the
specified platform, or, possibly a cross platform compiler, if you have
one configured.

==== -rc-file - Resource File

On Windows, ##euc## can automatically compile and link in an application specific resource
file. This resource file can contain product and version information, an application icon
or any other valid resource data.

{{{
euc -rc-file myapp.rc myapp.ex
}}}

The resulting executable will contain all the resources from ##myapp.rc## compiled into 
the executable. Please see [[:Using Resource Files]].

==== -silent

Do not display status messages.

==== -stack - Stack size

To increase or decrease the total amount of stack space reserved for your
program, add ##-stack nnnn## to the command line. e.g.

{{{
euc -stack 100000 myprog.ex
}}}

The total stack space (in bytes) that you specify will be divided up among all
the tasks that you have running (assuming you have more than one). Each task
has it's own private stack space. If it exceeds its allotment, you'll get a
run-time error message identifying the task and giving the size of its stack
space. Most non-recursive tasks can run with call stacks as small as 2000
bytes, but to be safe, you should allow more than this. A deeply-recursive
task could use a great deal of space. It all depends on the maximum levels of
calls that a task might need. At run-time, as your program creates more
simultaneously-active tasks, the stack space allotted to each task will tend
to decrease.

=== Dynamic Link Libraries

Simply by adding ##-dll## (or ##-so##) to the command line, the **Translator** will build a 
shared dynamically loading library instead of an executable program.

You can translate and compile a set of useful Euphoria routines, and share
them with other people, without giving them your source. Furthermore, your
routines will likely run much faster when translated and compiled. Both
translated/compiled and interpreted programs will be able to use your library.

Only the global Euphoria procedures and functions, i.e. those declared with
the "##global##", "##public##" or "##export##" keyword, will be exported from
the shared dynamically loaded library.

Any Euphoria program, whether translated or compiled or interpreted, can link
with a Euphoria shared dynamically loading library using the same mechanism that
lets you link with a shared dynamically loading library written in C. The 
program first calls [[:open_dll]] to open the
file, then it calls [[:define_c_func]] or [[:define_c_proc]] for
any routines that it wants to call. It calls these routines using [[:c_func]]
and [[:c_proc]].

The routine names exported from a Euphoria shared dynamically loading library 
will vary depending on which C compiler you use.

GNU C on //Unix// exports the names exactly as they appear in the C
code produced by the **Translator**, e.g. a Euphoria routine

{{{
global procedure foo(integer x, integer y)
}}}

would be exported as "##_0foo##" or maybe "##_1foo##" etc. The underscore and 
digit are added to prevent naming conflicts. The digit refers to the Euphoria 
file where the identifier is defined. The main file is numbered as 0. The 
include files are numbered in the order they are encountered by the compiler. 
You should check the C source to be sure.

For Watcom, the **Translator** also creates an EXPORT command, added to 
##objfiles.lnk## for each exported identifier, so ##foo## would be exported as
"##foo##".

With Watcom, if you specify the ##-makefile## option, you can edit the 
##objfiles.lnk## file to rename the exported identifiers, or remove ones that you
do not want to export.  Then build with the generated makefile.

Having nice exported names is not critical, since the name need only appear
once in each Euphoria program that uses the shared dynamically loading library, 
i.e. in a single [[:define_c_func]] or [[:define_c_proc]] statement. The 
author of a shared dynamically loading library
should probably provide his users with a Euphoria include file containing the
necessary [[:define_c_func]] and [[:define_c_proc]] statements, and he might
even provide a set of Euphoria "wrapper" routines to call the routines in the
shared dynamically loading library.

When you call [[:open_dll]], any top-level Euphoria statements in the shared 
dynamically loading library will be executed automatically, just like a normal 
program. This gives the
library a chance to initialize its data structures prior to the first call to
a library routine. For many libraries no initialization is required.

To pass Euphoria data (atoms and sequences) as arguments, or to receive a
Euphoria object as a result, you will need to use the following constants in
##euphoria\include\dll.e##:

<eucode>
-- Euphoria types for shared dynamically loading library arguments 
-- and return values:

global constant
    E_INTEGER = #06000004,
    E_ATOM    = #07000004,
    E_SEQUENCE= #08000004,
    E_OBJECT  = #09000004
</eucode>

Use these in ##define_c_proc## and ##define_c_func## just as you currently
use ##C_INT##, ##C_UINT## etc. to call C shared dynamically loading libraries.

Currently, file numbers returned by [[:open]], and routine id's returned by
[[:routine_id]], can be passed and returned, but the library and the main
program each have their own separate ideas of what these numbers mean. Instead
of passing the file number of an open file, you could instead pass the file
name and let the shared dynamically loading library open it. Unfortunately there
is no simple solution for passing routine id's. This might be fixed in the 
future.

A Euphoria shared dynamically loading library currently may not execute any 
multitasking operations. The Translator will give you an error message about 
this.

Euphoria shared dynamically loading library can also be used by C programs as 
long as only 31-bit integer values are exchanged. If a 32-bit pointer or integer must be 
passed, and you have the source to the C program, you could pass the value in two
separate 16-bit integer arguments (upper 16 bits and lower 16 bits), and then
combine the values in the Euphoria routine into the desired 32-bit atom.

=== Using Resource Files

When creating an executable file to deliver to your users on Windows, its best to link
in a resource file that at minimum sets your application icon but better if it sets 
product and version information.

When the resource compiler is launched by ##euc##, a single macro is defined named 
##SRCDIR##. This can be used in your resource files to reference your application source
path for including other resource files, icon files, etc...

A simple resource file to attach an icon to your executable file is as simple as:

{{{
myapp ICON SRCDIR\myapp.ico
}}}

Remember that SRCDIR will be expanded to your application source path.

A more complex resource file containing an icon and product/version information may look 
like:

{{{
1 VERSIONINFO

FILEVERSION 4,0,0,9
PRODUCTVERSION 4,0,0,9

FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L

BEGIN
  BLOCK "StringFileInfo"
    BEGIN
      BLOCK "040904B0"
        BEGIN
          VALUE "Comments",         "http://myapplication.com\0"
          VALUE "CompanyName",      "John Doe Computing\0"
          VALUE "FileDescription",  "Cool App\0
          VALUE "FileVersion",      "4.0.0\0"
          VALUE "InternalName",     "coolapp.exe\0"
          VALUE "LegalCopyright",   "Copyright (c) 2022 by John Doe Computing\0"
          VALUE "LegalTrademarks1", "Trademark Pending\0"
          VALUE "LegalTrademarks2", "\0"
          VALUE "OriginalFilename", "coolapp.exe\0"
          VALUE "ProductName",      "Cool Application\0"
          VALUE "ProductVersion",   "4.0.0\0"
        END
    END
  BLOCK "VarFileInfo"
    BEGIN
      VALUE "Translation", 0x409, 1200
    END
END

coolapp ICON SRCDIR\coolapp.ico
}}}

One other item you may wish to include is a manifest file which lets Windows know that
controls should use the new theming engines available in >= Windows XP. Simply append:

{{{
1 24 "coolapp.manifest"
}}}

to the end of your resource file. The ##coolapp.manifest## file is:

{{{
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="0.64.1.0"
    processorArchitecture="x86"
    name="euphoria"
    type="win32"
/>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>
}}}

Version, Product and Manfiest information may change with new releases of Microsoft 
Windows. You should consult MSDN for up to date information about using resource files
with your application. [[http://msdn.microsoft.com/en-us/library/aa380599(VS.85).aspx|MSDN About Resource Files]].

=== Executable Size and Compression

The translator does not compress your executable file.
If you want to do this we suggest you try the free
[[UPX -> http://upx.sourceforge.net]] compressor.

Large Win32Lib-based .exe's produced by the Translator can be compressed by
UPX to about 15% of their original size, and you won't notice any difference
in start-up time.

The **Translator** deletes routines that are not used, including those from
the standard Euphoria include files. After deleting unused routines, it checks
again for more routines that have now become unused, and so on. This can make
a big difference, especially with Win32Lib-based programs where a large file
is included, but many of the included routines are not used in a given
program.

Nevertheless, your compiled executable file will likely be larger than the
same Euphoria program bound with the interpreter **back-end**. This is partly
due to the **back-end** being a compressed executable. Also, Euphoria
statements are extremely compact when stored in a bound file. They need more
space after being translated to C, and compiled into machine code. Future
versions of the **Translator** will produce faster and smaller executables.

=== Interpreter versus Translator

All Euphoria programs can be translated to C, and with just a few exceptions
noted below, will run the same as with the **Interpreter** (but hopefully
faster).

The **Interpreter** and **Translator** share the same parser, so you will get
the same syntax errors, variable not declared errors etc. with either one.


The **Interpreter** automatically expands the call stack (until memory is
exhausted), so you can have a huge number of levels of nested calls. Most C
compilers, on most systems, have a pre-set limit on the size of the stack.
Consult your compiler or linker manual if you want to increase the limit, for
example if you have a recursive routine that might need thousands of levels of
recursion. Modify the link command in your makefile, or use the ##-lflags##
option when calling the translator. For Watcom C, use ##OPTION
STACK=nnnn##, where nnnn is the number of bytes of stack space.

==== Note:

The **Translator** assumes that your program has no run-time errors in it that
would be caught by the **Interpreter**. The **Translator** does not check for:
subscript out of bounds, variable not initialized, assigning the wrong type of
data to a variable, etc.

You should **debug** your program with the **Interpreter**. The Translator
checks for certain run-time errors, but in the interest of speed, most are not
checked. When translated C code crashes you'll typically get a very cryptic
machine exception. In most cases, the first thing you should do is run your
program with the **Interpreter**, using the same inputs, and preferably with
##type_check## turned on. If the error only shows up in translated code, you
can use ##with trace## and ##trace(3)## to get a ##ctrace.out## file showing a
circular buffer of the last 500 Euphoria statements executed. If a
translator-detected error message is displayed (and stored in ##ex.err##), you
will also see the offending line of Euphoria source whenever ##with trace## is
in effect. ##with trace## will slow your program down, and the slowdown can be
extreme when ##trace(3)## is also in effect.

=== Legal Restrictions

As far as RDS is concerned, any executable programs or shared dynamically 
loading libraries that you create
with this **Translator** without modifying an RDS translator library file, may
be distributed royalty-free. You are free to incorporate any Euphoria files
provided by RDS into your application.

In general, if you wish to use Euphoria code written by 3rd parties, please
honor any restrictions that apply. If in doubt, you should ask for permission.

On //Linux//, //FreeBSD//, the GNU Library licence
will normally not affect programs created with this **Translator**. Simply
compiling with GNU C does not give the Free Software Foundation any
jurisdiction over your program. If you statically link their libraries you
will be subject to their Library licence, but the standard compile/link
procedure does not statically link any FSF libraries, so there
should be no problem.


=== Disclaimer:

This is what we believe to be the case. We are not lawyers. If it's important
to you, you should read **all** licences and the legal comments in them,
to form your own judgment. You may need to get professional legal opinion as 
well.

=== Frequently Asked Questions

==== How much of a speed-up should I expect?

It all depends on what your program spends its time doing. Programs that use
mainly integer calculations, don't call run-time routines very often, and
don't do much I/O will see the greatest improvement, currently up to about 5x
faster. Other programs may see only a few percent improvement.

The various C compilers are not equal in optimization ability.

==== What if I want to change the compile or link options in my generated makefile?

Feel free to do so, that's one reason for producing a makefile.

==== How can I make my program run even faster?

It's important to declare variables as integer where possible. In general, it
helps if you choose the most restrictive type possible when declaring a
variable.

Typical user-defined types will not slow you down. Since your program is
supposed to be free of type_check errors, types are ignored by the Translator,
unless you call them directly with normal function calls. The one exception is
when a user-defined type routine has side-effects (i.e. it sets a global
variable, performs pokes into memory, I/O etc.). In that case, if 
##with type_check## is in effect, the Translator will issue code to call the 
type routine and report any type_check failure that results.

On //Windows// we have left out the ##/ol## loop optimization for
Watcom's ##wcc386##. We found in a couple of rare cases that this option led
to incorrect machine code being emitted by the Watcom C compiler. If you add
it back in to your own makefile you might get a slight
improvement in speed, with a slight risk of buggy code.

On //Linux// or //FreeBSD// you could try the ##-O3## option of gcc instead of
##-O2##. It will "in-line" small routines, improving speed slightly, but
creating a larger executable. You could also try the
[[http://www.intel.com/cd/software/products/asmo-na/eng/compilers/clin/index.htm|Intel C~+~+ Compiler for Linux]].
It's compatible with GNU C, but some adjustments to your makefile might be required.

=== Common Problems

Many large programs have been successfully translated and compiled using each
of the supported C compilers, and the Translator is now quite stable.

==== Note:

On //Windows//, if you call a C routine that uses the cdecl calling convention
(instead of stdcall), you must specify a '##+##' character at the start of the
routine's name in [[:define_c_proc]] and [[:define_c_func]]. If you don't,
the call may not work when running the ##eui## Interpreter.

In some cases a huge Euphoria routine is translated to C, and it proves to be
too large for the C compiler to process. If you run into this problem, make
your Euphoria routine smaller and simpler. You can also try turning off C
optimization in your makefile for just the ##.c## file that fails. Breaking up
a single constant declaration of many variables into separate constant
declarations of a single variable each, may also help. Euphoria has no limits
on the size of a routine, or the size of a file, but most C compilers do. The
Translator will automatically produce multiple small .c files from a large
Euphoria file to avoid stressing the C compiler. It won't however, break a
large routine into smaller routines.

!!CONTEXT:../docs/dynamic.txt
%%output = dynamic

== Indirect Routine Calling
:<<LEVELTOC level=2 depth=4>>

Euphoria does not have function pointers. However, it enables you to call
any routine, including some internal to the interpreter, in an indirect way, 
using two different sets of identifiers.

=== Indirect Calling a Routine Coded in Euphoria

The following applies to any routine coded in Euphoria that your program uses, 
whether it is defined in the standard library, any third party library or your 
own code. It does not apply to routines implemented in the backend.

==== Getting a Routine Identifier

Whenever a routine is in scope, you can supply its name to the builtin 
##routine_id## function, which returns a small integer:

<eucode>
include get.e
constant value_id = routine_id("value")
</eucode>

Because ##value## is defined as ##public##, that routine is in scope. This 
ensures the call succeeds.
A failed call returns ##-1##, else a small nonnegative integer.

You can then feed this integer to ##call_func## or ##call_proc## as 
appropriate. It does not matter whether the routine is still in scope at the 
time you make that call. Once the id is gotten, it's valid.

==== Calling Euphoria Routines by Id

This is very similar to using [[:c_func]] or [[:c_proc]] to interface with 
external code.

===== Function Calling

This is done as follows:

<eucode>
result = call_func(id_of_the_routine,argument_sequence)
</eucode>

where
* ##id_of_the_routine## is an id you obtained from [[:routine_id]].
* ##argument_sequence## is the list of the parameters to pass, enclosed into 
curly braces

<eucode>
include get.e

constant value_id = routine_id("value")
result = call_func(value_id, {"Model 36A", 6, GET_LONG_ANSWER})
-- result is {GET_SUCCESS, 36, 4, 1}
</eucode>

This is equivalent to

<eucode>
result = value("Model 36A", 6, GET_LONG_ANSWER)
</eucode>

===== Procedure Calling

The same formalism applies, but using ##call_proc## instead. The differences 
are almost the same as between [[:c_func]] and [[:c_proc]].

<eucode>
include std/pretty.e

constant pretty_id = routine_id("pretty_print")

call_proc(pretty_id,{1, some_object, some_options})
</eucode>

This does the same as a straightforward
<eucode>
include std/pretty.e

pretty_print(1, some_object, some_options)
</eucode>

The difference with [[:c_proc]] is that you can call an external function 
using [[:c_proc]] and thus ignore its return value, like in C. Note that you 
cannot use ##call_proc## to invoke a Euphoria function, only C functions.

==== Why Call Indirectly?

Calling functions and procedures indirectly can seem more complicated and slower
than just calling the routine directly, but indirect calls can be used when
the name of the routine you want to call might not be known until run-time.


<eucode>
integer foo_id

function bar(integer x)
    return call_func(foo_id,{x})
end function

function foo_dev1(integer y)
	return y + 1
end function

function foo_dev2(integer y)
	return y - 1
end function

function foo_dev3(integer y)
	return y * y - 3
end function

function user_opt(object x)
	 ... 
end function

-- Initialize foo ID
switch user_opt("dev") do
	case 1 then
		foo_id = routine_id("foo_dev1")
	case 2 then
		foo_id = routine_id("foo_dev2")
	case else
		foo_id = routine_id("foo_dev3")
end switch
</eucode>

One last word: when calling a routine indirectly, its **full** parameter list 
must be passed, even if some of its parameters are defaulted. This limitation 
may be overcome in future versions.

=== Calling Euphoria Internals

A number of Euphoria routines are defined in different ways depending on the 
platform they will run on. It would be cumbersome, and at times downright 
impossible, to put such code in include files or to make the routine fully 
builtin.

A solution to this is provided by ##machine_func## and ##machine_proc##. 
User code normally never needs to use these. Various examples are to be 
found in the standard library.

These primitives are called like this:
<eucode>
machine_proc(id, argument)
result = machine_func(id, argument)
</eucode>
##argument## is either an atom, or a sequence standing for one or more 
parameters. Since the first parameter does not need to be a constant, you may 
use some sort of dynamic calling. The circumstances where it is useful are rare.

The complete list of known values for ##id## is to be found in the file 
##source/execute.h##.

Defining new identifiers and overriding ##machine_func## or ##machine_proc##
to handle them is an easy way to extend the capabilities of the interpreter.

!!CONTEXT:../docs/tasking.txt
%%output = tasking

== Multitasking in Euphoria
:<<LEVELTOC level=2 depth=4>>

=== Introduction

Euphoria allows you to set up multiple, independent tasks.  Each task has its
own current statement that it is executing, its own call stack, and its own set
of private variables.  Tasks run in parallel with each other. That is, before
any given task completes its work, other tasks can be given a chance to
execute.  Euphoria's task scheduler decides which task should be active at any
given time.

=== Why Multitask?

Most programs do not need to use multitasking and would not benefit from it.
However it is very useful in some cases:

* Action games where numerous characters, projectiles etc. need to be displayed 
in a realistic way, as if they are all independent of one another. Language War 
is a good example.
* Situations where your program must sometimes wait for input from a human or 
other computer. While one task in your program is waiting, another separate task
could be doing some computation, disk search, etc.
* All operating systems today have special API routines that let 
you initiate some I/O, and then proceed without waiting for it to finish. A task
could check periodically to see if the I/O is finished, while another task is 
performing some useful computation, or is perhaps starting another I/O operation.
* Situations where your program might be called upon to serve many users 
simultaneously. With multiple tasks, it's easy to keep track of the state of 
your interaction with all these separate users.
* Perhaps you can divide your program into two logical processes, and have a 
task for each. One produces data and stores it, while the other reads the data 
and processes it. Maybe the first process is time-critical, since it interacts 
with the user, while the second process can be executed during lulls in the 
action, where the user is thinking or doing something that doesn't require quick
response.

=== Types of Tasks

Euphoria supports two types of tasks: real-time tasks, and time-share tasks.

**Real-time tasks** are scheduled at intervals, specified by a number of
seconds or fractions of a second. You might schedule one real-time task to be
activated every 3 seconds, while another is activated every 0.1 seconds.  In
Language War, when the Euphoria ship moves at warp 4, or a torpedo flies across
the screen, it's important that they move at a steady, timed pace.

**Time-share tasks** need a share of the CPU but they needn't be rigidly
scheduled according to any clock.

It's possible to reschedule a task at any time, changing its timing or its
slice of the CPU. You can even convert a task from one type to the other
dynamically.

=== A Small Example

This example shows the main task (which all Euphoria programs start off
with) creating two additional real-time tasks. We call them real-time because
they are scheduled to get control every few seconds.

You should try copy/pasting and running this example.  You'll see that task 1
gets control every 2.5 to 3 seconds, while task 2 gets control every 5 to 5.1
seconds.  In between, the main task (task 0), has control as it checks for a
'q' character to abort execution.

<eucode>
constant TRUE = 1, FALSE = 0

type boolean(integer x)
	return x = 0 or x = 1
end type

boolean t1_running, t2_running

procedure task1(sequence message)
	for i = 1 to 10 do
		printf(1, "task1 (%d) %s\n", {i, message})
		task_yield()
	end for
	t1_running = FALSE
end procedure

procedure task2(sequence message)
	for i = 1 to 10 do
		printf(1, "task2 (%d) %s\n", {i, message})
		task_yield()
	end for
	t2_running = FALSE
end procedure

puts(1, "main task: start\n")

atom t1, t2

t1 = task_create(routine_id("task1"), {"Hello"})
t2 = task_create(routine_id("task2"), {"Goodbye"})

task_schedule(t1, {2.5, 3})
task_schedule(t2, {5, 5.1})

t1_running = TRUE
t2_running = TRUE

while t1_running or t2_running do
	if get_key() = 'q' then
		exit
	end if
	task_yield()
end while

puts(1, "main task: stop\n")
-- program ends when main task is finished
</eucode>

=== Comparison with earlier multitasking schemes

In earlier releases of Euphoria, Language War already had a mechanism for
multitasking, and some people submitted to User Contributions their own
multitasking schemes. These were all implemented using plain Euphoria code,
whereas this new multitasking feature is built into the interpreter. Under the
old Language War tasking scheme a scheduler would *call* a task, which would
eventually have to *return* to the scheduler, so it could then dispatch the
next task.

In the new system, a task can call the built-in procedure ##task_yield## at any
point, perhaps many levels deep in subroutine calls, and the scheduler, which
is now part of the interpreter, will be able to transfer control to any other
task. When control comes back to the original task, it will resume execution at
the statement after ##task_yield##, with its call stack and all private variables
intact. Each task has its own call stack, program counter (i.e. current
statement being executed), and private variables.  You might have several tasks
all executing a routine at the same time, and each task will have its own set
of private variable values for that routine. Global and local variables are
shared between tasks.

It's fairly easy to take any piece of code and run it as a task.  Just insert a
few ##task_yield## statements so it will not hog the CPU.

=== Comparison with multithreading

When people talk about threads, they are usually referring to a mechanism
provided by the operating system. That's why we prefer to use the term
"multitasking".  Threads are generally "preemptive", whereas Euphoria
multitasking is "cooperative". With preemptive threads, the operating system
can force a switch from one thread to another at virtually any time.  With
cooperative multitasking, each task decides when to give up the CPU and let
another task get control. If a task were "greedy" it could keep the CPU for
itself for long intervals. However since a program is written by one person or
group that wants the program to behave well, it would be silly for them to
favor one task like that.  They will try to balance things in a way that works
well for the user.  An operating system might be running many threads, and many
programs, that were written by different people, and it would be useful to
enforce a reasonable degree of sharing on these programs.  Preemption makes
sense across the whole operating system. It makes far less sense within one
program.

Furthermore, threading is notorious for causing subtle bugs.  Nasty things can
happen when a task loses control at just the wrong moment. It may have been
updating a global variable when it loses control and leaves that variable in an
inconsistent state.  Something as trivial as incrementing a variable can go
awry if a thread-switch happens at the wrong moment. e.g. consider two threads.
One has:

<eucode>
x = x + 1
</eucode>

and the other also has:

<eucode>
x = x + 1
</eucode>

At the machine level, the first task loads the value of x into a register, then
loses control to the second task which increments x and stores the result back
into x in memory. Eventually control goes back to the first task which also
increments x *using the value of x in the register*, and then stores it into x
in memory. So x has only been incremented once instead of twice as was
intended. To avoid this problem, each thread would need something like:

<eucode>
lock x
x = x + 1
unlock x
</eucode>

where lock and unlock would be special primitives that are safe for threading.
It's often the case that programmers forget to lock data, but their program
seems to run ok. Then one day, many months after they've written the code, the
program crashes mysteriously.

Cooperative multitasking is much safer, and requires far fewer expensive
locking operations. Tasks relinquish control at safe points once they have
completed a logical operation.

=== Summary

For a complete function reference, refer to the Library Documentation
[[:Multitasking]].


!!CONTEXT:../docs/database.txt
%%output = database

== Euphoria Database System (EDS)
:<<LEVELTOC level=2 depth=4>>

=== Introduction  

While you can connect Euphoria to most databases 
(MySQL, SQLite, PostgreSQL, etc.), sometimes you don't need that kind
of power. The **Euphoria Database System** (EDS) is a simple, easy-to-use, 
flexible, Euphoria-oriented database for storing data that works better for 
cases where you need more than a text file and don't quite need or want the
power and complexity of larger database packages.
 
=== EDS Database Structure

In EDS, a **database** is "a single file with a ##.edb## file extension."  An EDS
database contains zero or more **tables**. Each table has a **name**, and 
contains zero or more **records**.  Each record consists of a **key** part, and 
a **data** part. The key can be //any// Euphoria object~--an atom, a sequence, a
deeply-nested sequence, whatever. Similarly the data can be //any// Euphoria
object.  There are //no// constraints on the size or structure of the key or
data. Within a given table, the keys are all unique. That is, no two records in
the same table can have the same key part.
 
The records of a table are stored in ascending order of key value.  An
efficient binary search is used when you refer to a record by key. You can also
access a record directly, with no search, if you know its current 
**record number** within the table. Record numbers are integers from one to the 
length (current number of records) of the table. By incrementing the record 
number, you can efficiently step through all the records, in order of key. 
Note however that a record's number can change whenever a new record is 
inserted, or an existing record is deleted.

The keys and data parts are stored in a compact form, but //no// accuracy is 
lost when saving or restoring floating-point numbers or //any// other Euphoria 
data.

##std/eds.e## will work as is, on all platforms. EDS database files can be 
copied and shared between programs running on all platforms as well. When 
sharing EDS database files, be sure to make an exact byte-for-byte copy using 
"binary" mode copying, rather than "text" or "ASCII" mode, which could change 
the line terminators.
 
Example:

{{{
database: "mydata.edb"
    first table: "passwords"
        record #1:  key: "jones"   data: "euphor123"
        record #2:  key: "smith"   data: "billgates"
        
    second table: "parts"
        record #1:  key: 134525    data: {"hammer", 15.95, 500}
        record #2:  key: 134526    data: {"saw", 25.95, 100}
        record #3:  key: 134530    data: {"screw driver", 5.50, 1500}
}}}

It's up to you to interpret the meaning of the key and data. //In keeping with
the spirit of Euphoria, you have total flexibility.// Unlike most other
database systems, an EDS record is //not// required to have either a fixed 
number of fields, or fields with a preset maximum length.
 
In many cases there will not be any natural key value for your records.  In
those cases you should simply create a meaningless, but unique, integer to be
the key. Remember that you can always access the data by record number. It's
easy to loop through the records looking for a particular field value.

=== Accessing Data

To reduce the number of parameters that you have to pass, there is a notion of
the **current database**, and **current table**. 

==== Current Database.

Any data operation or table operation assumes there is a current database being 
defined. You set the current database by opening, creating or selecting a 
database. Deleting the current database leaves the current database undefined.

==== Current Table.

All data operations assume there is a current table being defined. You must 
create, select or rename a table in order to make it current. Deleting the 
current table leaves the current table undefined.

==== Accessing Data

Most routines use these
//current// values automatically.  You normally start by opening (or creating)
a database file, then selecting the table that you want to work with.
 
You can map a key to a record number using [[:db_find_key]]. It uses an
efficient binary search. Most of the other record-level routines expect the
record number as a parameter. You can very quickly access any record, given
it's number. You can access all the records by starting at record number one and
looping through to the record number returned by [[:db_table_size]].
 
=== Storage Recycling

When you delete something, such as a record, the space for that item gets put
on a free list, for future use. Adjacent free areas are combined into larger
free areas. When more space is needed, and no suitable space is found on the
free list, the file will grow in size.  Currently there is no automatic way
that a file will shrink in size, but you can use a
[[:db_compress]] to completely rewrite a
database, removing the unused spaces.

=== Security and Multi-user Access

This release provides a simple way to lock an entire database to prevent unsafe
access by other processes.

=== Scalability

Internal pointers are 4 bytes. In theory that limits the size of a database
file to 4 Gb. In practice, the limit is 2 Gb because of limitations in 
various C file functions used by Euphoria.  Given enough user demand, EDS 
databases could be expanded well beyond 2 Gb in the future.
 
The current algorithm allocates four bytes of memory per record in the current
table. So you will need at least 4 Mb RAM per million records on disk.
 
The binary search for keys should work reasonably well for large tables. 
 
Inserts and deletes take slightly longer as a table gets larger. 
 
At the low end of the scale, it's possible to create extremely small databases
without incurring much disk space overhead.

=== EDS API

More details on using EDS, including complete coverage of the EDS API, can be 
found at [[:Euphoria Database (EDS)]].

=== Disclaimer

Do not store valuable data without a backup.  RDS will not be responsible for
any damage or data loss.

=== Warning: Use Binary File Mode

##.edb## files are binary files, not text files.  You **must** use ##BINARY## 
mode when
transferring a ##.edb## file via FTP from one machine to another. You must also
avoid loading a ##.edb## file into an editor and saving it. If you open a 
##.edb## file directly using Euphoria's ##open##, which is not recommended, 
you must use binary
mode, not text mode.  Failure to follow these rules could result in 10
(line-feed) and 13 (carriage-return) bytes being changed, leading to subtle and
not-so-subtle forms of corruption in your database.

!!CONTEXT:../docs/preproc.txt
%%output = preproc

== The User Defined Pre-Processor
:<<LEVELTOC level=2 depth=4>>

The user defined **pre-processor**, developed by Jeremy Cowgar, opens a world
of possibilities to the Euphoria programmer. In a sentence, it allows
one to create (or use) a translation process that occurs transparently
when a program is run. This mini-guide is going to explore the
pre-processor interface by first giving a quick example, then
explaining it in detail and finally by writing a few useful
pre-processors that can be put immediately to work.

Any program can be used as a pre-processor. It must, however, adhere to a
simple specification:

# Accept a parameter "-i filename" which specifies which file to read and
process.
# Accept a parameter "-o filename" which specifies which file to write
the result to.
# Exit with a zero error code on success or a non-zero error code on
failure.

It does not matter what type of program it is. It can be a Euphoria script,
an executable written in the C programming language, a script/batch file or
anything else that can read one file and write to another file. As Euphoria
programmers, however, we are going to focus on writing pre-processors in
the Euphoria programming language. As a benefit, we will describe later
on how you can easily convert your pre-processor to a shared library that
Euphoria can make use of directly thus improving performance.

=== A Quick Example

The problem in this case is that you want the copyright statement and the
about screen to show what date the program was compiled on but you do not
want to manually maintain this date. So, we are going to create a simple
pre-processor that will read a source file, replace all instances of
@DATE@ with the current date and then write the output back out.

Before we get started, let me say that we will expand on this example
later on. Up front, we are going to do almost no error checking for
the purpose of showing off the pre-processor not for the sake of
making a production quality application.

We are going to name this file ##datesub.ex##.

<eucode>
-- datesub.ex
include std/datetime.e -- now() and format()
include std/io.e       -- read_file() and write_file()
include std/search.e   -- match_replace()

sequence cmds = command_line()
sequence inFileName, outFileName

for i = 3 to length(cmds) do
    switch cmds[i] do
        case "-i" then
            inFileName = cmds[i+1]
        case "-o" then
            outFileName = cmds[i+1]
    end switch
end for

sequence content = read_file(inFileName)

content = match_replace("@DATE@", content, format(now()))

write_file(outFileName, content)

-- programs automatically exit with ZERO error code, if you want
-- non-zero, you exit with abort(1), for example.
</eucode>

So, that is our pre-processor. Now, how do we make use of it? First let's
create a
simple test program that we can watch it work with. Name this file
##thedate.eui##.

<eucode>
-- thedate.eui

puts(1, "The date this was run is @DATE@\n")
</eucode>

Rather simple, but it shows off the pre-processor we have created. Now,
let's
run it, but first without a pre-processor hook defined.

NOTE: Through this document I am going to assume that you are working in
//Windows//.
If not, you can make the appropriate changes to the shell type examples.

{{{
C:\MyProjects\datesub> eui thedate.eui
The date this was run is @DATE@
}}}

Not very helpful? Ok, let's tell Euphoria how to use the pre-processor
that we just
created and then see what happens.

{{{
C:\MyProjects\datesub> eui -p eui:datesub.ex thedate.eui
The date this was run is 2009-08-05 19:36:22
}}}

If you got something similar to the above output, good job, it worked! If
not,
go back up and check your code for syntax errors or differences from the
examples
above.

What is this -p paramater? In short, -p tells eui or euc that there is a
pre-processor. The definition of the pre-processor comes next and can
be broken into 2 required sections and 1 optional section. Each section
is divided by a colon (:). \\
For example, ##-p e,ex:datesub.ex##

# ##e,ex## tells Euphoria that when it comes across a file with the
extension ##e## or ##ex## that it should run a pre-processor
# ##datesub.ex## tells Euphoria which pre-processor should be run. This
can be a ##.ex## file or any other executable command.
# An optional section exists to pass options to the pre-processor but we
will go into this later.

That's it for the quick introduction. I hope that the wheels are turning
in your head already as to what can be accomplished with such a system.
If you are interested, please continue reading and see where things
will get very interesting!

=== Pre-process Details

Euphoria manages when the pre-processor should be called and with what
arguments. The pre-processor does not need to concern itself as to if it
should run, what filename it is reading or what filename it will be
writing to. It should simply do as Euphoria tells it to do. This is
because Euphoria monitors what the modification time is on the source
file and what time the last pre-process call was made on the file. If
nothing has changed in the source file then the pre-processor is not
called again. Pre-processing does have a slight penalty in speed as the
file is processed twice. For example, the ##datesub.ex## pre-processor
read the entire file, searched for ##@DATE@##, wrote the file and then
Euphoria picked up from there reading the output file, parsing it and
finally executing it. To minimize the time taken, Euphoria caches the
output of the pre-processor so that the interim process is not normally
needed after it has been run once.

=== Command Line Options

==== -p - Define a pre-processor

The primary command line option that you will use is the ##-p## option
which defines the pre-processor. It is a two or three section option. The
first section is a comma delimited list of file extensions to associate
with the pre-processor, the second is the actual pre-processor
script/command and the optional third is parameters to send to the
pre-processor in addition to the ##-i## and ##-o## parameters.

Let's go over some examples:

* ##-p e:datesub.ex## - This will be executed for every ##.e## file and
the command to call is ##datesub.ex##.
* ##-p "de,dex,dew:dot4.dll:-verbose -no-dbc"## - Files with ##de, dex,
dew## extensions will be passed to the ##dot4.dll## process. ##dot4.dll##
will get the optional parameters ##-verbose -no-dbc## passed to it.

Multiple pre-processors can be defined at the same time. For instance,

{{{
C:\MyProjects\datesub> eui -p e,ex:datesub.ex -p de,dex:dot4.dll \
        -p le,lex:literate.ex hello.ex
}}}

is a valid command line. It's possible that ##hello.ex## may include a
file named ##greeter.le## and that file may include a file named
##person.de##. Thus, all three pre-processors will be called upon even
though the main file is only processed by ##datesub.ex##

==== -pf - Force pre-processing

When writing a pre-processor you may run into the problem that your
source file did not change, therefore, Euphoria is not calling your
pre-processor. However, your pre-processor has changed and you want
Euphoria to re-process your unchanged source file. This is where ##-pf##
comes into play. ##-pf## causes Euphoria to force the pre-processing,
regardless of the cached state of any file. When used, Euphoria will
always call the pre-processor for all files with a matching pre-processor
definition.

==== Use of a configuration file

Ok, so who wants to type these pre-processor definitions in all the time?
I don't either. That's where the standard Euphoria configuration file
comes into play. You can simply create a file named ##eu.cfg## and place
something like this into it.

{{{
-p le,lex:literate.ex
-p ei,eui:datesub.ex
... etc ...
}}}

Then you can execute any of those files directly without the ##-p##
parameters on the command line. This ##eu.cfg## file can be local to a
project, local to a user or global on a system. Please read about the
[[:eu.cfg]] file for more information.

=== DLL/Shared Library Interface

A pre-processor may be a Euphoria file, ending with an extension of
##.ex##, a compiled Euphoria program, ##.exe## or even a compiled
Euphoria DLL file, ##.dll##. The only requirements are that it must
accept the two command line options, -i and -o described above and exit
with a ZERO status code on success or non-ZERO on failure.

The DLL file (or shared library on //Unix//) has a real benefit in that
with each file that needs to be pre-processed does not require a new
process to be spawned as with an executable or a Euphoria script. Once
you have the pre-processor written and functioning, it's easy to convert
your script to use the more advanced, better performing shared library.
Let's do that now with our ##datesub.ex## pre-processor. Take a
moment to review the code above for the ##datesub.ex## program before
continuing. This will allow you to more easily see the changes that we
make here.

<eucode>
-- datesub.ex
include std/datetime.e -- now() and format()
include std/io.e       -- read_file() and write_file()
include std/search.e   -- match_replace()

public function preprocess(sequence inFileName, sequence outFileName,
        sequence options={})

    sequence content = read_file(inFileName)

    content = match_replace("@DATE@", content, format(now()))

    write_file(outFileName, content)

    return 0
end function

ifdef not EUC_DLL then
    sequence cmds = command_line()
    sequence inFileName, outFileName

    for i = 3 to length(cmds) do
        switch cmds[i] do
            case "-i" then
                inFileName = cmds[i+1]
            case "-o" then
                outFileName = cmds[i+1]
        end switch
    end for

    preprocess(inFileName, outFileName)
end ifdef
</eucode>

It's beginning to look a little more like a well structured program.
You'll notice that we took the actual pre-processing functionality out
the the top level program making it into an exported function named
##preprocess##. That function takes three parameters:

# ##inFileName## - filename to read from
# ##outFileName## - filename to write to
# ##options## - options that the user may wish to pass on verbatim to the
pre-processor

It should return 0 on no error and non-zero on an error. This is to keep
a standard with the way error levels from executables function. In that
convention, it's suggested that 0 be OK and 1, 2, 3, etc... indicate
different types of error conditions. Although the function could return a
negative number, the main routine cannot exit with a negative number.

To use this new process, we simply translate it through ##euc##,

{{{
C:\MyProjects\datesub> euc -dll datesub.ex
}}}

If all went correctly, you now have a datesub.dll file. I'm sure you can
guess on how it should be used, but for the sake of being complete,

{{{
C:\MyProjects\datesub> eui -p eui:datesub.dll thedate.eui
}}}

On such a simple file and such a simple pre-processor, you probably are
not going to notice a speed difference but as things grow and as the
pre-processor gets more complicated, compiling to a shared library is
your best option.

=== Advanced Examples

==== Finish datesub.ex

Before we move totally away from our ##datesub.ex## example, let's finish
it off by adding some finishing touches and making use of optional
parameters. Again, please go back and look at the Shared Library version
of ##datesub.ex## before continuning so that you can see how we have
changed things.

<eucode>
-- datesub.ex
include std/cmdline.e  -- command line parsing
include std/datetime.e -- now() and format()
include std/io.e       -- read_file() and write_file()
include std/map.e      -- map accessor functions (get())
include std/search.e   -- match_replace()

sequence cmdopts = {
    { "f", 0, "Date format", { NO_CASE, HAS_PARAMETER, "format" } }
}

public function preprocess(sequence inFileName, sequence outFileName,
        sequence options={})
    map opts = cmd_parse(cmdopts, options)
    sequence content = read_file(inFileName)

    content = match_replace("@DATE@", content, format(now(), map:get(opts,
"f")))

    write_file(outFileName, content)

    return 0
end function

ifdef not EUC_DLL then
    cmdopts = {
        { "i", 0, "Input filename", { NO_CASE, MANDATORY, HAS_PARAMETER,
"filename"} },
        { "o", 0, "Output filename", { NO_CASE, MANDATORY, HAS_PARAMETER,
"filename"} }
    } & cmdopts

    map opts = cmd_parse(cmdopts)
    preprocess(map:get(opts, "i"), map:get(opts, "o"),
        "-f " & map:get(opts, "f", "%Y-%m-%d"))
end ifdef
</eucode>

Here we simply used ##cmdline.e## to handle the command line parsing for
us giving out command line program a nice interface, such as parameter
validation and an automatic help screen. At the same time we also added a
parameter for the date format to use. This is optional and if not
supplied, ##%Y-%m-%d## is used.

The final version of ##datesub.ex## and ##thedate.ex## are located in the
##demo/preproc## directory of your Euphoria installation.

==== Others

TODO: this needs done still.

Euphoria includes two more demos of pre-processors. They are ETML and
literate. Please explore ##demo/preproc## for these examples and
explanations.

===== Other examples of pre-processors include

* eSQL - Allows you to include a ##.sql## file directly. It parses
##CREATE TABLE## and ##CREATE INDEX## statements building common routines
to create, destroy, get by id, find by any index, add, remove and save
entities.
* make40 - Will process any 3.x script on the fly making sure that it
will run in 4.x. It does this by converting variables, constants and
routine names that are the same as new 4.x keywords into something
acceptable to 4.x. Thus, 3.x programs can run in the 4.x interpreter and
translator with out any user intervention.
* dot4 - Adds all sorts of syntax goodies to Euphoria such as structured
sequence access, one line if statements, DOT notation for any
function/routine call, design by contract and more.

===== Other Ideas

* Include a //Windows// .RC file that defines a dialog layout and generate
code that will create the dialog and interact with it.
* Object Oriented system for Euphoria that translates into pure Euphoria
code, thus has the raw speed of Euphoria.
* Include a Yacc, Lex, ANTLR parser definition directly that then
generates a Euphoria parser for the given syntax.
* Instead of writing interpreters such as a QBasic clone, simply write a
pre-processor that converts QBasic code into Euphoria code, thus you can
run eui -p bas:qbasic.ex hello.bas directly.
* Include a XML specification, which in turn, gives you nice accessory
functions for working with XML files
matching that schema.

If you have ideas of helpful pre-processors, please put the idea out on
the forum for discussion.

!!CONTEXT:../docs/trouble.txt
%%output = trouble

== Euphoria Trouble-Shooting Guide
:<<LEVELTOC level=2 depth=4>>

If you get stuck, here are some things you can do:

# Type: ##guru## followed by some keywords associated with your problem. For 
example, ##guru declare global include##
# Check the list of common problems ([[:Common Problems and Solutions]]).
# Read the relevant parts of the documentation, i.e. 
[[:toc|Euphoria Programming Language v4.0]] or [[:API Reference]].
# Try running your program with trace:
<eucode>
with trace
trace(1)
</eucode>
# The [[http://openeuphoria.org/forum/index.wc|Euphoria Forum]] has a 
search facility. You can search the archive of all previous messages. There is a
good chance that your question has already been discussed.
# Post a message on the forum.
# Visit the Euphoria IRC channel, [[irc://irc.freenode.net/#euphoria]].

=== Common Problems and Solutions

Here are some commonly reported problems and their solutions.

==== Console window disappeared

//I ran my program with ##euiw.exe## and the console window disappeared
before I could read the output.//

The console window will only appear if required, and will disappear immediately 
when your program finishes execution. Perhaps you should code something like:

<eucode>
puts(1, "\nPress Enter\n")
if getc(0) then
end if
</eucode>
at the end of your program.

You may also run your console program with ##eui.exe##.

==== Press Enter

//At the end of execution of my program, I see "Press Enter" and I have to hit 
the Enter key. How do I get rid of that?//

Call [[:free_console]] just before your program terminates.

<eucode>
include dll.e

free_console()
</eucode>

==== CGI Program Hangs / No Output

//My Euphoria CGI program hangs or has no output//

# Make sure that you are using the ##-batch## parameter to ##eui##. This causes 
Euphoria to not present the normal "Press any key to continue..." prompt when a 
warning or error occurs. The web server will not respond to this prompt and your
application will hang waiting for ENTER to be pressed.
# Use the ##-wf## parameter to write all warnings to a file instead of the 
console. The warnings that Euphoria will write to the console may interfere with 
the actual output of your web content.
# Look for an ex.err file in your cgi-bin directory. Turn on 
##with trace## / ##trace(3)## to see  what statements are executed (see 
##ctrace.out## in your cgi-bin). On //Windows// you should always use ##eui.exe##
to run CGI programs, or you may have problems with standard output. With
Apache Web Server, you can have a first line in your program of:
#!.\eui.exe to run your program using eui.exe in the current (cgi-bin)
directory. Be careful that your first line ends with the line breaking characters
appropriate for your platform, or the ##!## won't be handled correctly. You 
must also set the execute permissions on your program correctly, and ##ex.err## 
and ctrace.out must be writable by the server process or they won't be updated.


==== Read / Write Ports?

//How do I read/write ports?//

There are collections of machine-level routines from the
[[http://www.rapideuphoria.com|Euphoria Web Page]].

==== Program has no errors, no output

//When I run my program there are no errors but nothing happens.//

You probably forgot to call your main procedure. You need
a top-level statement that comes after your main procedure to call the
main procedure and start execution.

==== Routine not declared

//I'm trying to call a routine documented in ##library.doc##, but it keeps
saying the routine has not been declared.//

Did you remember to include the necessary ##.e## file from the 
##euphoria\include## directory? If the syntax of the routine says for example,
"##include\std\graphics.e##", then your program must have 
"##include\std\graphics.e##" (without the quotes) before the place where you 
first call the routine.

==== Routine not declared, my file

//I have an include file with a routine in it that I want to call, but when I
try to call the routine it says the routine has not been declared. But it 
**has** been declared.//

Did you remember to define the routine as ##public##, ##export## or possibly 
##global##? If not, the routine is not visible outside of its own file.

==== After user input, left margin problem

//After inputting a string from the user with ##gets##, the next line that 
comes out on the screen does not start at the left margin.//

Your program should output a //new-line// character e.g.

<eucode>
input = gets()
puts(SCREEN, '\n')
</eucode>

==== Floating-point calculations not exact

//Why aren't my floating-point calculations coming out exact?//

Intel CPU's, and most other CPU's, use binary numbers to represent
fractions. Decimal fractions such as 0.1, 0.01 and
similar numbers can't be represented precisely. For example, 0.1 might
be stored internally as ##0.0999999999999999## . That means that ##10 * 0.1##
might come out as ##0.999999999999999##, and ##floor(10 * 0.1)## might be ##0##,
not ##1## as you would expect. This can be a nuisance when you are dealing
with money calculations, but it is not a Euphoria problem. It's a
general problem that you must face in most programming languages.
Always remember: floating-point numbers are just an approximation
to the "real" numbers in mathematics. Assume that any floating-point calculation
might have a tiny bit of error in the result. Sometimes you can
solve the problem by rounding, e.g. x = round( x, 100 ) would round
x off to the nearest hundredth.  Storing money values as an integer
number of pennies, rather than a fractional number of dollars
(or similar currency) will help, but some calculations could still
cause problems.



==== Number to a string?

//How do I convert a number to a string?//

Use [[:sprintf]]:

<eucode>
string = eu:sprintf("%d", 10) -- string is "10"
</eucode>

or use [[:number]]:

<eucode>
include std/locale.e as locale
string = locale:number(10) 
         -- string is probably "10.00" if called in the U.S.
         -- It depends on the locale preferences set on your computer.
</eucode>

Number formats according to the locale setting on your computer and
strangely, this means to give you two decimal places whether or not
you supply an integer value for the U.S. locale.

Besides ##%d##, you can also try other formats, such as
##%x## (Hex) or ##%f## (floating-point).

==== String to a number?

//How do I convert a string to a number?//

Use [[:value]].

==== Redefine my for-loop variable?

//It says I'm attempting to redefine my for-loop variable.//

For-loop variables are declared automatically. Apparently you already have a
declaration with the same name earlier in your routine or your program.
Remove that earlier declaration or change the name of your loop variable.

==== Unknown Escape Character

//I get the message "unknown escape character" on a line where I am trying
to specify a file name.//

**Do not** say ##"C:\TMP\MYFILE"##. You need to say ##"C:~\~\TMP~\~\MYFILE"## 
or use back-quotes ##`C:~\TMP~\MYFILE`##.

Backslash is used for escape characters such as ##\n## or ##\t##. To specify a 
single backslash in a string you need to type ##~\~\##. Therefore, say 
##"C:~\~\TMP~\~\MYFILE"## instead of ##"C:\TMP\MYFILE"##

==== Only first character in printf

//I'm trying to print a string using [[:printf]] but only the first character
comes out.//

You need to put braces around the parameters sequence to [[:printf]]. You
probably wrote:

<eucode>
printf(1, "Hello, %s!\n", mystring)
</eucode>

but you need:

<eucode>
printf(1, "Hello, %s!\n", {mystring})
</eucode>

==== Only 10 significant digits during printing

//When I print numbers using [[:printf]] or [[:? ->q_print]] only 10 significant
digits are displayed.//

Euphoria normally only shows about 10 digits. Internally, all
calculations are performed using at least 15 significant digits. To see
more digits you have to use [[:printf]]. For example,

<eucode>
printf(1, "%.15f", 1/3)
</eucode>

This will display 15 digits.

==== A type is expected here

//It complains about my routine declaration, saying, "a type is expected
here."//

When declaring subroutine parameters, Euphoria requires you to
provide an explicit type for each individual parameter. e.g.

<eucode>
procedure foo(integer x, y)         -- WRONG
procedure foo(integer x, integer y) -- RIGHT
</eucode>

In all other contexts it is ok to make a list:

<eucode>
atom a, b, c, d, e
</eucode>

==== Expected to see...

//It says: ##Syntax Error - expected to see possibly 'xxx', not 'yyy'##//

At this point in your program you have typed a variable, keyword, number or
punctuation symbol, yyy, that does not fit syntactically with what has come
before it. The compiler is offering you one example, xxx, of something that
would be accepted at this point in place of yyy. Note that there may be many
other legal (and much better) possibilities at this point than xxx, but xxx
might at least give you a clue as to what the compiler is "thinking."

!!CONTEXT:../docs/platform.txt
%%output = platform

== Platform Specific Issues
:<<LEVELTOC level=2 depth=4>>

=== Introduction

OpenEuphoria currently supports Euphoria on many different
**platforms**. More platforms will be added in the future.

[[**DOS**|:The Discontinued DOS32 Platform]] platform support has been discontinued.

[[**Windows**|:The WINDOWS Platform]] in particular, the 32-bit x86 compatible version of//Windows//. The minimum version is
Windows 95 Original Equipment Manufacturer Service Release 2.5. EUPHORIA will work on all old and
new versions of //Windows// written after Windows 95. However, to use all of the features you must use 
Windows XP or later.  See ''.

**Linux**. Linux is inspired by the UNIX operating system. It has recently become very popular on PCs.
There are many distributors of Linux, including Red Hat, Debian, Ubuntu, and many more. Linux can be obtained
on a CD for a very low price. Linux is an open-source operating system.

**FreeBSD**. FreeBSD is also based on the UNIX
operating system. It is very popular on  Internet server machines. It's
also open source.

Apple's **OS X**. OS X is also based on the UNIX
operating system. While it is closed source, it is gaining a wide
following due to it's ease of use and power.

**OpenBSD**. Open BSD is also a UNIX-like
Operating System and is developed by volunteers.

**NetBSD**. Net BSD is also a UNIX-like
Operating System  and is designed to be easily  portable to other
hardware platforms.



Euphoria source files use various file extensions. The common
extensions are:

|=extension |= application |
| .e | Euphoria include file |
| .ew | Euphoria include file for a Windowed (GUI) application only |
| .ex | Console main program file \\or any executable program |
| .exw | Windowed (GUI) main program file\\or a //Windows// specific program |
| .exu | Unix specific program |

It is convenient to use these file extensions, but they are not
mandatory. 


The Euphoria for //Windows// installation file contains **eui.exe**. It runs
Euphoria programs on the //Windows// 32bit platform.

The Euphoria for //Linux// .tar file contains only **eui**. It runs
Euphoria programs on the Linux platform.

Other versions of Euphoria are installed by first installing the Linux
version of Euphoria, replacing eui with the version of eui for
that Operating System, then rebuilding the other binaries from the source.

Sometimes you'll find that the majority of your code will be the
same on all platforms, but some small parts will have to be
written differently for each platform. Use the [[:ifdef]] statement 
to tell you 
[[:Platform Definitions|which platform you are currently running on]].

You can also use the [[:platform]] and [[:platform_name]] functions:

<eucode>
printf(1, "Our platform number is: %d", {platform()})
</eucode>

The evaluation of ##platform## occurs at 'runtime', you may even use a switch 
statement with it.

<eucode>
switch platform() do
    case WINDOWS then
       -- Windows code
    case LINUX then
       -- LINUX code
    case FREEBSD,NETBSD then
       -- BSD code
       ... etc
    case else
       crash("Unsupported platform")
end switch
</eucode>

Another way is to use parse-time evaluation using ifdefs.  

<eucode>
ifdef WINDOWS then
  -- Windows code
elsifdef LINUX then
  -- LINUX code
elsifdef FREEBSD or NETBSD then
  -- BSD code
elsedef
    crash("Unsupported platform")
end ifdef
</eucode>

With parse-time evalution you get faster execution, for there is no conditional 
in the final code.  You can put this deeply inside a loop without penalty.  You 
can test for ##UNIX## to see if the platform has //Unix//-like properties and 
thus will work on new //Unix//-like platforms without modification.  You can 
even put statements that are top-level, such as constant and routine defintions.  
However, since the interpreter skips over the platforms you are not running on, 
syntax errors can hide in this construct and if you misspell an OS name you will 
not get warned.

<eucode>
ifdef UNIX then
	public constant SLASH='/'
	public constant SLASHES = "/"
	public constant EOLSEP = "\n"
	public constant PATHSEP = ':'
	public constant NULLDEVICE = "/dev/null"
	ifdef OSX then
		public constant SHARED_LIB_EXT = "dylib"
	elsedef
		public constant SHARED_LIB_EXT = "so"
	end ifdef
        
	public constant FOO =  SLASH == PATHSEP -- this has a hidden syntax error
	
elsifdef WINDOWS then

	public constant SLASH='\\'
	public constant SLASHES = "\\/:"
	public constant EOLSEP = "\r\n"
	public constant PATHSEP = ';'
	public constant NULLDEVICE = "NUL:"
	public constant SHARED_LIB_EXT = "dll"
	
elsifdef TRASHOS then  -- this symbol is never defined -- no error here either
       
end ifdef
</eucode>

In this above example, we have constant declarations which are different 
according to OS such things.  The line with FOO has a syntax error but your 
interpreter will not catch it if you are running //Windows//.  There is no OS 
with the name 'TRASHOS'.  I simply made it up and this construct will not warn 
you about mistakes like these.

Run-time evalution provides you something that is always syntax-checked and you 
can even make expressions using comparatives to avoid both parse-time and 
run-time branching all together.

<eucode>
add_code = {
    -- first int argument is at stack offset +4, 2nd int is at +8 
       #8B, #44, #24, #04,                  -- mov   eax, +4[esp]
       #03, #44, #24, #08,                  -- add   eax, +8[esp]
       #C2, #00, #08 * (platform() = WINDOWS) -- ret 8  
                                            -- pop 8 bytes off the stack
}
</eucode>

This is machine code to be put into memory as an example from 
##.../euphoria/demo/callmach.ex##.  Here if ##platform() = WINDOWS## is true, then the code 
will pop 8 bytes off of the stack, if not it will pop 0 bytes off of the stack.  
This has to be done because of where the function call conventions are 
implemented in the various compilers.  We use Watcom C for //Windows// and GCC for the 
others.  Now if the programmer had put a non-existent symbol, such as ARCH64, the 
parser would stop, point out the error, and the programmer would then fix it.


=== The Discontinued DOS32 Platform

This platform is no longer supported.  

Those interested in writing DOS programs in Euphoria may use version 3.1
downloadable from the original ~RapidEuphoria website:
http://www.rapideuphoria.com/v20.htm.

The ##DOS32## platform was for computers 
without //Windows// OS, and though people could still use the Euphoria binaries 
built for this platform on //Windows//, it was slower than and lacked features 
available on binaries built for the ##WINDOWS## platform.

The binaries for this platform had support for low-level graphics and though 
DOS was 16-bit, the Euphoria binaries for ##DOS32## used techniques that allowed 
you to use 32-bit addresses transparently, hence the name of the platform: 
##DOS32##.  However, in this platform you could not use dynamically loaded 
libraries and filenames had to be in a format of: eight letters, a dot, and 
three letters when creating a file.  You could not use the Windowing system even
if your computer had //Windows//.  You were limited to full-sreen mode graphics and 
the text console.

=== The Windows Platform

With the //Windows// platform, your programs can still use the 
##//text console//##.  Because most library routines work the same way on each 
platform most text mode programs can be run using the console interpreter of any
platform without any change.

Since the Euphoria interpreter can work directly with your OS you can also 
create GUI programs. You can use a user submitted library from the archive or 
handle calls directly into the DLLs.  
There are high-level graphics libraries for Direct3D and OpenGL available from 
the [[http://www.RapidEuphoria.com/archive.htm | Euphoria Web site]].

A console window will be created automatically when a //Windows// Euphoria program
first outputs something to the screen or reads from the keyboard.  If your 
program is displaying a screen, you will also see a console window when you read
standard input or write to standard output, even when these have been redirected
to files. The console
will disappear when your program finishes execution, or via a call to
[[:free_console]].

If you don't want a console to appear, it might help to put the following 
statements at the top of your Euphoria program:

<eucode>
-- Now, when there is input or output to the console we will get an error
-- and see in which line number this happens. 
close(STDOUT)
close(STDIN)
</eucode>

Now with these lines the interpreter is forced to give you a runtime error, 
report where in the program the standard input or output is used.  It can be 
hard to find the offending I/O statement in programs that contain many commented
out or debug mode only console I/O statements.

If you actually *want* to use the console, and there is something on the console
that you want your
user to read, you should prompt them and wait for his input before terminating.
To prevent the console from quickly disappearing you might include a statement
such as:

<eucode>
include std/console.e

any_key("Press any key to close this Window")
</eucode>
which will wait for the user enters something.

If you want to run an interpreted Euphoria program to use the current console 
use ##eui.exe## but if you want it to create a new console window use 
##euiw.exe##.

Programs translated by the translator for this platform will also pop up a 
new console whenever input is asked for our output is sent to the screen unless
you specify the ##-CON## option.

When running an interpreter or translator for the //Windows// platform, ##platform## 
returns WINDOWS and a parsetime branch (with ifdef/end ifdef) with ##WINDOWS## 
will be followed.

In order to use [[:sockets]] you must have Windows 2000 Professional or later. In order for the the
routines [[:has_console]] and [[:maybe_any_key]] to have useful behavior you must have Windows XP or
later.

==== High-Level Windows Programming

Thanks to **David Cuny**, **Derek Parnell**, **Judith Evans**
and many others, there's a package called **Win32Lib** that
you can use to develop //Windows// GUI applications in Euphoria. It's
remarkably easy to learn and use, and comes with good documentation and
many small example programs.  

If you have a SVN client, you can get a Euphoria version 4.0-compatible Win32lib
 at:
 
[[ https://win32libex.svn.sourceforge.net/svnroot/win32libex/trunk ]].  

Get version 68.

There is also an **IDE**, by Judith Evans for use with **Win32lib**. 
[[ https://euvide.svn.sourceforge.net/svnroot/euvide ]].

!!**Andrea Cini** has also developed a similar, somewhat smaller package
!!called **EuWinGUI**. It's also available from the RapidEuphoria web site.

**Matt Lewis** has developed a wrapper for the wxWidgets library for
Euphoria: wxEuphoria.  It is cross-platform.

You can download WxEuphoria, 
Win32Lib and Judith's IDE
from the [[http://www.RapidEuphoria.com/archive.htm | Euphoria Web site]].


==== Low-Level WINDOWS Programming

To allow access to //Windows// at a lower level, Euphoria
provides a mechanism for calling any C function in any //Windows// API .dll file,
or indeed in any 32-bit //Windows// .dll file that you create or someone else
creates. There is also a call-back mechanism that lets //Windows// call your
Euphoria routines. Call-backs are necessary when you create a graphical
user interface.

To make full use of the //Windows// platform, you need documentation on 32-bit
Windows programming, in particular the //Windows// Application Program Interface
(API), including the C structures defined by the API. There is a large
WINDOWS.HLP file (c) Microsoft that is available with many programming tools
for //Windows//. There are numerous books available on the
subject of //Windows// programming for {{{C/C++}}}. You can adapt most of what you 
find
in those books to the world of Euphoria programming for //Windows//.
A good book is **//{{{Programming Windows}}} by Charles Petzold//**.

A //Windows// API Windows help file (8 Mb) can be downloaded from
ftp://ftp.borland.com/pub/delphi/techpubs/delphi2/win32.zip, Borland's
Web site.

=== The Unix Platforms

As with //Windows//, you can write text on a console, or xterm window,
in multiple colors and at any line or column position.

Just as in //Windows//, you can call C routines in shared libraries
and C code can call back to your Euphoria routines.

You can get a Euphoria 
interface to high level graphics library **OpenGL** from the 
[[http://www.RapidEuphoria.com/archive.htm | Euphoria Web site]].
OpenGL also works with //Windows//.

Easy X-windows GUI programming is available using either Irv Mullin's
EuGTK interface to the GTK GUI library, or wxEuphoria developed by
Matt Lewis. wxEuphoria also runs on Windows.

When porting code from //Windows// to //Unix//, you'll notice the following 
differences:

* Some of the numbers assigned to the 16 main colors in graphics.e
are different. If you use the constants defined in graphics.e you won't
have a problem. If you hard-code your color numbers you will see
that blue and red have been switched etc.
* The key codes for special keys such as Home, End, arrow keys
are different, and there are some additional differences when you run
under XTERM.
* The Enter key is code 10 (line-feed) on Linux, where on Windows
it was 13 (carriage-return).
* Other OSes use '/' (slash) on file paths. Windows use '\' (backslash).
  If you use the SLASH constant from std/filesys.e you don't have to
  worry about this however.
* Calls to ##system## and ##system_exec## that contain //Windows// commands
will obviously have to be changed to the corresponding Linux or FreeBSD
command. e.g. "DEL" becomes "rm", and "MOVE" becomes "mv".  Often you
can use a standard library call instead and it will be portable across platforms.
For example you can use [[:filesys:create_directory]] or [[:filesys:delete_file]].

When running an interpreter or translator for a //Unix// platform, ##platform## 
will return one of the several symbols for ##UNIX## and a parsetime branch (with
ifdef/end ifdef) with ##UNIX## and the symbol that is that of the specific OS 
will be followed.

We assume that the environment is always run from some kind of CLI in two routines: The routine
[[:has_console]] always returns 0, and [[:maybe_any_key]] never waits for key input.

=== Interfacing with C Code

On //Windows// and //Unix// it is possible to interface Euphoria code with C code. Your 
Euphoria program can call C routines and read and write C variables. C routines 
can even call ("callback") your Euphoria routines. The C code must reside in a 
dynamic link or shared library. By interfacing with dynamic link libraries and 
shared libraries, you can
access the full programming interface on these systems.

Using the Euphoria to C Translator, you can translate Euphoria routines to C, 
and compile them into a shared library file. You can pass Euphoria atoms and 
sequences to these compiled Euphoria routines, and receive Euphoria data as a 
result. Translated/compiled routines typically run much faster than interpreted 
routines. For more information, see
the [[:Translator -> "Euphoria to C Translator"]].

==== Calling C Functions

To call a C function in a shared library file you must perform the following steps:
# Open the shared library file that contains the C function by calling [[:open_dll]].
# Define the C function, by calling [[:define_c_func]] or [[:define_c_proc]].
This tells Euphoria the number and type of the arguments as well as the
type of value returned.\\
Euphoria currently supports all C integer and pointer types as
arguments and return values. It also supports floating-point arguments
and return values (C double type). It is currently not possible to
pass C structures by value or receive a structure as a function
result, although you can certainly pass a pointer to a structure
and get a pointer to a structure as a return value. Passing C
structures by value is rarely required for operating system calls.\\
Euphoria also supports all forms of Euphoria data - atoms and
arbitrarily-complex sequences, as arguments to translated/compiled
Euphoria routines.
# Call the C function by calling [[:c_func]] or [[:c_proc]]
<eucode>
include dll.e

atom user32
integer LoadIcon, icon

user32 = open_dll("user32.dll")

-- The name of the routine in user32.dll is "LoadIconA".
-- It takes a pointer and an 32-bit integers as arguments,
-- and it returns a 32-bit integer.
LoadIcon = define_c_func(user32, "LoadIconA", {C_POINTER, C_INT}, C_INT)

icon = c_func(LoadIcon, {NULL, IDI_APPLICATION})
</eucode>

See [[:c_func]], [[:c_proc]], [[:define_c_func]], [[:define_c_proc]], [[:open_dll]]

See ##**demo\win32**## or ##**demo/linux**## for example programs.

On //Windows// there is more than one C calling convention.
The Windows API routines all use the **{{{__stdcall}}}** convention.
Most C compilers however have **{{{__cdecl}}}** as their default.
{{{__cdecl}}} allows for variable numbers of arguments to be passed.
Euphoria assumes {{{__stdcall}}}, but if you need to call a C routine
that uses {{{__cdecl}}}, you can put a '+' sign at the start of the
routine name in define_##c_proc## and ##define_c_func##. In the
example above, you would have "+LoadIconA", instead of "LoadIconA".

You can examine a ##dll## file by right-clicking on it, and choosing
"QuickView" (if it's on your system). You will see a list of all the C
routines that the ##dll## exports.

To find out which **.**dll file contains a particular //Windows// C function,
run **Euphoria\demo\win32\dsearch.exw**

==== Accessing C Variables

You can get the address of a C variable using [[:define_c_var]].
You can then use [[:poke]] and [[:peek]] to access the value of the variable.

==== Accessing C Structures

Many C routines require that you pass pointers to structures. You can
simulate C structures using allocated blocks of memory. The address
returned by [[:allocate]] can be passed as if it were a C pointer.

You can read and write members of C structures using [[:peek]] and [[:poke]], or
[[:peek4u]], [[:peek4s]], and [[:poke4]]. You can allocate space for
structures using [[:allocate]].\\
You must calculate the offset of a member of a C structure. This is usually
easy, because anything in C that needs 4 bytes will be assigned 4
bytes in the structure. Thus C int's, char's, unsigned int's, pointers to
anything, etc. will all take 4 bytes. If the C declaration looks like:

{{{
// Warning C code ahead!

struct example {
    int a;           // offset  0
    char *b;         // offset  4
    char c;          // offset  8
    long d;          // offset 12
};
}}}

To allocate space for "struct example" you would need:
<eucode>
atom p = allocate(16) -- size of "struct example"
</eucode>

The address that you get from [[:allocate]] is always at least 4-byte aligned.
This is useful, since //Windows// structures are supposed to start on a
4-byte boundary. Fields within a C structure that are 4-bytes or more in size
must start on a 4-byte boundary in memory. 2-byte fields must start on a
2-byte boundary. To achieve this you may have to leave small gaps within
the structure. In practice it is not hard to align most structures since
90% of the fields are 4-byte pointers or 4-byte integers.

You can set the fields using something like:
<eucode>
poke4(p + 0, a)
poke4(p + 4, b)
poke4(p + 8, c)
poke4(p +12, d)
</eucode>

You can read a field with something like:
<eucode>
d = peek4(p+12)
</eucode>

; Tip:
: For readability, make up Euphoria constants for the field offsets.
See Example below.

<eucode>
constant RECT_LEFT = 0,
RECT_TOP  = 4,
RECT_RIGHT = 8,
RECT_BOTTOM = 12,
RECT_SIZEOF = 16

atom rect = allocate(RECT_SIZEOF)

poke4(rect + RECT_LEFT,    10)
poke4(rect + RECT_TOP,     20)
poke4(rect + RECT_RIGHT,   90)
poke4(rect + RECT_BOTTOM, 100)

-- pass rect as a pointer to a C structure
-- hWnd is a "handle" to the window
if not c_func(InvalidateRect, {hWnd, rect, 1}) then
    puts(2, "InvalidateRect failed\n")
end if
</eucode>

The Euphoria code that accesses C routines and data structures
may look a bit ugly, but it will typically form just a small
part of your program, especially if you use Win32Lib,
EuWinGUI, or Irv Mullin's X Windows library.
Most of your program will be written in pure Euphoria,
which will give you a big advantage over those forced to code in C.

==== Call-backs to your Euphoria routines

When you create a window, the //Windows// operating system will need to call 
your Euphoria routine.  
To set this up, you must get a 32-bit "call-back"
address for your routine and give it to Windows. For example (taken from
**demo\win32\window.exw**):
<eucode>
integer id
atom WndProcAddress

id = routine_id("WndProc")

WndProcAddress = call_back(id)
</eucode>

[[:routine_id]] uniquely identifies a
Euphoria procedure or function by returning an integer value. This
value can be used later to call the routine. You can also use it as an
argument to the [[:call_back]] function.

In the example above, The 32-bit //call-back address//, ##WndProcAddress##,
can be stored in a C structure and passed to //Windows// via the
~RegisterClass() C API function.\\
**This gives //Windows// the ability to call the Euphoria routine, ~WndProc(),
whenever the user performs an action on a certain class of window.**
Actions include clicking the mouse, typing a key, resizing the window etc.\\
//See the **window.exw** demo program for the whole story.//

;Note:
: It is possible to get a //call-back address// for
**//any//** Euphoria routine that meets the following conditions:
* the routine must be a function, not a procedure
* it must have from 0 to 9 parameters
* the parameters should all be of type atom (or integer etc.),
not sequence
* the return value should be an integer value up to 32-bits in size

You can create as many call-back addresses as you like, but you should
not call [[:call_back]] for the same Euphoria routine multiple times -
each call-back address that you create requires a small block of memory.

The values that are passed to your Euphoria routine can be any 32-bit
##unsigned## atoms, i.e. non-negative. Your routine could
choose to interpret large positive numbers as negative if that is desirable.
For instance,
if a C routine tried to pass you -1, it would appear as hex FFFFFFFF.
If a value is passed that does not fit the type you have chosen for a
given parameter, a Euphoria type-check error may occur (depending on
[[:type_check]]) \\
No error will occur if you declare all parameters as ##atom##.

Normally, as in the case of ~WndProc() above, //Windows// initiates these
call-backs to your routines. **It is also
possible for a C routine in any .dll to call one of your Euphoria
routines.** You just have to declare the C routine properly,
and pass it the call-back address.

Here's an example of a WATCOM C routine that takes your call-back address as
its only parameter, and then calls your 3-parameter Euphoria routine:

{{{
/* 1-parameter C routine that you call from Euphoria */
unsigned EXPORT APIENTRY test1(
    LRESULT CALLBACK (*eu_callback)(unsigned a,
    unsigned b,
    unsigned c))
{
    /* Your 3-parameter Euphoria routine is called here
    via eu_callback pointer */
    return (*eu_callback)(111, 222, 333);
}
}}}

The C declaration above declares test1 as an externally-callable C
routine that takes a single parameter. The single parameter is a pointer
to a routine that takes 3 unsigned parameters - i.e. your Euphoria routine.

In WATCOM C, "CALLBACK" is the same as "{{{__stdcall}}}".
This is the calling convention that's used to call //Windows// API routines,
and the C pointer to your Euphoria routine should be declared this way too,
or you'll get an error when your Euphoria routine tries to return to
your .DLL.

If you need your Euphoria routine to be called using the {{{__cdecl}}}
convention, you must code the call to ##call_back## as:

<eucode>
myroutineaddr = call_back({'+', id})
</eucode>

The plus sign and braces indicate the {{{__cdecl}}} convention. The simple case,
with no braces, is {{{__stdcall}}}.

In the example above, your Euphoria routine will be passed the
three values 111, 222 and 333
as arguments. Your routine will return a value to test1. That value will then
be immediately returned to the caller of test1 (which could be at some
other place in your Euphoria program).

A call-back address can be passed to the UNIX signal()
function to specify a Euphoria routine to handle various signals (e.g. SIGTERM).
It can also be passed to C routines such as ##qsort##, to specify a Euphoria
comparison function.

!!CONTEXT:../docs/perform.txt
%%output = perform

== Performance Tips
:<<LEVELTOC level=2 depth=4>>

=== General Tips

* If your program is fast enough, forget about speeding it up.
   Just make it simple and readable.
* If your program is way too slow, the tips below will probably not solve
   your problem. You should find a better overall algorithm.
* The easiest way to gain a bit of speed is to turn off run-time
 type-checking. Insert the line:
<eucode>
without type_check
</eucode>
   at the top of your main ##.ex## file, ahead of any ##include## statements.
   You'll typically gain between 0 and 20 percent depending on the
   types you have defined, and the files that you are including.
   Most of the standard include files do some user-defined type-checking.
   A program that is completely without user-defined type-checking
   might still be speeded up slightly.
\\
   Also, be sure to remove, or comment-out, any
<eucode>
with trace
with profile
with profile_time
</eucode>
   statements. **with trace** (even without  any calls to [[:trace]]), and
   **with profile** can easily slow you down
   by 10% or more. **with profile_time**
   might slow you down by 1%. Each of these options will consume extra
   memory as well.
* Calculations using integer values are faster than calculations using
   floating-point numbers
* Declare variables as integer rather than atom where possible,
   and as sequence rather than object where possible. This usually gains
   you a few percent in speed.
* In an expression involving floating-point calculations, it's usually faster
   to write constant numbers in floating point form, e.g. when x has a
   floating-point value, say, x = 9.9\\\\
   change:
<eucode>
x = x * 5
</eucode>
   to:
<eucode>
x = x * 5.0
</eucode>
   This saves the interpreter from having to convert integer 5 to
   floating-point 5.0 each time.
* Euphoria does //short-circuit// evaluation of ##if##, ##elsif##, and
  ##while## conditions involving ##and## and ##or##. Euphoria will stop 
evaluating any condition once it determines if the condition is true or not.
  For instance in the //if-statement//:
<eucode>
if x > 20 and y = 0 then
    ...
end if
</eucode>
   The "y = 0" test will only be made when "x > 20" is true.
\\
   For maximum speed, you can order your tests. Do "x > 20" first if it is
   more likely to be false than "y = 0".
\\
   In general, with a condition "A and B", Euphoria will not evaluate the
   expression B, when A is false (zero). Similarly, with a condition like
   "A or B", B will not be evaluated when A is true (non-zero).
\\
   Simple if-statements are highly optimized.
   With the current version of the interpreter,
   nested simple if's that compare integers are usually a bit faster
   than a single short-circuit if-statement e.g.:
<eucode>
if x > 20 then
    if y = 0 then
       ...
    end if
end if
</eucode>
* The speed of access to private variables, local variables and global
   variables is the same.
* There is no performance penalty for defining constants versus plugging
   in hard-coded literal numbers. The speed of:
<eucode>
y = x * MAX
</eucode>
   is exactly the same as:
<eucode>
y = x * 1000
</eucode>
   where you've previously defined:
<eucode>
constant MAX = 1000
</eucode>
* There is no performance penalty for having lots of comments in your
   program. Comments are completely ignored. They are not executed in any way.
   It might take a few milliseconds longer for the initial load of your
   program, but that's a very small price to pay for future maintainability,
   and when you **bind** your program,
   or **translate** your program to C,
   all comments are stripped out, so the cost becomes absolute zero.

=== Measuring Performance

 In any programming language, and especially in Euphoria,
 **you really have to make measurements before
 drawing conclusions about performance**.

 Euphoria provides both **execution-count profiling**, as well as
 **time profiling**.
 You will often be surprised by the results of these profiles. Concentrate
 your efforts on the places in your program that are using a high percentage
 of the total time (or at least are executed a large number of times.)
 There's no point to rewriting a section of code that uses 0.01% of the total
 time. Usually there will be one place, or just a few places where code
 tweaking will make a significant difference.

 You can also measure the speed of code by using the [[:time]]() function. e.g.
<eucode>
atom t = time()
for i = 1 to 10000 do
    -- small chunk of code here
end for
? time() - t
</eucode>
 You might rewrite the small chunk of code in different ways to see which way
 is faster.

=== How to Speed-Up Loops

 **Profiling** will show you the //hot spots// in your program.
 These are usually inside loops. Look at each calculation inside the loop
 and ask yourself if it really needs to happen every time through the loop,
 or could it be done just once, prior to the loop.

=== Converting Multiplies to Adds in a Loop

 Addition is faster than multiplication. Sometimes you can replace a
 multiplication by the loop variable, with an addition. Something like:
<eucode>
for i = 0 to 199 do
    poke(screen_memory+i*320, 0)
end for
</eucode>
  becomes:
<eucode>
x = screen_memory
for i = 0 to 199 do
    poke(x, 0)
    x = x + 320
end for
</eucode>

=== Saving Results in Variables

* It's faster to save the result of a calculation in a variable, than it is to
   recalculate it later. Even something as simple as a subscript operation,
   or adding ##1## to a variable is worth saving.
* When you have a sequence with multiple levels of subscripting,
   it is faster to change code like:
<eucode>
for i = 1 to 1000 do
   y[a][i] = y[a][i]+1
end for
</eucode>
   to:
<eucode>
ya = y[a]
for i = 1 to 1000 do
    ya[i] = ya[i] + 1
end for
y[a] = ya
</eucode>
    So you are doing two subscript operations per iteration of the loop, rather
    than four. The operations, ##ya = y[a]## and ##y[a] = ya## are very cheap.
    **They just copy a pointer.** They don't copy a whole sequence.
* There is a slight cost when you create a new sequence using **{a,b,c}**.
   If possible, move this operation out of a critical loop by storing it
   in a variable before the loop, and referencing the variable inside the
   loop.

=== In-lining of Routine Calls
 If you have a routine that is rather small, the interpreter and translator
 will //in-line// it for you.  Your code will remain
 as readable as before.

=== Operations on Sequences
 Euphoria lets you operate on a large sequence of data using a single
 statement. This saves you from writing a loop where you process one element
 at-a-time. e.g.
<eucode>
x = {1,3,5,7,9}
y = {2,4,6,8,10}
z = x + y
</eucode>
 versus:
<eucode>
z = repeat(0, 5)  -- if necessary
for i = 1 to 5 do
    z[i] = x[i] + y[i]
end for
</eucode>

 In most interpreted languages, it is much faster to process a whole sequence
 (array) in one statement, than it is to perform scalar operations
 in a loop. This is because the interpreter has a large amount of overhead
 for each statement it executes.

 Euphoria is different. Euphoria is very lean, with little
 interpretive overhead, so operations on sequences don't always win.
 The only solution is to time it both ways. The per-element cost is usually
 lower when you process a sequence in one statement, but there are overheads
 associated with allocation and deallocation of sequences that
 may tip the scale the other way.

=== Some Special Case Optimizations

 Euphoria automatically optimizes certain special cases. ##x## and ##y##
 below could  be variables or arbitrary expressions.
<eucode>
x + 1      -- faster than general x + y
1 + x      -- faster than general y + x
x * 2      -- faster than general x * y
2 * x      -- faster than general y * x
x / 2      -- faster than general x / y
floor(x/y) -- where x and y are integers, is faster than x/y
floor(x/2) -- faster than floor(x/y)
</eucode>

 x below is a simple variable, y is any variable or expression:
<eucode>
x = append(x, y)   -- faster than general z = append(x, y)
x = prepend(x, y)  -- faster than general z = prepend(x, y)

x = x & y          -- where x is much larger than y,
                   -- is faster than general z = x & y
</eucode>

When you write a loop that "grows" a sequence, by appending or
concatenating data onto it, the time will, in general, grow in proportion
to the **square** of the number (N) of elements you are adding.
However, if you can use one of the special optimized forms of ##append##,
##prepend## or concatenation listed above, the time will grow in proportion
to just N (roughly). This could save you a **huge** amount of time
when creating an extremely long sequence. 


(You could also use ##repeat## to establish the maximum size
of the sequence, and then fill in the elements in a loop, as discussed
below.)

=== Assignment with Operators

For greater speed, convert:
{{{
**left-hand-side = left-hand-side op expression**
}}}
 to:
{{{
**left-hand-side op= expression**
}}}
For example:
<eucode>
-- Instead of ...
some_val = some_val * 3
-- Use ...
some_val *= 3
</eucode>

 whenever left-hand-side contains at least two subscripts, or at least
 one subscript and a slice. In all simpler cases the two forms run at
 the same speed (or very close to the same).

=== Library / Built-In Routines

 Some common routines are extremely fast. You probably couldn't do the job
 faster any other way, even if you used C or assembly language. Some of these
 are:
 
 ==== Low Level Memory Manipulation
* ##[[:mem_copy]]##
* ##[[:mem_set]]##

==== Sequence Manipulation
* ##[[:append]]##
* ##[[:head]]##
* ##[[:insert]]##
* ##[[:remove]]##
* ##[[:repeat]]##
* ##[[:replace]]##
* ##[[:splice]]##
* ##[[:tail]]##


 Other routines are reasonably fast, but you might be able
 to do the job faster in some cases if speed was crucial.
<eucode>
x = repeat(0,100) -- Pre-allocate all the elements first.
for i = 1 to 100 do
    x[i] = i
end for
</eucode>
 is somewhat faster than:
<eucode>
x = {}
for i = 1 to 100 do
    x = append(x, i)
end for
</eucode>
 because ##append## has to allocate and reallocate
 space as ##x## grows in size. With ##repeat##(), the
 space for ##x## is allocated once at the beginning. (##append## is smart enough
 not to allocate space with //every// append to ##x##.
 It will allocate somewhat more than it needs, to reduce the number of
 reallocations.)

These built-in operations are also optimize to make changes in place (where possible), 
rather than creating copies of sequences via slices.

==== Bitwise operations vs Arithmetic
 You can replace:
<eucode>
remainder(x, p)
</eucode>
 with:
<eucode>
and_bits(x, p-1)
</eucode>
 for greater speed when ##p## is a positive power of 2. ##x## must be a 
non-negative  integer that fits in 32-bits.

 [[:arctan]] is faster than [[:arccos]] or [[:arcsin]].

=== Searching

 Euphoria's [[:find]] is the fastest way to search for a value in a
 sequence up to about 50 elements. Beyond that, you might consider a 
 [[:map]] or other implementation of a //hash table//
 (**demo\hash.ex**) or a //binary tree// (**demo\tree.ex**).

=== Sorting

 In most cases you can just use the //shell sort// routine in ##sort.e##.

 If you have a huge amount of data to sort, you might try one of the sorts
 in **demo\allsorts.e** (e.g.
 //great sort//). If your data is too big to fit in
 memory, don't rely on Euphoria's automatic memory swapping capability.
 Instead, sort a few thousand records at a time, and write them out to a
 series of temporary files. Then merge all the sorted temporary files into
 one big sorted file.

 If your data consists of integers only, and they are all in a fairly
 narrow range, try the //bucket sort// in **demo\allsorts.e**.

=== Taking Advantage of Cache Memory

As CPU speeds increase, the gap between the speed of the on-chip cache
memory and the speed of the main memory or DRAM (dynamic random access memory)
becomes ever greater. You might have 256 Mb of DRAM on your computer, but the
on-chip cache is likely to be only 8K (data) plus 8K (instructions) on a
Pentium, or 16K (data) plus 16K (instructions) on a Pentium with MMX or a
Pentium II/III. Most machines will also have a "level-2" cache of 256K or 512K.

An algorithm that steps through a long sequence of a couple of thousand
elements or more, many times, from beginning to end, performing one
small operation on each element, will not make good use of the on-chip data
cache. It might be better to go through once, applying several operations to
each element, before moving on to the next element. The same argument holds
when your program starts swapping, and the least-recently-used data is moved
out to disk.

These cache effects aren't as noticeable in Euphoria as they are in
lower-level compiled languages, but they are measurable.

=== Using Machine Code and C

Euphoria lets you call routines written in machine code. You can call C 
routines in dynamically loaded library files, and these C routines can call 
your Euphoria routines.
You might need to call C or machine code because of something that can not be
done directly in Euphoria, or you might do it for improved speed.

To boost speed, the machine code or C routine needs to do a significant
amount of work on each call, otherwise the overhead of setting up the
arguments and making the call will dominate the time, and it might not
gain you much.

Many programs have some inner core operation that consumes most of the
CPU time. If you can code this in C or machine code, while leaving the
bulk of the program in Euphoria, you might achieve a speed comparable
to C, without sacrificing Euphoria's safety and flexibility.

=== Using The Euphoria To C Translator

The Euphoria To C Translator is included in the installation package.
It will translate any Euphoria program into a set of C source files that you
can compile using a C compiler.

The executable file that you get using the Translator should run the same,
but faster than when you use the interpreter. The speed-up can be anywhere
from a few percent to a factor of 5 or more.
%%output=tools
= Included Tools
<<LEVELTOC level=1 depth=2>>

!!CONTEXT:../docs/eutest.txt
%%output = eutest

== eutest Unit Testing

<<LEVELTOC level=2 depth=4>>

=== Introduction

The testing system gives you the ability to check if the library,
interpreter and translator works properly by use of //unit tests//.  The
unit tests are Euphoria //include// files that ##include unittest.e##
at the top, several test-routines for comparison between expected value
and true value and at the end of the program a call to
##test_report##.  There are error control files for when we expect
the interpreter to fail but we want it to fail with a particular error
message. You may use this section as an outline for testing your own code.

=== eutest Tool

==== Synopsis, Running Tests 

{{{
eutest [-D NO_INET ] [-D NO_INET_TESTS ]
    [-verbose] [-log] [-i include path] [-cc wat|gcc] [-exe interpreter]
    [-ec translator] [-lib binary library path]
    [optional list of unit test files]
}}}

==== Synopsis, Report From Log

{{{
eutest -process-log [-html]
}}}

==== General Behavior

If you want to test translation of your tests as well as interpreted tests, you
can specify it with ##-ec##.

If you don't specify unit tests on the command line eutest
will scan the directory for unit test files using the pattern
##t_*.e##.  If you specify a pattern it will interpret the pattern, as
some shells do not do this for programs.

==== Options Detail

* -D REC: Is for creating control files, use only when on tests that
work already on an interpreter that correctly works or correctly *fails*
 with them.  This option must come before the ##eutest.ex## program
itself in the command line and is the option with that requirement.
* -log: Is for creating a log file for later processing
* -verbose: Is for ##eutest.ex## to give you detail of what it is doing
* -i: is for specify the include path which will be passed to both the
  interpreter and the translator when interpreting and translating the
  test.
* -cc: is for specifying the compiler.  This can be any one of -wat,
  djg, or gcc.  Each of these represent the kind of compiler we will
  request the translator to use.
* -process-log: Is for processing a log created by a previous
invocation of ##eutest.ex## output is sent to standard output as a report
of how the tests went.  By default this is in ASCII format.  Use -html
to make it HTML format.
* -html: Is for making the report creation to be in HTML format
* -D NO_INET: This is for keeping tests from trying to use the Internet.  The
tests have to be written to support them by using ifdef/end ifdef statements.
Since in some Euphoria unit tests "-D NO_INET_TESTS" is used
in its place, you must use both options to prevent them from trying to connect 
through the Internet.
* -D NO_INET_TESTS: See NO_INET

=== The Unit Test Files

Unit test files must match a pattern ##t_*.e##.  If the unit test file
matches ##t_c_*.e## the test program will expect the program to fail,
if there is an error control file in a directory with its same name and
'd' extension it will also expect it to fail according to the control
file's contents found in the said directory.  Such a failure is marked as
a successful test run.  However, if there is no such 
directory or file the counter test will be marked as a failed test run.

==== Trivial Example

The following is a minimal unit test file~:
{{{
include std/unittest.e

test_report()
}}}

Please see the [[:Unit Testing Framework]], for information on how to
construct these files.


=== The Error Control Files

There are times when we expect something to fail.  We want good
EUPHORIA code to do the correct thing and there is a correct thing to
do also for *bad* code.  The interpreter must return with an error message
of why it failed and the error must be correct and it must get written to 
##ex.err##.
We must thus check the ex.err file to see if it has
the correct error message.

If the unit test is ##t_foo.e## then the location for its control file
can be in the following locations:

* ##t_foo.d/interpreter///OSNAME///control.err##
* ##t_foo.d///OSNAME///control.err##
* ##t_foo.d/control.err##

The //OSNAME// is the name of the operating system.  Which is either
UNIX or Win32.

Now, if ##t_foo.d/Win32/control.err## exists, then the testing program
eutest.ex expects t_foo.e to fail when run with the //Windows// interpreter.
However, this is not necessarily true for other platforms.  In //Windows//
eutest runs it, watches it fail, then compares the ex.err file to
##t_foo.d/Win32/control.err##.  If they ex.err is different from
control.err an error message is written to the log.  Now on, say NetBSD,
t_file.e is tested with the expectation it will return 0 and the tests
will all pass unless ##t_foo.d/UNIX/control.err## or ##t_foo.d/control.err## 
also exist.
Thus you can have different expectations for differing platforms.
Some feature that is not possible to implement under //Windows// can be put into a 
unit test and the
resulting ##ex.err## file can be put into a control file for //Windows//.
This means we do not need to have all of these errors that we expect to get
drawing our attention away from errors that need our attention.
On the other hand, if an unexpected error message not like 
##t_foo.d/Win32/control.err##
gets generated in the //Windows// case then ##eutest## will tell us that.

How do we construct these control files?  You don't really need to, you
can take an ##ex.err## file that results from running a stable interpreter
on a test and rename it and move it to the appropriate place.


=== Test Coverage

When writing and evaluating the results of unit tests, it is important to 
understand which parts of your code are and are not being tested.  The Euphoria 
interpreter has a  built in capability to instrument your code to analyze how 
many times each line of your code is executed during your suite of tests.  The 
data is output into an EDS database.  Euphoria also comes with a coverage data 
post-processor that generates html reports to make 
analysis of your coverage easy.

The coverage capabilities can be used manually, with arguments supplied on the 
command line, or passed to ##eutest##.  Indeed, ##eutest## simply passes these along to 
the interpreter.  The Euphoria suite of unit tests can be run via the makefiles, 
and there is a special target to run a coverage analysis of the standard 
library:

{{{
Windows:
> wmake coverage

Unix:
$ make coverage
}}}

Then, in your build directory, ##eutest## will run the tests to create the coverage 
database ##unit-test.edb##, and will post-process the results, placing the HTML 
reports into a unit-test subdirectory from your build directory.

==== Coverage Command Line Switches

* ##-coverage [file|dir]## This specifies what files to gather stats for.  If 
you supply a directory, it recurses on child directories.  Only files that are 
obviously Euphoria are
included ( ##.e, .ew, .eu, .ex, .exw, .exu##).

* ##-coverage-db <file>## This one allows you to specify a specific location and
name for the database where coverage information is stored.  It is an EDS 
database. By default, the DB is ##eui-cvg.edb##.

* ##-coverage-erase##  Tells the interpreter to start over.  By default, 
multiple runs accumulate coverage in the DB to allow coverage analysis based on 
a suite of unit test files.

* ##-coverage-exclude <pattern>##  Specifies a regular expression that is used to
exclude files from coverage analysis.

* ##-coverage-pp <post-processor>##  Supported by ##eutest## only (i.e., not the 
interpreter itself). Tells ##eutest## how to post process the coverage data.  
##<post-processor>## must be the path to a the post processing application.  
After running the suite of tests, ##eutest## will execute this program with the 
path to the coverage db as an argument.


==== Coverage Post-Processing

Once you have run tests to generate a coverage database, the data is not easily 
viewed. Euphoria comes with a post-processor called ##eucoverage.ex##, which is 
installed in the bin directory. On a //Unix// packaged install, you should be 
able to simply use ##eucoverage##, which is configured to run ##eucoverage.ex##.

The post-processor generates an index page, with coverage stats for each file, 
and individual html files, linked from the index page, for each file analyzed 
for test coverage.  At the file level, statistics are presented for total and 
executed routines and lines of code.  The files are sorted in descending order 
of lines that were never executed, in order to highlight the parts of your code 
that are less tested.  The page for each file shows this information, as well as
a similar breakdown by routine, displaying the number of lines in each routine
that was executed.  The routines are also sorted in descending order by the
most unexecuted lines.  

Additionally, the source of the file is displayed below the statistics.  The 
routines are linked to their place in the code. Each line is colored either 
green red or white.  White lines are those that are not executed.  These are 
typically
blank, comments, declarations or "end" clauses of code blocks that do not 
create any executable code.  Red lines are those that were never executed, and
lines that were executed are colored green.  The line number is displayed in the
left margin, and the number of times each line was executed is displayed just
to the left of where the source code begins.

===== Command Line Switches

* ##-o <dir>## Specify the output directory.  The default is to create a 
subdirectory, from the same directory as the coverage database, with the name of
the base filename (without extension) of the coverage database.

* ##-v## Verbose output



!!CONTEXT:../docs/eudoc.txt
%%output = eudoc


== EuDOC Source Documentation Tool
:<<LEVELTOC level=2 depth=4>>

Writing and managing documentation for your programs is made 
easier with the **##eudoc##** tool. ##eudoc##, written entirely in Euphoria, 
converts text comments embedded in your program, as well as information
about routines and identifiers, into documentation
that can be saved in a variety of formats, including plain text and HTML.

Since Euphoria comments do not slow down the 
execution of programs, documentation written inside source-code 
introduces no speed penalty but is very convenient.

##eudoc## can also incorporate documentation written externally from 
your source-code.

You write your material using //Creole// style markup to format documention.
This gives you creative control using elements like headers, fonts, 
cross-references, tables, etc. The **##creole##** program takes the
output  of ##eudoc## and produces HTML-formatted documentation.

A third party program like ##htmldoc## or ##wkhtmltopdf## may then be used to 
convert HTML to PDF. ##creole## will also output LaTeX files directly
that can be used to create professional PDF files for online viewing or
publishing.

=== Documentation Tags

Documentation is embedded in source-code using the Euphoria line 
//(// **--** //)// comments. Two special tags, {{{--**** }}} and 
{{{ --** }}} distinguish documentation from comments that will not be 
extracted.

=== Generic Documentation

"Generic" documentation starts with the //(// {{{ --**** }}} //)// tag, 
continues with lines starting with {{{ -- }}} in the first column, and 
ends with the next blank line. The tags and {{{--}}} will not appear in 
the documentation.

<eucode>
--****
-- generic text, thus tagged, will be extracted by eudoc
-- write your documentation here...
--

-- blank line is a terminator, this line is not included
</eucode> 
 
Produces...

{{{
generic text, thus tagged, will be extracted by eudoc
write your documentation here...

}}} 
 
 
=== Source Documentation 
 
"Source" documentation starts with the //(// {{{--**}}} //)// tag. 
Locate them before a routine or identifier that you wish to be described
in your documentation. The ##eudoc## program will extract the 
"signature" of a routine and combines it with the comments that you 
write after this tag. 

Starting with the source-code file ##favorite.ex##:

<eucode>
--**
-- this is my favorite routine

public procedure hello( sequence name )
   printf(1, "Hello %s!", {name} )
end procedure
</eucode>

Executing ##eui eudoc -o foo.txt favorite.ex## produces:

{{{
%%disallow={camelcase}

!!CONTEXT:favorite.ex

@[hello|]
==== hello
<eucode>
include favorite.ex
public procedure hello(sequence name)
</eucode>

  This is my favorite routine.
}}}

Process with ##eui creole foo.txt##:

<eucode>
include favorite.ex
public procedure hello(sequence name)
</eucode>

  This is my favorite routine.

If you examine the source-code included with Euphoria you will realize
how these steps were used to create the documentation you are reading 
now. 

=== Assembly File

Large projects are managed using an **assembly file**, which is a list 
of files (source-code, and external) that will be incorporated into one 
output file. Look at ##euphoria/docs/manual.af## for the file used to 
produce this documentation.

=== Creole Markup

Creole is a text markup language used in wikis, such as the 
[[http://openeuphoria.org/wiki/view/home.wc|Euphoria Wiki]], 
and for documenting source-code. 

* Common Creole tags are:

{{{
= Title

== Section

//italic// **bold** ##fixed##

* bullet
* lists are
* easy to produce


||  tables || are |
| easy to produce |  //with bold headers// |

<eucode>
-- euphoria code is colorized
for i=1 to 5 do	 
   ? i
end for
</eucode>
}}}

* The previous tags will produce html that looks like...

** Title ** \\
** Section ** 

//italic// **bold** ##fixed##

* bullet
* lists are
* easy to produce


||  tables        || are                   |
| easy to produce |  //with bold headers// |

<eucode>
-- euphoria code is colorized
for i=1 to 5 do	 
   ? i
end for
</eucode>

* More details can be found at the Euphoria Wiki under [[wiki:CreoleHelp|CreoleHelp]].

=== Documentation Software

The programs required for creating documentation are hosted on our
Mercurial SCM server at [[http://scm.openeuphoria.org]].

eudoc: http://scm.openeuphoria.org/hg/eudoc

creole: http://scm.openeuphoria.org/hg/creole

[[wiki:Documenting40|More on using eudoc]]

[[wiki:CreoleHelp|More on using Creole markup]]

The program htmldoc is found at... http://www.htmldoc.org/ and http://htmldoc-binaries.org/.

For LaTeX on Windows, we suggest MiKTeX found at... http://miktex.org/
For those on Linux, you should be able to install via your package
manager.

!!CONTEXT:../docs/edx.txt
%%output = edx

== Edx Demonstration Code Editor
:<<LEVELTOC level=2 depth=4>>

=== Introduction

The Euphoria includes a handy, text-mode editor, **##edx##**  
that is written completely in Euphoria. 

While ##edx## is intended as a demonstration program, many people find ##edx## convenient for 
editing and examinng small programs.

=== Summary

Usage:

# ##edx filename##
# ##edx##

After any error, just type ##edx## and
you will be placed in the editor at the line and column where the error was
detected. The error message will be at the top of your screen.

Euphoria related files are displayed in color. Other text files are in mono.
You will know that you have misspelled something when the color does not change
as you expect. Keywords are blue. Names of routines that are built in to the
interpreter appear in magenta. Strings are green, comments are red, most other
text is black. Balanced brackets (on the same line) have the same color. You
can change these colors as well as several other parameters of **edx**. See
//user-modifiable parameters// near the top of ##edx.ex##.

The arrow keys move the cursor left, right, up or down. Most other characters
are immediately inserted into the file.

In Windows, you can //associate// various types of files with ##edx.bat##. You
will then be put into **edx** when you //double-click// on these types of files
~-- such as. ##.e, .pro, .doc## etc.  Main Euphoria files ending in ##.ex##, ##.exd##
or ##.exw## might better be associated with ##eui.exe##, ##euid.exe##, or
##euiw.exe##, respectively.

**edx** is a multi-file and multi-window text-based editor. //Esc c// will split your
screen so you can view and edit up to ten files simultaneously, with cutting and
pasting between them. You can also use multiple edit windows to view and edit
different parts of a single file.

=== Special Keys

Some PC keys do not work in a Linux or FreeBSD or Windows text console, or in 
Telnet, and
some keys do not work in an xterm under X windows. Alternate keys have been
provided. In some cases you might have to edit ##edx.ex## to map
the desired key to the desired function.  For example you may have to use
//C-t// and //C-b// instead of //C-Home// and //C-End//.

| Delete    | Delete the current character above the cursor |
| Backspace | Move the cursor to the left and delete a character |
| C-Delete  | Delete the current line (not available on all platforms) |
| C-d       | Delete the current line (same as C-Delete) |
| Insert    | re-insert the preceding series of Deletes before the current line/character |
| C-Left    | Move to the start of the previous word. On //Unix// use C-l |
| C-Right   | Move to the start of the next word. On //Unix// use C-r |
| Home      | Move to the beginning of the current line |
| End       | Move to the end of the current line |
| C-Home    | Move to the beginning of the file (euid.exe only, others use C-t |
| C-End     | Move to the end of the file (euid.exe only, others use C-b |
| PgUp      | Move up one screen. On //Unix// use C-u |
| PgDn      | Move down one screen. On //Unix// use C-p |
| F1..F10   | Select a new window. The windows are numbered from top to bottom with the top window on the screen being //F1// |
| F12       | User definable key (see ##CUSTOM_KEYSTROKES## near top of ##ed.ex##. Default action is to insert ##--## for a Euphoria comment |

=== Escape Commands

Press and release the //Esc// key, then press one of the following keys:

| h | Get help text for the editor, or Euphoria. The screen is split so you
      can view your program and the help text at the same time. |
| c | "Clone" the current window, i.e. make a new edit window that is initially
      viewing the same file at the same position as the current window. The
      sizes of all windows are adjusted to make room for the new window. You
      might want to use **Esc l** to get more lines on the screen. Each window
      that you create can be scrolled independently and each has its own menu
      bar. The changes that you make to a file will initially appear only in
      the current window. When you press an **F-key** to select a new window,
      any changes will appear there as well. You can use **Esc n** to read a
      new file into any window. |
| q | Quit (delete) the current window and leave the editor if there are no
      more windows. You'll be warned if this is the last window used for
      editing a modified file. Any remaining windows are given more space. |
| s | Save the file being edited in the current window, then quit the current
      window as **Esc q** above. |
| w | Save the file but do not quit the window. |
| e | Save the file, and then execute it with ##euid##, ##euiw## or ##eui##.
      When the program finishes execution you'll hear a beep. Hit //Enter// to
      return to the editor. This operation may not work if you are very low on
      extended memory. You can't supply any command-line arguments to the
      program. |
| d | Run an operating system command. After the beep, hit //Enter// to return
      to the editor. You could also use this command to edit another file and
      then return, but //Esc c// is probably more convenient. |
| n | Start editing a new file in the current window. Deleted lines/chars and
      search strings are available for use in the new file. You must type in
      the path to the new file. Alternatively, you can drag a file name from a
      Windows file manager window into the console window for ##edx##. This
      will type the full path for you. |
| f | Find the next occurrence of a string in the current window. When you type
      in a new string there is an option to "match case" or not. Press //y//
      if you require upper/lower case to match. Keep hitting //Enter// to find
      subsequent occurrences. Any other key stops the search. To search from
      the beginning, press //C-Home// before //Esc f//. The default string to
      search for, if you don't type anything, is shown in double quotes. |
| r | Globally replace one string by another. Operates like //Esc f// command.
      Keep hitting //Enter// to continue replacing. Be careful - //there is no
      way to skip over a possible replacement.// |
| l | Change the number of lines displayed on the screen. Only certain values
      are allowed, depending on your video card. Many cards will allow 25, 28,
      43 and 50 lines. In a //Unix// text console you're stuck with the
      number of lines available (usually 25). In a //Unix// terminal xterm window,
      ##edx## will use the number of lines initially available when ##edx## is
      started up. Changing the size of the window will have no effect after
      ##edx## is started. |
| m | Show the modifications that you've made so far. The current edit buffer
      is saved as ##editbuff.tmp##, and is compared with the file on disk
      using the Windows ##fc## command, or the Linux/FreeBSD ##diff## command.
      //Esc m// is very useful when you want to quit the editor, but you can't
      remember what changes you made, or whether it's ok to save them. It's
      also useful when you make an editing mistake and you want to see what the
      original text looked like. |
| //ddd// | Move to line number //ddd//. e.g. //Esc 1023 Enter// would move to
            line 1023 in the file.
| CR | //Esc Carriage-Return//, i.e. //Esc Enter//, will tell you the name of
       the current file, as well as the line and character position you are on,
       and whether the file has been modified since the last save. If you
       press //Esc// and then change your mind, it is harmless to just hit
       //Enter// so you can go back to editing. |

=== Recalling Previous Strings

The //Esc n//, //Esc d//, //Esc r// and //Esc f// commands prompt you to enter
a string. You can recall and edit these strings just as you would at the
 command line. Type up-arrow or down-arrow to cycle through
strings that you previously entered for a given command, then use left-arrow,
right-arrow and the delete key to edit the strings. Press Enter to submit the
string.

=== Cutting and Pasting

When you //C-Delete// (or //C-d//) a series of consecutive lines, or //Delete//
a series of consecutive characters, you create a "kill-buffer" containing what
you just deleted. This kill-buffer can be re-inserted by moving the cursor and
then pressing //Insert//.

A new kill-buffer is started, and the old buffer is lost, each time you move
away and start deleting somewhere else. For example, cut a series of //lines//
with //C-Delete//. Then move the cursor to where you want to paste the lines and
press //Insert//. If you want to copy the lines, without destroying the original
text, first //C-Delete// them, then immediately press //Insert// to re-insert 
them.
Then move somewhere else and press //Insert// to insert them again, as many 
times as
you like. You can also //Delete// a series of individual //characters//, move 
the
cursor, and then paste the deleted characters somewhere else. Immediately
press //Insert// after deleting if you want to copy without removing the 
original characters.

Once you have a kill-buffer, you can type //Esc n// to read in a new file, or 
you can
press an //F-key// to select a new edit window. You can then insert your 
kill-buffer.

=== Using Tabs

The standard //tab// width is 8 spaces. The editor assumes tab=8 for most
files. However, it is more convenient when editing a program for a tab to equal
the amount of space that you like to indent.  Therefore you will find that tabs
are set to four when you edit Euphoria files (or .c, or .h or .bas files). The
editor converts from tab=8 to tab=4 when reading your //program// file, and
converts back to tab=8 when you save the file. Thus your file remains
compatible with the tab=8 world.

If you would like to choose a different number of spaces to indent, change the line at the
top of ##edx.ex## that says "##constant PROG_INDENT = 4##".

=== Long Lines

Lines that extend beyond the right edge of the screen are marked with an
 //inverse video// character in the 80th column. This warns you that
 there is more text "out there" that you can not see. You can move the cursor
beyond the 80th column. The screen will scroll left or right so the cursor
position is always visible.

=== Maximum File Size

Like any Euphoria program, ##edx## can access all the memory on your machine.
It can edit huge files, and unless disk swapping occurs, most operations will
be very fast.

=== Non-text Files

##edx## is designed for editing pure text files, although you can use it to
view other files. As ##edx## reads in a file, it replaces certain non-printable
characters (less than ASCII 14) with ASCII 254 ~-- a small square. //If you try to
save a non-text file you will be warned about this.// Since ##edx## opens all
files as "text" files, a //control-z// character (26) embedded in a file will
appear to ##edx## to be the //end of the file//.

=== Line Terminator

The end-of-line terminator on //Unix//is simply ##\n##. On //Windows// text files have lines ending with ##\r\n##.
If you copy a //Windows// file to //Unix//  and try to modify it, **edx** will 
give you a
choice of either keeping the ##\r\n## terminators, or saving the file with
##\n## terminators.

=== Source-Code

The complete source code to this editor is in ##bin\edx.ex## and 
##bin\syncolor.e## .
You are welcome to make improvements. There is a section at the top of ##edx.ex##
containing //user-modifiable// configuration parameters that you can adjust. The
colors and the cursor size may need adjusting for some operating environments.



!!CONTEXT:../docs/dis.txt
%%output = dis

== EuDis, Disassembling Euphoria Code

<<LEVELTOC level=2 depth=3>>

=== Introduction

In the Euphoria source directory is a program named ##dis.ex##, which can be
used for parsing Euphoria code and outputting detailed disassembly
of the intermediate language (i.e., byte code) used by Euphoria, as well
as the symbol table.  The purpose of this tool is for low level debugging,
especially for developing Euphoria itself, or for understanding why 
certain code performs the way it does.

It uses the actual Euphoria front end to parse your code.  When Euphoria
is installed, there should be a shell script or batch file (depending on
your operating system) called ##eudis## or ##eudis.bat##, respectively, that can
be used to analyze your code:

{{{
$ eudis myapp.ex
saved to [/path/to/myapp.ex.dis]
}}}

When run, ##eudis## will say where its output was saved.  The file name, 
including extension, is used as the base for its output.  By default,
it outputs four files:

* ##.dis## The main disassembly file.  This shows the IL code representation
  both raw and symbolically.
* ##.sym## The symbol table.  This shows details for the entire symbol table
  for your code.
* ##.hash## Details about symbol hashing.
* ##.line## Line table information.  Unless tracing is enabled, this will be
  blank.
* ##.fwd## Counts, by name, of the number of forward references by symbol,
  along with the number of references by file.

=== HTML Output

##eudis## can output html documentation of your program somewhat similar to the
output from Doxygen.  This documentation is different than ##eudoc##.  It is 
meant to document the structure of your program, and to help developers 
understand code dependencies.  It can generate graphs showing how files include 
each other, as well as which routines call which others.  Note that generating 
graphs requires that you have [[http://www.graphviz.org|Graphviz]] installed.  
Note that generating call graphs can be quite time consuming for a large 
program.

By default, ##eudis## will create a subdirectory in the current directory called
##eudox##.  This may be changed using the ##--dir## option.

==== Command Line Switches

You can use the standard ##-i## and ##-c## switches with ##eudis##.  There are 
additional options:

* ##-b## parse the code as though it were being bound
* ##--dir <dir>## Specify the output directory for the html files
* ##-f## include a particular file in the html output
* ##--file-list## output the list of files included in the ##.dis## file at the 
top of the listing
* ##-g## suppress call graphs in html output
* ##--html## generate html documentation of your program
* ##--no-dep## Suppress dependencies.  Will not generate file and routine 
dependency graphs.
* ##--std## show standard library information, by default this is not shown
* ##-t## parse the code as though it were being translated

!!CONTEXT:../docs/eudist.txt
%%output = eudist

== EuDist, Distributing Programs

<<LEVELTOC level=2 depth=4>>

=== Introduction

EuDist is a tool that makes distributing your program easier.
It is designed to gather all of the Euphoria files that your program
uses and put them into a directory.  This can also be useful for
sending example code for bug reports.

=== Command Line Switches

You can use the standard ##-i## and ##-c## switches with ##eudist##.  There are 
additional options:

* ##~--clear## Clear the output directory before copying files
* ##-d <dir>## Specify the output directory for the files
* ##-e <file>## ##~--exclude-file <file>## Exclude a file from being copied
* ##-ed <dir>## ##~--exclude-directory <file>## Exclude a directory from being copied
* ##-edr <dir>## ##~--exclude-directory-recursively <file>## Exclude a directory
and all subdirectories from being copied
%%output=apiref
= API Reference
<<LEVELTOC level=1 depth=2>>

!!CONTEXT:../docs/builtins.txt
%%output = builtins

== Built-in Routines

These **built-in** routines do not require an include file~:

| ##[[? -> :q_print]]## | ##[[:abort]]## | ##[[:and_bits]]## | ##[[:append]]## |
| ##[[:arctan]]## | ##[[:atom]]## | ##[[:c_func]]## | ##[[:c_proc]]## |
| ##[[:call]]## | ##[[:call_func]]## | ##[[:call_proc]]## | ##[[:clear_screen]]## |
| ##[[:close]]## | ##[[:command_line]]## | ##[[:compare]]## | ##[[:cos]]## |
| ##[[:date]]## | ##[[:delete]]## | ##[[:delete_routine]]## | ##[[:equal]]## |
| ##[[:find]]## | ##[[:floor]]## | ##[[:get_key]]## | ##[[:getc]]## |
| ##[[:getenv]]## | ##[[:gets]]## | ##[[:hash]]## | ##[[:head]]## |
| ##[[:include_paths]]## | ##[[:insert]]## | ##[[:integer]]## | ##[[:length]]## |
| ##[[:log]]## | ##[[:machine_func]]## | ##[[:machine_proc]]## | ##[[:match]]## |
| ##[[:mem_copy]]## | ##[[:mem_set]]## | ##[[:not_bits]]## | ##[[:object]]## |
| ##[[:open]]## | ##[[:option_switches]]## | ##[[:or_bits]]## | ##[[:peek]]## |
| ##[[:peek2s]]## | ##[[:peek2u]]## | ##[[:peek4s]]## | ##[[:peek4u]]## |
| ##[[:peek8s]]## | ##[[:peek8u]]## | ##[[:peek_longs]]## | ##[[:peek_longu]]## |
| ##[[:peek_pointer]]## | ##[[:peeks]]## | ##[[:peek_string]]## | ##[[:pixel]]## |
| ##[[:platform]]## | ##[[:poke]]## | ##[[:poke2]]## | ##[[:poke4]]## |
| ##[[:poke8]]## | ##[[:poke_long]]## | ##[[:poke_pointer]]## | ##[[:position]]## |
| ##[[:power]]## | ##[[:prepend]]## | ##[[:print]]## | ##[[:printf]]## |
| ##[[:puts]]## | ##[[:rand]]## | ##[[:remainder]]## | ##[[:remove]]## |
| ##[[:repeat]]## | ##[[:replace]]## | ##[[:routine_id]]## | ##[[:sequence]]## |
| ##[[:sin]]## | ##[[:splice]]## | ##[[:sprintf]]## | ##[[:sqrt]]## |
| ##[[:system]]## | ##[[:system_exec]]## | ##[[:tail]]## | ##[[:tan]]## |
| ##[[:task_clock_start]]## | ##[[:task_clock_stop]]## | ##[[:task_create]]## | ##[[:task_list]]## |
| ##[[:task_schedule]]## | ##[[:task_self]]## | ##[[:task_status]]## | ##[[:task_suspend]]## |
| ##[[:task_yield]]## | ##[[:time]]## | ##[[:trace]]## | ##[[:xor_bits]]## |

A built-in routine has global scope and belongs to the ##eu## namespace. 

An identifier for a built-in is not reserved; it is possible to override a built-in
identifier with a new declaration.

!!CONTEXT:../include/std/cmdline.e
!!namespace:cmdline
%%output = std_cmdline

== Command Line Handling

<<LEVELTOC level=2 depth=4>>



=== Constants


@[:cmdline:NO_PARAMETER|]
==== NO_PARAMETER
<eucode>
include std/cmdline.e
namespace cmdline
public constant NO_PARAMETER
</eucode>

 This option switch does not have a parameter. See [[:cmd_parse]]



@[:cmdline:HAS_PARAMETER|]
==== HAS_PARAMETER
<eucode>
include std/cmdline.e
namespace cmdline
public constant HAS_PARAMETER
</eucode>

 This option switch does have a parameter. See [[:cmd_parse]]



@[:cmdline:NO_CASE|]
==== NO_CASE
<eucode>
include std/cmdline.e
namespace cmdline
public constant NO_CASE
</eucode>

 This option switch is not case sensitive. See [[:cmd_parse]]



@[:cmdline:HAS_CASE|]
==== HAS_CASE
<eucode>
include std/cmdline.e
namespace cmdline
public constant HAS_CASE
</eucode>

 This option switch is case sensitive. See [[:cmd_parse]]



@[:cmdline:MANDATORY|]
==== MANDATORY
<eucode>
include std/cmdline.e
namespace cmdline
public constant MANDATORY
</eucode>

 This option switch must be supplied on command line. See [[:cmd_parse]]



@[:cmdline:OPTIONAL|]
==== OPTIONAL
<eucode>
include std/cmdline.e
namespace cmdline
public constant OPTIONAL
</eucode>

 This option switch does not have to be on command line. See [[:cmd_parse]]



@[:cmdline:ONCE|]
==== ONCE
<eucode>
include std/cmdline.e
namespace cmdline
public constant ONCE
</eucode>

 This option switch must only occur once on the command line. See [[:cmd_parse]]



@[:cmdline:MULTIPLE|]
==== MULTIPLE
<eucode>
include std/cmdline.e
namespace cmdline
public constant MULTIPLE
</eucode>

 This option switch may occur multiple times on a command line. See [[:cmd_parse]]



@[:cmdline:HELP|]
==== HELP
<eucode>
include std/cmdline.e
namespace cmdline
public constant HELP
</eucode>

 This option switch triggers the 'help' display. See [[:cmd_parse]]




@[:cmdline:HEADER|]
==== HEADER
<eucode>
include std/cmdline.e
namespace cmdline
public constant HEADER
</eucode>

 This option switch is simply a help display header to group like options together.
See [[:cmd_parse]]




@[:cmdline:VERSIONING|]
==== VERSIONING
<eucode>
include std/cmdline.e
namespace cmdline
public constant VERSIONING
</eucode>

 This option switch sets the program version information. If this option
is chosen by the user ##cmd_parse## will display the program version information
and then end the program with a zero error code.




@[:cmdline:HELP_RID|]
==== HELP_RID
<eucode>
include std/cmdline.e
namespace cmdline
public enum HELP_RID
</eucode>

Additional help routine id. See [[:cmd_parse]]




@[:cmdline:VALIDATE_ALL|]
==== VALIDATE_ALL
<eucode>
include std/cmdline.e
namespace cmdline
public enum VALIDATE_ALL
</eucode>

Validate all parameters (default). See [[:cmd_parse]]




@[:cmdline:NO_VALIDATION|]
==== NO_VALIDATION
<eucode>
include std/cmdline.e
namespace cmdline
public enum NO_VALIDATION
</eucode>

Do not cause an error for an invalid parameter. See [[:cmd_parse]]




@[:cmdline:NO_VALIDATION_AFTER_FIRST_EXTRA|]
==== NO_VALIDATION_AFTER_FIRST_EXTRA
<eucode>
include std/cmdline.e
namespace cmdline
public enum NO_VALIDATION_AFTER_FIRST_EXTRA
</eucode>

Do not cause an error for an invalid parameter after the
first extra item has been found. This can be helpful for
processes such as the Interpreter itself that must deal
with command line parameters that it is not meant to
handle.  At expansions after the first extra are also disabled.

For instance~:

##eui -D TEST greet.ex -name John -greeting Bye##

##-D TEST## is meant for ##eui##, but ##-name## and ##-greeting## options
are meant for ##greet.ex##. See [[:cmd_parse]]

##eui @euopts.txt greet.ex @hotmail.com##

here 'hotmail.com' is not expanded into the command line but
'euopts.txt' is.




@[:cmdline:SHOW_ONLY_OPTIONS|]
==== SHOW_ONLY_OPTIONS
<eucode>
include std/cmdline.e
namespace cmdline
public enum SHOW_ONLY_OPTIONS
</eucode>

Only display the option list in ##show_help##. Do not display other
information (such as program name, options, and so on) See [[:cmd_parse]]




@[:cmdline:AT_EXPANSION|]
==== AT_EXPANSION
<eucode>
include std/cmdline.e
namespace cmdline
public enum AT_EXPANSION
</eucode>

Expand arguments that begin with ##'@'## into the command line. (default)
For example, ##@filename## will expand the contents of file named 'filename'
as if the file's contents were passed in on the command line.  Arguments
that come after the first extra will not be expanded when
##NO_VALIDATION_AFTER_FIRST_EXTRA## is specified.




@[:cmdline:NO_AT_EXPANSION|]
==== NO_AT_EXPANSION
<eucode>
include std/cmdline.e
namespace cmdline
public enum NO_AT_EXPANSION
</eucode>

Do not expand arguments that begin with ##'@'## into the command line.
Normally ##@filename## will expand the file names contents as if the
file's contents were passed in on the command line.  This option
supresses this behavior.




@[:cmdline:PAUSE_MSG|]
==== PAUSE_MSG
<eucode>
include std/cmdline.e
namespace cmdline
public enum PAUSE_MSG
</eucode>

Supply a message to display and pause just prior to ##abort## being called.




@[:cmdline:NO_HELP|]
==== NO_HELP
<eucode>
include std/cmdline.e
namespace cmdline
public enum NO_HELP
</eucode>

Disable the automatic inclusion of ##-h##, ##-?##, and ##~--help## as help switches.




@[:cmdline:NO_HELP_ON_ERROR|]
==== NO_HELP_ON_ERROR
<eucode>
include std/cmdline.e
namespace cmdline
public enum NO_HELP_ON_ERROR
</eucode>

Disable the automatic display of all of the possible options on error.




@[:cmdline:OPT_IDX|]
==== OPT_IDX
<eucode>
include std/cmdline.e
namespace cmdline
public enum OPT_IDX
</eucode>

An index into the ##opts## list. See [[:cmd_parse]]




@[:cmdline:OPT_CNT|]
==== OPT_CNT
<eucode>
include std/cmdline.e
namespace cmdline
public enum OPT_CNT
</eucode>

The number of times that the routine has been called
by ##cmd_parse## for this option. See [[:cmd_parse]]




@[:cmdline:OPT_VAL|]
==== OPT_VAL
<eucode>
include std/cmdline.e
namespace cmdline
public enum OPT_VAL
</eucode>

The option's value as found on the command line. See [[:cmd_parse]]




@[:cmdline:OPT_REV|]
==== OPT_REV
<eucode>
include std/cmdline.e
namespace cmdline
public enum OPT_REV
</eucode>

The value ##1## if the command line indicates that this option is to remove
any earlier occurrences of it. See [[:cmd_parse]]




@[:cmdline:EXTRAS|]
==== EXTRAS
<eucode>
include std/cmdline.e
namespace cmdline
public constant EXTRAS
</eucode>

The extra parameters on the cmd line, not associated with any
specific option. See [[:cmd_parse]]




=== Routines


@[:eu:command_line|]
==== command_line
<eucode>
<built-in> function command_line()
</eucode>

returns sequence of strings containing each word entered at the command-line that started your program.

===== Returns:
# The ##path##, to either the Euphoria executable (##eui##, ##eui.exe##, ##euid.exe##, ##euiw.exe##) or to your bound
executable file.
# The ##next word##, is either the name of your Euphoria main file or
(again) the path to your bound executable file.
# Any ##extra words##, typed by the user. You can use these words in your program.

There are as many entries as words, plus the two mentioned above.

The Euphoria interpreter itself does not use any command-line options. You are free to use
any options for your own program. The interpreter does have [[:command line switches]] though.

The user can put quotes around a series of words to make them into a single argument.

If you convert your program into an executable file, either by binding it, or translationg it to C,
you will find that all command-line arguments remain the same, except for the first two,
even though your user no longer types "eui" on the command-line (see examples below).

===== Example 1:
<eucode>
 -- The user types:  eui myprog myfile.dat 12345 "the end"

cmd = command_line()

-- cmd will be:
      {"C:\EUPHORIA\BIN\EUI.EXE",
       "myprog",
       "myfile.dat",
       "12345",
       "the end"}
</eucode>

===== Example 2:
<eucode>
-- Your program is bound with the name "myprog.exe"
-- and is stored in the directory c:\myfiles
-- The user types:  myprog myfile.dat 12345 "the end"

cmd = command_line()

-- cmd will be:
       {"C:\MYFILES\MYPROG.EXE",
        "C:\MYFILES\MYPROG.EXE", -- place holder
        "myfile.dat",
        "12345",
        "the end"
        }

-- Note that all arguments remain the same as in Example 1
-- except for the first two. The second argument is always
-- the same as the first and is inserted to keep the numbering
-- of the subsequent arguments the same, whether your program
-- is bound or translated as a .exe, or not.
</eucode>

===== See Also:
[[:build_commandline]], [[:option_switches]],  [[:getenv]], [[:cmd_parse]], [[:show_help]]


@[:eu:option_switches|]
==== option_switches
<eucode>
<built-in> function option_switches()
</eucode>

retrieves the list of switches passed to the interpreter on the command line.

===== Returns:
A **sequence**, of strings, each containing a word related to switches.

===== Comments:

All switches are recorded in upper case.

===== Example 1:
<eucode>
euiw -d helLo
-- will result in
-- option_switches() being {"-D","helLo"}
</eucode>

===== See Also:
[[:Command line switches]]


@[:cmdline:show_help|]
==== show_help
<eucode>
include std/cmdline.e
namespace cmdline
public procedure show_help(sequence opts, object add_help_rid = - 1,
        sequence cmds = command_line(), object parse_options = {})
</eucode>

  shows the help message for the given opts.

===== Parameters:
# ##opts## : a sequence of options. See the [[:cmd_parse]] for details.
# ##add_help_rid## : an object. Either a routine_id or a set of text strings.
The default is -1 meaning that no additional help text will be used.
# ##cmds## : a sequence of strings. By default this is the output from [[:command_line]]
# ##parse_options## : An option set of behavior modifiers.  See the [[:cmd_parse]] for details.

===== Comments:
* ##opts## is identical to the one used by [[:cmd_parse]]
* ##add_help_rid## can be used to provide additional help text. By default, just
the option switches and their descriptions will be displayed. However you can
provide additional text by either supplying a routine_id of a procedure that
accepts no parameters; this procedure is expected to write text to the stdout
device. Or you can supply one or more lines of text that will be displayed.

===== Example 1:
<eucode>
-- in myfile.ex
constant description = {
       "Creates a file containing an analysis of the weather.",
       "The analysis includes temperature and rainfall data",
       "for the past week."
    }

show_help({
    {"q", "silent", "Suppresses any output to console", NO_PARAMETER, -1},
    {"r", 0, "Sets how many lines the console should display", 
    {HAS_PARAMETER,"lines"}, -1}}, description)
</eucode>
Outputs~:
{{{
myfile.ex options:
-q, --silent      Suppresses any output to console
-r lines          Sets how many lines the console should display

Creates a file containing an analysis of the weather.
The analysis includes temperature and rainfall data
for the past week.
}}}

===== Example 2:
<eucode>
-- in myfile.ex
constant description = {
       "Creates a file containing an analysis of the weather.",
       "The analysis includes temperature and rainfall data",
       "for the past week."
    }
procedure sh()
  for i = 1 to length(description) do
     printf(1, " >> %s <<\n", {description[i]})
  end for
end procedure

show_help({
    {"q", "silent", "Suppresses any output to console", NO_PARAMETER, -1},
    {"r", 0, "Sets how many lines the console should display", 
     {HAS_PARAMETER,"lines"}, -1}}, routine_id("sh"))
</eucode>
Outputs~:
{{{
myfile.ex options:
-q, --silent      Suppresses any output to console
-r lines          Sets how many lines the console should display

>> Creates a file containing an analysis of the weather. <<
>> The analysis includes temperature and rainfall data  <<
>> for the past week.  <<
}}}



@[:cmdline:cmd_parse|]
==== cmd_parse
<eucode>
include std/cmdline.e
namespace cmdline
public function cmd_parse(sequence opts, object parse_options = {},
        sequence cmds = command_line())
</eucode>

  parses command line options and optionally calls procedures based on these options.

===== Parameters:
# ##opts## : a sequence of records that define the various command line
//switches// and //options// that are valid for the application: See Comments: section for details
# ##parse_options## : an optional list of special behavior modifiers: See Parse Options section for details
# ##cmds## : an optional sequence of command line arguments. If omitted the output from
##command_line## is used.

===== Returns:
A **map**, containing the set of actual options used in ##cmds##. The returned
map has one special key, ##EXTRAS## that are values passed on the
command line that are not part of any of the defined options. This is commonly
used to get the list of files entered on the command line. For instance, if
the command line used was //##myprog -verbose file1.txt file2.txt##// then
the ##EXTRAS## data value would be ##{"file1.txt", "file2.txt"}##.

When any command item begins with an **##@##** symbol then it is assumed
that it prefixes a file name. That file will then be opened and its contents used
to add to the command line, as if the file contents had actually been entered as
part of the original command line.

Parse Options~:
##parse_options## is used to provide a set of behavior modifiers that change the
default rules for parsing the command line. If used, it is a list of values
that will affect the parsing of the command line options.

These modifers can be any combination of~:

# ##VALIDATE_ALL## ~-- The default. All options will be validated for all possible errors.
# ##NO_VALIDATION## ~-- Do not validate any parameter.
# ##NO_VALIDATION_AFTER_FIRST_EXTRA## ~-- Do not validate any parameter after the first extra
was encountered. This is helpful for programs such as the Interpreter itself:
##eui -D TEST greet.ex -name John##. -D TEST should be validated but anything after
"greet.ex" should not as it is meant for greet.ex to handle, not eui.
# ##HELP_RID## ~-- The next Parse Option must either a routine id or a set of
text strings. The routine is called or the text is displayed when a parse error
(invalid option given, mandatory option not given, no parameter given for an option that requires a
parameter, etc...) occurs. This can be used to provide additional
help text. By default, just the option switches and their descriptions will be
displayed. However you can provide additional text by either supplying a
routine_id of a procedure that accepts no parameters, or a sequence containing
lines of text (one line per element).  The procedure is expected
to write text to the stdout device.
# ##NO_HELP_ON_ERROR## ~-- Do not show a list of options on a command line error.
# ##NO_HELP## ~-- Do not automatically add the switches '-h', '-?', and '--help'
to display the help text (if any).
# ##NO_AT_EXPANSION## ~-- Do not expand arguments that begin with '@.'
# ##AT_EXPANSION## ~-- Expand arguments that begin with '@'.  The name that follows @ will be
opened as a file, read, and each trimmed non-empty line that does not begin with a
'#' character will be inserted as arguments in the command line. These lines
replace the original '@' argument as if they had been entered on the original
command line. \\
** If the name following the '@' begins with another '@', the extra
'@' is removed and the remainder is the name of the file. However, if that
file cannot be read, it is simply ignored. This allows //optional// files
to be included on the command line. Normally, with just a single '@', if the
file cannot be found the program aborts.
** Lines whose first non-whitespace character is '#' are treated as a comment
and thus ignored.
** Lines enclosed with double quotes will have the quotes stripped off and the
result is used as an argument. This can be used for arguments that begin with
a '#' character, for example.
** Lines enclosed with single quotes will have the quotes stripped off and
the line is then further split up use the space character as a delimiter. The
resulting 'words' are then all treated as individual arguments on the command
line.

An example of parse options~:
<eucode>
{ HELP_RID, routine_id("my_help"), NO_VALIDATION }
</eucode>

===== Comments:
Token types recognized on the command line~:

# a single '-'. Simply added to the 'extras' list
# a single "~-~-". This signals the end of command line options. What remains of the command
line is added to the 'extras' list, and the parsing terminates.
# -shortName. The option will be looked up in the short name field of ##opts##.
# /shortName. Same as -shortName.
# -!shortName. If the 'shortName' has already been found the option is removed.
# /!shortName. Same as -!shortName
# ~-~-longName. The option will be looked up in the long name field of ##opts##.
# ~-~-!longName. If the 'longName' has already been found the option is removed.
# anything else. The word is simply added to the 'extras' list.

For those options that require a parameter to also be supplied, the parameter
can be given as either the next command line argument, or by appending '=' or ':'
to the command option then appending the parameter data. \\
For example, **##-path=/usr/local##** or as **##-path /usr/local##**.

On a failed lookup, the program shows the help by calling [[:show_help]](##opts##,
##add_help_rid##, ##cmds##) and terminates with status code 1.

If you do not explicitly define the switches ##-h##, ##-?##, or ##--help##,
these will be automatically added to the list of valid switches and will be
set to call the [[:show_help]] routine.

You can remove any of these as default 'help' switches simply by explicitly
using them for something else.

You can also remove all of these switches as //automatic// help switches by
using the ##NO_HELP## parsing option. This just means that these switches are
not automatically used as 'help' switches, regardless of whether they are used
explicitly or not. So if ##NO_HELP## is used, and you want to give the user
the ability to display the 'help' then you must explicitly set up your own
switch to do so. **N.B**, the 'help' is still displayed if an invalid command
line switch is used at runtime, regardless of whether ##NO_HELP## is used or not.

Option records have the following structure~:
# a sequence representing the (short name) text that will follow the "-" option format.
Use an atom if not relevant
# a sequence representing the (long name) text that will follow the "~-~-" option format.
Use an atom if not relevant
# a sequence, text that describes the option's purpose. Usually short as it is
displayed when "-h"/"--help" is on the command line. Use an atom if not required.
# An object ...
** If an **atom** then it can be either ##HAS_PARAMETER## or anything
else if there is no parameter for this option. This format also implies that
the option is optional, case-sensitive and can only occur once.
** If a **sequence**, it can containing zero or more processing flags in any order ...
*** ##MANDATORY## to indicate that the option must always be supplied.
*** ##HAS_PARAMETER## to indicate that the option must have a parameter following it.
You can optionally have a name for the parameter immediately follow the ##HAS_PARAMETER##
flag. If one isn't there, the help text will show "x" otherwise it shows the
supplied name.
*** ##NO_CASE## to indicate that the case of the supplied option is not significant.
*** ##ONCE## to indicate that the option must only occur once on the command line.
*** ##MULTIPLE## to indicate that the option can occur any number of times on the command line.
** If both ##ONCE## and ##MULTIPLE## are omitted then switches that also have
##HAS_PARAMETER## are only allowed once but switches without ##HAS_PARAMETER##
can have multuple occurances but only one is recorded in the output map.
# an integer; a [[:routine_id]]. This function will be called when the option is located
on the command line and before it updates the map. \\
Use -1 if cmd_parse is not to invoke a function for this option.\\
The user defined function must accept a single sequence parameter containing four values.
If the function returns ##1## then the command option does not update the map.
You can use the predefined index values ##OPT_IDX##, ##OPT_CNT##, ##OPT_VAL##, ##OPT_REV## when
referencing the function's parameter elements.
## An index into the ##opts## list.
## The number of times that the routine has been called
by cmd_parse for this option
## The option's value as found on the command line
## 1 if the command line indicates that this option is to remove any earlier occurrences of it.

One special circumstance exists and that is an option group header. It should contain only
two elements~:
# The header constant: HEADER
# A sequence to display as the option group header

When assigning a value to the resulting map, the key is the long name if present,
otherwise it uses the short name. For options, you must supply a short name,
a long name or both.

If you want ##cmd_parse## to call a user routine for the extra command line values,
you need to specify an Option Record that has neither a short name or a long name,
in which case only the routine_id field is used.

For more details on how the command line is being pre-parsed, see [[:command_line]].

===== Example 1:
<eucode>
   -- simple usage

map args = cmd_parse({  
    { "o", 0, "Output directory", { HAS_PARAMETER } },  
    { "v", 0, "Verbose mode" }  
})

if map:get(args, "v") then
    printf(1, "Output directory is %s\n", { map:get(args, "o") })
end if
</eucode>

===== Example 2:
<eucode>
    -- complex usage

sequence option_definition
integer gVerbose = 0
sequence gOutFile = {}
sequence gInFile = {}
function opt_verbose( sequence value)
   if value[OPT_VAL] = -1 then -- (-!v used on command line)
   	gVerbose = 0
   else
     if value[OPT_CNT] = 1 then
        gVerbose = 1
     else
        gVerbose += 1
     end if
   end if
	return 1
end function

function opt_output_filename( sequence value)
   gOutFile = value[OPT_VAL]
	return 1
end function

function extras( sequence value)
   if not file_exists(value[OPT_VAL]) then
       show_help(option_definition, sprintf("Cannot find '%s'", 
                 {value[OPT_VAL]}) )
       abort(1)
   end if
   gInFile = append(gInFile, value[OPT_VAL])
	return 1
end function

option_definition = {
    { HEADER,         "General options" },
    { "h", "hash",    "Calc hash values", { NO_PARAMETER }, -1 },
    { HEADER,         "Input and output" },
    { "o", "output",  "Output filename",  { MANDATORY, HAS_PARAMETER, ONCE } , 
                                            routine_id("opt_output_filename") },
    { "i", "import",  "An import path",   { HAS_PARAMETER, MULTIPLE}, -1 },
    { HEADER,         "Miscellaneous" },
    { "v", "verbose", "Verbose output",   { NO_PARAMETER }, routine_id("opt_verbose") },
    { "e", "version", "Display version",  { VERSIONING, "myprog v1.0" } },
    {  0, 0, 0, 0, routine_id("extras")}
}

map:map opts = cmd_parse(option_definition, NO_HELP)

-- When run as: 
--             eui myprog.ex -v @output.txt -i /etc/app input1.txt input2.txt
-- and the file "output.txt" contains the two lines ...
--   --output=john.txt
--   '-i /usr/local'
--
-- map:get(opts, "verbose") --> 1
-- map:get(opts, "hash") --> 0 (not supplied on command line)
-- map:get(opts, "output") --> "john.txt"
-- map:get(opts, "import") --> {"/usr/local", "/etc/app"}
-- map:get(opts, EXTRAS) --> {"input1.txt", "input2.txt"}
</eucode>

===== See Also:
[[:show_help]], [[:command_line]]


@[:cmdline:build_commandline|]
==== build_commandline
<eucode>
include std/cmdline.e
namespace cmdline
public function build_commandline(sequence cmds)
</eucode>

  returns a text string based on the set of supplied strings.

===== Parameters:
# ##cmds## : A sequence. Contains zero or more strings.

===== Returns:
A **sequence**, which is a text string. Each of the strings in ##cmds## is
quoted if they contain spaces, and then concatenated to form a single
string.

===== Comments:
Typically, this
is used to ensure that arguments on a command line are properly formed
before submitting it to the shell.

Though this function does the quoting for you it is not going to protect
your programs from globing ##*##, ##?## .  And it is not specied here what happens if you
pass redirection or piping characters.

When passing a result from with build_commandline to [[:system_exec]],
file arguments will benefit from using [[:canonical_path]] with the [[:TO_SHORT]].
On //Windows// this is required for file arguments to always work.  There is a complication
with files that contain spaces.  On //Unix//
this call will also return a useable filename.

Alternatively, you can leave out calls to [[:canonical_path]] and use [[:system]] instead.

===== Example 1:
<eucode>
s = build_commandline( { "-d", canonical_path("/usr/my docs/",,TO_SHORT)} )
-- s now contains a short name equivalent to '-d "/usr/my docs/"'
</eucode>

===== Example 2:
You can use this to run things that might be difficult to quote out.
Suppose you want to run a program that requires quotes on its
command line?  Use this function to pass quotation marks~:

<eucode>
s = build_commandline( { "awk", "-e", "'{ print $1"x"$2; }'" } )
system(s,0)
</eucode>

===== See Also:
[[:parse_commandline]], [[:system]], [[:system_exec]], [[:command_line]],
[[:canonical_path]],  [[:TO_SHORT]]


@[:cmdline:parse_commandline|]
==== parse_commandline
<eucode>
include std/cmdline.e
namespace cmdline
public function parse_commandline(sequence cmdline)
</eucode>

  parses a command line string breaking it into a sequence of command line
options.

===== Parameters:
# ##cmdline## : Command line sequence (string)

===== Returns:
A **sequence**, of command line options

===== Example 1:
<eucode>
sequence opts = parse_commandline("-v -f '%Y-%m-%d %H:%M'")
-- opts = { "-v", "-f", "%Y-%m-%d %H:%M" }
</eucode>

===== See Also:
[[:build_commandline]]




!!CONTEXT:../include/std/console.e
!!namespace:console
%%output = std_console

== Console

<<LEVELTOC level=2 depth=4>>


=== Information


@[:console:has_console|]
==== has_console
<eucode>
include std/console.e
namespace console
public function has_console()
</eucode>

  determines if the process has a console (terminal) window.

===== Returns:
An **atom**,
* ##1## if there is more than one process attached to the current console,
* ##0## if a console does not exist or only one process (Euphoria) is attached to
the current console.

===== Comments:
* On //Unix// systems always returns ##1## .
* On //Windows// client systems earlier than Windows XP the function always returns ##0## .
* On //Windows// server systems earlier than Windows Server 2003 the function always returns ##0## .

===== Example 1:
<eucode>
include std/console.e

if has_console() then
    printf(1, "Hello Console!")
end if
</eucode>



@[:console:key_codes|]
==== key_codes
<eucode>
include std/console.e
namespace console
public function key_codes(object codes = 0)
</eucode>

  gets and sets the keyboard codes used internally by Euphoria.

===== Parameters:
# ##codes## : Either a sequence of exactly 256 integers or an atom (the default).

===== Returns:
A **sequence**,
of the current 256 keyboard codes, prior to any changes that
this function might make.

===== Comments:
When ##codes## is a atom then no change to the existing codes is made, otherwise
the set of 256 integers in ##codes## completely replaces the existing codes.

===== Example 1:
<eucode>
include std/console.e
sequence kc
kc = key_codes() -- Get existing set.
kc[KC_LEFT] = 263 -- Change the code for the left-arrow press.
key_codes(kc) -- Set the new codes.
</eucode>



=== Key Code Names
These are the names of the index values for each of the 256 key code values.


===== See Also:
[[:key_codes]]


@[:console:KC_LBUTTON|]
==== KC_LBUTTON
<eucode>
include std/console.e
namespace console
public constant KC_LBUTTON
</eucode>





@[:console:set_keycodes|]
==== set_keycodes
<eucode>
include std/console.e
namespace console
public function set_keycodes(object kcfile)
</eucode>

  changes the default codes returned by the keyboard.

===== Parameters:
# ##kcfile## : Either the name of a text file or the handle of an opened (for reading) text file.

===== Returns:
An **integer**,
* ##0## means no error.
* ##-1## means that the supplied file could not me loaded in to a [[:map]].
* ##-2## means that a new key value was not an integer.
* ##-3## means that an unknown key name was found in the file.

===== Comments:
The text file is expected to contain bindings for one or more keyboard codes.

The format of the files is a set of lines, one line per key binding, in the
form ##KEYNAME = NEWVALUE##. The ##KEYNAME## is the same as the constants but without
the "##KC_##" prefix. The key bindings can be in any order.

===== Example 1:
{{{
-- doskeys.txt file containing some key bindings
F1 = 260
F2 = 261
INSERT = 456
}}}
<eucode>
  set_keycodes( "doskeys.txt" )
</eucode>

===== See Also:
[[:key_codes]]


=== Cursor Style Constants

In cursor constants the second and fourth hex digits (from the
left) determine the top and bottom row of pixels in the cursor. The first
digit controls whether the cursor will be visible or not. For example~: ###0407##
turns on the 4th through 7th rows.

Note: //Windows// only.

===== See Also:
[[:cursor]]


@[:console:NO_CURSOR|]
==== NO_CURSOR
<eucode>
include std/console.e
namespace console
public constant NO_CURSOR
</eucode>





@[:console:UNDERLINE_CURSOR|]
==== UNDERLINE_CURSOR
<eucode>
include std/console.e
namespace console
public constant UNDERLINE_CURSOR
</eucode>





@[:console:THICK_UNDERLINE_CURSOR|]
==== THICK_UNDERLINE_CURSOR
<eucode>
include std/console.e
namespace console
public constant THICK_UNDERLINE_CURSOR
</eucode>





@[:console:HALF_BLOCK_CURSOR|]
==== HALF_BLOCK_CURSOR
<eucode>
include std/console.e
namespace console
public constant HALF_BLOCK_CURSOR
</eucode>





@[:console:BLOCK_CURSOR|]
==== BLOCK_CURSOR
<eucode>
include std/console.e
namespace console
public constant BLOCK_CURSOR
</eucode>





=== Keyboard Related Routines


@[:eu:get_key|]
==== get_key
<eucode>
<built-in> function get_key()
</eucode>

returns the key that was pressed by the user, without waiting. Special
codes are returned for the function keys, arrow keys, and so on.

===== Returns:
An **integer**,
either -1 if no key waiting, or the code of the next key
waiting in keyboard buffer.

===== Comments:
The operating system can hold a small number of key-hits in its keyboard buffer.
##get_key## will return the next one from the buffer, or ##-1## if the buffer is empty.

Run the ##.../euphoria/demo/key.ex## program to see what key code is generated for each key on your
keyboard.

===== Example 1:
<eucode>
integer n = get_key()
if n=-1 then
    puts(1, "No key waiting.\n")
end if
</eucode>

===== See Also:
[[:wait_key]]


@[:console:allow_break|]
==== allow_break
<eucode>
include std/console.e
namespace console
public procedure allow_break(types :boolean b)
</eucode>

  sets the behavior of Control+C and Control+Break keys.

===== Parameters:
# ##b## : a boolean,  TRUE ( != 0 ) to enable the trapping of
Control+C and Control+Break, FALSE ( 0 ) to disable it.

===== Comments:
When ##b## is ##1## (true), Control+C and Control+Break can terminate
your program when it tries to read input from the keyboard. When
##b## is ##0## (false) your program will not be terminated by Control+C or Control+Break.

Initially your program can be terminated at any point where
it tries to read from the keyboard.

You can find out if the user has pressed Control+C or Control+Break by calling
[[:check_break]].

===== Example 1:
<eucode>
allow_break(0)  -- don't let the user kill the program!
</eucode>

===== See Also:
[[:check_break]]


@[:console:check_break|]
==== check_break
<eucode>
include std/console.e
namespace console
public function check_break()
</eucode>

returns the number of Control+C and Control+Break key presses.

===== Returns:
An **integer**,
the number of times that Control+C or Control+Break have
been pressed since the last call to ##check_break##, or since the
beginning of the program if this is the first call.

===== Comments:
This is useful after you have called [[:allow_break]](0) which
prevents Control+C or Control+Break from terminating your
program. You can use ##check_break## to find out if the user
has pressed one of these keys. You might then perform some action
such as a graceful shutdown of your program.

Neither Control+C nor Control+Break will be returned as input
characters when you read the keyboard. You can only detect
them by calling ##check_break##.

===== Example 1:
<eucode>
k = get_key()
if check_break() then  -- ^C or ^Break was hit once or more
    temp = graphics_mode(-1)
    puts(STDOUT, "Shutting down...")
    save_all_user_data()
    abort(1)
end if
</eucode>

===== See Also:
[[:allow_break]]


@[:console:wait_key|]
==== wait_key
<eucode>
include std/console.e
namespace console
public function wait_key()
</eucode>

waits for user to press a key, unless any is pending, and returns key code.

===== Returns:
An **integer**,
which is a key code. If one is waiting in keyboard buffer, then return it. Otherwise, wait for one to come up.

===== See Also:
[[:get_key]], [[:getc]]


@[:console:any_key|]
==== any_key
<eucode>
include std/console.e
namespace console
public procedure any_key(sequence prompt = "Press Any Key to continue...", integer con = 1)
</eucode>

displays a prompt to the user and waits for any key.

===== Parameters:
# ##prompt## : Prompt to display, defaults to ##"Press Any Key to continue..."## .
# ##con## : Either ##1## (stdout), or ##2## (stderr). Defaults to ##1## .

===== Comments:
This wraps [[:wait_key]] by giving a clue that the user should press a key, and
perhaps do some other things as well.

===== Example 1:
<eucode>
any_key() -- "Press Any Key to continue..."
</eucode>

===== Example 2:
<eucode>
any_key("Press Any Key to quit")
</eucode>

===== See Also:
[[:wait_key]]


@[:console:maybe_any_key|]
==== maybe_any_key
<eucode>
include std/console.e
namespace console
public procedure maybe_any_key(sequence prompt = "Press Any Key to continue...",
        integer con = 1)
</eucode>

displays a prompt to the user and waits for any key. //Only// if the user is
running under a GUI environment.

===== Parameters:
# ##prompt## : Prompt to display, defaults to ##"Press Any Key to continue..."##
# ##con## : Either 1 (stdout), or 2 (stderr). Defaults to 1.

===== Comments:
This wraps [[:wait_key]] by giving a clue that the user should press a key, and
perhaps do some other things as well.

Requires Windows XP or later or Windows 2003 or later to work.  Earlier versions of //Windows//
or O/S will always pause even when not needed.

On //Unix// systems this will not pause even when needed.

===== Example 1:
<eucode>
any_key() -- "Press Any Key to continue..."
</eucode>

===== Example 2:
<eucode>
any_key("Press Any Key to quit")
</eucode>

===== See Also:
[[:wait_key]]


@[:console:prompt_number|]
==== prompt_number
<eucode>
include std/console.e
namespace console
public function prompt_number(sequence prompt, sequence range)
</eucode>

prompts the user to enter a number and returns only validated input.

===== Parameters:
# ##st## : is a string of text that will be displayed on the screen.
# ##s## : is a sequence of two values {lower, upper} which determine the range of values
that the user may enter. s can be empty, {}, if there are no restrictions.

===== Returns:
An **atom**,
in the assigned range which the user typed in.

===== Errors:
If [[:puts]] cannot display ##st## on standard output, or if the first or second element
of ##s## is a sequence, a runtime error will be raised.

If user tries cancelling the prompt by hitting Control+Z, the program will abort as well,
issuing a type check error.

===== Comments:
As long as the user enters a number that is less than lower or greater
than upper, the user will be prompted again.

If this routine is too simple for your needs, feel free to copy it and make your
own more specialized version.

===== Example 1:
<eucode>
age = prompt_number("What is your age? ", {0, 150})
</eucode>

===== Example 2:
<eucode>
t = prompt_number("Enter a temperature in Celcius:\n", {})
</eucode>

===== See Also:
[[:puts]], [[:prompt_string]]



@[:console:prompt_string|]
==== prompt_string
<eucode>
include std/console.e
namespace console
public function prompt_string(sequence prompt)
</eucode>

  prompts the user to enter a string of text.

===== Parameters:
# ##st## : is a string that will be displayed on the screen.

===== Returns:
A **sequence**,
the string that the user typed in, stripped of any new-line character.

===== Comments:
If the user happens to type Control+Z (indicates end-of-file), "" will be returned.

===== Example 1:
<eucode>
name = prompt_string("What is your name? ")
</eucode>

===== See Also:
[[:prompt_number]]


=== Cross Platform Text Graphics


@[:console:positive_int|]
==== positive_int
<eucode>
include std/console.e
namespace console
public type positive_int(object x)
</eucode>



@[:eu:clear_screen|]
==== clear_screen
<eucode>
<built-in> procedure clear_screen()
</eucode>

clears the screen using the current background color.

===== Comments:
The background color can be set by [[:bk_color]] ).

===== See Also:
[[:bk_color]]



@[:console:get_screen_char|]
==== get_screen_char
<eucode>
include std/console.e
namespace console
public function get_screen_char(positive_atom line, positive_atom column, integer fgbg = 0)
</eucode>

  gets the value and attribute of the character at a given screen location.

===== Parameters:
# ##line## : the 1-base line number of the location.
# ##column## : the 1-base column number of the location.
# ##fgbg## : an integer, if ##0## (the default) you get an attribute_code
returned otherwise you get a foreground and background color
number returned.

===== Returns:
* If fgbg is zero then a **sequence** of //two// elements, ##{character, attribute_code}##
for the specified location.
* If fgbg is not zero then a **sequence** of //three// elements, ##{characterfg_color, bg_color}##.

===== Comments:
* This function inspects a single character on the //active page//.
* The attribute_code is an atom that contains the foreground and background
color of the character, and possibly other operating-system dependant
information describing the appearance of the character on the screen.
* With ##get_screen_char## and ##put_screen_char## you can save and restore
a character on the screen along with its attribute_code.
* The ##fg_color## and ##bg_color## are integers in the range ##0## to ##15## which correspond
to the values in the table~:

Color Table

|= color number |= name |
|       0       | black      |
|       1       | dark blue      |
|       2       | green      |
|       3       | cyan      |
|       4       | crimson      |
|       5       | purple      |
|       6       | brown      |
|       7       | light gray      |
|       8       | dark gray      |
|       9       | blue      |
|       10      | bright green      |
|       11      | light blue      |
|       12      | red      |
|       13      | magenta      |
|       14      | yellow      |
|       15      | white      |


===== Example 1:
<eucode>
-- read character and attributes at top left corner
s = get_screen_char(1,1)
-- s could be {'A', 92}
-- store character and attributes at line 25, column 10
put_screen_char(25, 10, s)
</eucode>

===== Example 2:
<eucode>
-- read character and colors at line 25, column 10.
s = get_screen_char(25,10, 1)
-- s could be {'A', 12, 5}
</eucode>

===== See Also:
[[:put_screen_char]], [[:save_text_image]]


@[:console:put_screen_char|]
==== put_screen_char
<eucode>
include std/console.e
namespace console
public procedure put_screen_char(positive_atom line, positive_atom column, sequence char_attr)
</eucode>

  stores and displays a sequence of characters with attributes at a given location.

===== Parameters:
# ##line## : the 1-based line at which to start writing.
# ##column## : the 1-based column at which to start writing.
# ##char_attr## : a sequence of alternated characters and attribute codes.

===== Comments:

##char_attr## must be in the form  ##{character, attribute code, character, attribute code, ...}##.

===== Errors:
The length of ##char_attr## must be a multiple of two.

===== Comments:

The attributes atom contains the foreground color, background color, and possibly other platform-dependent information controlling how the character is displayed on the screen.
If ##char_attr## has ##0## length, nothing will be written to the screen. The characters are written to the //active page//.
It is faster to write several characters to the screen with a single call to ##put_screen_char## than it is to write one character at a time.

===== Example 1:
<eucode>
-- write AZ to the top left of the screen
-- (attributes are platform-dependent)
put_screen_char(1, 1, {'A', 152, 'Z', 131})
</eucode>

===== See Also:
[[:get_screen_char]], [[:display_text_image]]


@[:console:attr_to_colors|]
==== attr_to_colors
<eucode>
include std/console.e
namespace console
public function attr_to_colors(integer attr_code)
</eucode>

  converts an attribute code to its foreground and background color components.

===== Parameters:
# ##attr_code## : integer, an attribute code.

===== Returns:
A **sequence**,
of two elements ~-- ##{fgcolor, bgcolor}##

===== Example 1:
<eucode>
? attr_to_colors(92) --> {12, 5}
</eucode>

===== See Also:
[[:get_screen_char]], [[:colors_to_attr]]


@[:console:colors_to_attr|]
==== colors_to_attr
<eucode>
include std/console.e
namespace console
public function colors_to_attr(object fgbg, integer bg = 0)
</eucode>

  converts a foreground and background color set to its attribute code format.

===== Parameters:
# ##fgbg## : Either a sequence of ##{fgcolor, bgcolor}## or just an integer fgcolor.
# ##bg## : An integer bgcolor. Only used when ##fgbg## is an integer.

===== Returns:
An **integer**,
an attribute code.

===== Example 1:
<eucode>
? colors_to_attr({12, 5}) --> 92
? colors_to_attr(12, 5) --> 92
</eucode>

===== See Also:
[[:get_screen_char]], [[:put_screen_char]], [[:attr_to_colors]]


@[:console:display_text_image|]
==== display_text_image
<eucode>
include std/console.e
namespace console
public procedure display_text_image(text_point xy, sequence text)
</eucode>

  displays a text image in any text mode.

===== Parameters:
# ##xy## : a pair of 1-based coordinates representing the point at which to start writing.
# ##text## : a list of sequences of alternated character and attribute.

===== Comments:
This routine displays to the active text page, and only works in text modes.

You might use [[:save_text_image]] and [[:display_text_image]] in a text-mode graphical
user interface, to allow "pop-up" dialog boxes, and drop-down menus to appear and disappear
without losing what was previously on the screen.

===== Example 1:
<eucode>
clear_screen()
display_text_image({1,1}, {{'A', WHITE, 'B', GREEN},
                           {'C', RED+16*WHITE},
                           {'D', BLUE}})
-- displays:
--     AB
--     C
--     D
-- at the top left corner of the screen.
-- 'A' will be white with black (0) background color,
-- 'B' will be green on black,
-- 'C' will be red on white, and
-- 'D' will be blue on black.
</eucode>

===== See Also:
[[:save_text_image]], [[:put_screen_char]]



@[:console:save_text_image|]
==== save_text_image
<eucode>
include std/console.e
namespace console
public function save_text_image(text_point top_left, text_point bottom_right)
</eucode>

  copies a rectangular block of text out of screen memory.

===== Parameters:
# ##top_left## : the coordinates, given as a pair, of the upper left corner of the area to save.
# ##bottom_right## : the coordinates, given as a pair, of the lower right corner of the area to save.

===== Returns:
A **sequence**,
of ##{character, attribute, character, ...}## lists.

===== Comments:

The returned value is appropriately handled by [[:display_text_image]].

This routine reads from the active text page, and only works in text modes.

You might use this function in a text-mode graphical user interface to save a portion of the
screen before displaying a drop-down menu, dialog box, alert box, and so on.

===== Example 1:
<eucode>
-- Top 2 lines are: Hello and World
s = save_text_image({1,1}, {2,5})

-- s is something like: {"H-e-l-l-o-", "W-o-r-l-d-"}
</eucode>

===== See Also:
[[:display_text_image]], [[:get_screen_char]]


@[:console:text_rows|]
==== text_rows
<eucode>
include std/console.e
namespace console
public function text_rows(positive_int rows)
</eucode>

  sets the number of lines on a text-mode screen.

===== Parameters:
# ##rows## : an integer, the desired number of rows.

===== Platform:
//Windows//

===== Returns:
An **integer**,
the actual number of text lines.

===== Comments:
Values of 25, 28, 43 and 50 lines are supported by most video cards.

===== See Also:

[[:graphics_mode]], [[:video_config]]


@[:console:cursor|]
==== cursor
<eucode>
include std/console.e
namespace console
public procedure cursor(integer style)
</eucode>

  selects a style of cursor.

===== Parameters:
# ##style## : an integer defining the cursor shape.

===== Platform:
//Windows//

===== Comments:

In pixel-graphics modes no cursor is displayed.

===== Example 1:
<eucode>
cursor(BLOCK_CURSOR)
</eucode>

Cursor Type Constants~:
* [[:NO_CURSOR]]
* [[:UNDERLINE_CURSOR]]
* [[:THICK_UNDERLINE_CURSOR]]
* [[:HALF_BLOCK_CURSOR]]
* [[:BLOCK_CURSOR]]

===== See Also:
[[:graphics_mode]], [[:text_rows]]



@[:console:free_console|]
==== free_console
<eucode>
include std/console.e
namespace console
public procedure free_console()
</eucode>

  frees (deletes) any console window associated with your program.

===== Comments:
Euphoria will create a console text window for your program the first time that your
program prints something to the screen, reads something from the keyboard, or in some
way needs a console. On //Windows// this window will automatically disappear when your program
terminates, but you can call ##free_console## to make it disappear sooner. On //Unix//
the text mode console is always there, but an xterm window will disappear after Euphoria
issues a ##"Press Enter"## prompt at the end of execution.

On //Unix// ##free_console## will set the terminal parameters back to normal,
undoing the effect that curses has on the screen.

In a //Unix// terminal a call to ##free_console## (without any further
printing to the screen or reading from the keyboard) will eliminate the
"Press Enter" prompt that Euphoria normally issues at the end of execution.

After freeing the console window, you can create a new console window by printing
something to the screen, calling ##clear_screen##, ##position##, or any other
routine that needs a console.

When you use the trace facility, or when your program has an error, Euphoria will
automatically create a console window to display trace information, error messages, and so on.

There is a WINDOWS API routine, {{{FreeConsole()}}} that does something similar to
##free_console##. Use the Euphoria ##free_console## because it lets the interpreter know
that there is no longer a console to write to or read from.

===== See Also:
[[:clear_screen]]


@[:console:display|]
==== display
<eucode>
include std/console.e
namespace console
public procedure display(object data_in, object args = 1, integer finalnl = - 918_273_645)
</eucode>

  displays the supplied data on the console screen at the current cursor position.

===== Parameters:
# ##data_in## : Any object.
# ##args## : Optional arguments used to format the output. Default is ##1## .
# ##finalnl## : Optional. Determines if a new line is output after the data.
Default is to output a new line.

===== Comments:
* If ##data_in## is an atom or integer, it is simply displayed.

* If ##data_in## is a simple text string, then ##args## can be used to
produce a formatted output with ##data_in## providing the [[:text:format]] string and
##args## being a sequence containing the data to be formatted.
** If the last character of ##data_in## is an underscore character then it
is stripped off and ##finalnl## is set to zero. Thus ensuring that a new line
is **not** output.
** The formatting codes expected in ##data_in## are the ones used by [[:text:format]].
It is not mandatory to use formatting codes, and if ##data_in## does not contain
any then it is simply displayed and anything in ##args## is ignored.

* If ##data_in## is a sequence containing floating-point numbers, sub-sequences
or integers that are not characters, then ##data_in## is forwarded on to the
[[:pretty_print]] to display.
** If ##args## is a non-empty sequence, it is assumed to contain the pretty_print formatting options.
** if ##args## is an atom or an empty sequence, the assumed pretty_print formatting
options are assumed to be ##{2}##.

After the data is displayed, the routine will normally output a New Line. If you
want to avoid this, ensure that the last parameter is a zero. Or to put this
another way, if the last parameter is zero then a New Line will **not** be output.

===== Example 1:
<eucode>
display("Some plain text") 
        -- Displays this string on the console plus a new line.
display("Your answer:",0)  
       -- Displays this string on the console without a new line.
display("cat")
display("Your answer:",,0) 
        -- Displays this string on the console without a new line.
display("")
display("Your answer:_")   
       -- Displays this string, 
       -- except the '_', on the console without a new line.
display("dog")
display({"abc", 3.44554}) 
       -- Displays the contents of 'res' on the console.
display("The answer to [1] was [2]", {"'why'", 42}) 
       -- formats these with a new line.
display("",2)
display({51,362,71}, {1})
</eucode>
Output would be~:
{{{
Some plain text
Your answer:cat
Your answer:
Your answer:dog
{
"abc",
3.44554
}
The answer to 'why' was 42
""
{51'3',362,71'G'}
}}}




!!CONTEXT:../include/std/datetime.e
!!namespace:datetime
%%output = std_datetime

== Date and Time

<<LEVELTOC level=2 depth=4>>


=== Localized Variables


@[:datetime:month_names|]
==== month_names
<eucode>
include std/datetime.e
namespace datetime
public sequence month_names
</eucode>

  Month Names


@[:datetime:month_abbrs|]
==== month_abbrs
<eucode>
include std/datetime.e
namespace datetime
public sequence month_abbrs
</eucode>

  Abbreviations of Month Names


@[:datetime:day_names|]
==== day_names
<eucode>
include std/datetime.e
namespace datetime
public sequence day_names
</eucode>

  Day Names


@[:datetime:day_abbrs|]
==== day_abbrs
<eucode>
include std/datetime.e
namespace datetime
public sequence day_abbrs
</eucode>

  Abbreviations of Day Names


@[:datetime:ampm|]
==== ampm
<eucode>
include std/datetime.e
namespace datetime
public sequence ampm
</eucode>

  AM and PM


=== Date and Time Type Accessors

These accessors can be used with the [[:datetime]] type.


@[:datetime:YEAR|]
==== YEAR
<eucode>
include std/datetime.e
namespace datetime
public enum YEAR
</eucode>

Year (full year, i.e. 2010, 1922, )




@[:datetime:MONTH|]
==== MONTH
<eucode>
include std/datetime.e
namespace datetime
public enum MONTH
</eucode>

Month (1-12)




@[:datetime:DAY|]
==== DAY
<eucode>
include std/datetime.e
namespace datetime
public enum DAY
</eucode>

Day (1-31)




@[:datetime:HOUR|]
==== HOUR
<eucode>
include std/datetime.e
namespace datetime
public enum HOUR
</eucode>

Hour (0-23)




@[:datetime:MINUTE|]
==== MINUTE
<eucode>
include std/datetime.e
namespace datetime
public enum MINUTE
</eucode>

Minute (0-59)




@[:datetime:SECOND|]
==== SECOND
<eucode>
include std/datetime.e
namespace datetime
public enum SECOND
</eucode>

Second (0-59)




=== Intervals

These constant enums are to be used with the [[:add]] and [[:subtract]] routines.



@[:datetime:YEARS|]
==== YEARS
<eucode>
include std/datetime.e
namespace datetime
public enum YEARS
</eucode>

Years




@[:datetime:MONTHS|]
==== MONTHS
<eucode>
include std/datetime.e
namespace datetime
public enum MONTHS
</eucode>

Months




@[:datetime:WEEKS|]
==== WEEKS
<eucode>
include std/datetime.e
namespace datetime
public enum WEEKS
</eucode>

Weeks




@[:datetime:DAYS|]
==== DAYS
<eucode>
include std/datetime.e
namespace datetime
public enum DAYS
</eucode>

Days




@[:datetime:HOURS|]
==== HOURS
<eucode>
include std/datetime.e
namespace datetime
public enum HOURS
</eucode>

Hours




@[:datetime:MINUTES|]
==== MINUTES
<eucode>
include std/datetime.e
namespace datetime
public enum MINUTES
</eucode>

Minutes




@[:datetime:SECONDS|]
==== SECONDS
<eucode>
include std/datetime.e
namespace datetime
public enum SECONDS
</eucode>

Seconds




@[:datetime:DATE|]
==== DATE
<eucode>
include std/datetime.e
namespace datetime
public enum DATE
</eucode>

Date




=== Types


@[:datetime:datetime|]
==== datetime
<eucode>
include std/datetime.e
namespace datetime
public type datetime(object o)
</eucode>

  datetime type

===== Parameters:
# ##obj## : any object, so no crash takes place.

===== Comments:
A datetime type consists of a sequence of length six in the form
##{year, month, day_of_month, hour, minute, second}##. Checks are made to guarantee
those values are in range.

===== Note:
All elements must be integers except for
seconds which could either integer or atom values.


=== Routines


@[:eu:time|]
==== time
<eucode>
<built-in> function time()
</eucode>

returns the number of seconds since some fixed point in the past.

===== Returns:
An **atom**, which represents an absolute number of seconds.

===== Comments:
Take the difference between two readings of ##time()## to measure, for example, how long
a section of code takes to execute.

On some machines, ##time()## can return a negative number. However, you can still use the
difference in calls to ##time()## to measure elapsed time.

===== Example 1:
<eucode>
constant ITERATIONS = 1000000
integer p
atom t0, loop_overhead

t0 = time()
for i = 1 to ITERATIONS do
    -- time an empty loop
end for
loop_overhead = time() - t0

t0 = time()
for i = 1 to ITERATIONS do
    p = power(2, 20)
end for
? (time() - t0 - loop_overhead)/ITERATIONS
-- calculates time (in seconds) for one call to power
</eucode>

===== See Also:
[[:date]], [[:now]]


@[:eu:date|]
==== date
<eucode>
<built-in> function date()
</eucode>

returns a sequence with information on the current date.

===== Returns:
A **sequence** of length 8, laid out as follows~:
# year  ~-- since 1900
# month ~-- January = 1
# day   ~-- day of month, starting at 1
# hour  ~-- 0 to 23
# minute ~-- 0 to 59
# second ~-- 0 to 59
# day of the week ~-- Sunday = 1
# day of the year ~-- January 1st = 1

===== Comments:
The value returned for the year is actually the number of years since 1900 (not the last 2 digits of the year).
In the year 2000 this value was 100. In 2001 it was 101, and so on.

===== Example 1:

<eucode>
now = date()
-- now has: {95,3,24,23,47,38,6,83}
-- i.e. Friday March 24, 1995 at 11:47:38pm, day 83 of the year
</eucode>

===== See Also:
[[:time]], [[:now]]


@[:datetime:from_date|]
==== from_date
<eucode>
include std/datetime.e
namespace datetime
public function from_date(sequence src)
</eucode>

  converts a sequence formatted according to the built-in ##date## function to a valid datetime
sequence.

===== Parameters:
# ##src## : a sequence which ##date## might have returned

===== Returns:
A **sequence**, more precisely a **datetime** corresponding to the same moment
in time.

===== Example 1:
<eucode>
d = from_date(date())
-- d is the current date and time
</eucode>

===== See Also:
[[:date]], [[:from_unix]], [[:now]], [[:new]]


@[:datetime:now|]
==== now
<eucode>
include std/datetime.e
namespace datetime
public function now()
</eucode>

  creates a new datetime value initialized with the current date and time.

===== Returns:
A **sequence**, more precisely a **datetime** corresponding to the current
moment in time.

===== Example 1:
<eucode>
dt = now()
-- dt is the current date and time
</eucode>

===== See Also:
[[:from_date]], [[:from_unix]], [[:new]], [[:new_time]], [[:now_gmt]]


@[:datetime:now_gmt|]
==== now_gmt
<eucode>
include std/datetime.e
namespace datetime
public function now_gmt()
</eucode>

  create a new datetime value that falls into the Greenwich Mean Time (GMT) timezone.

===== Comments:
This function will return a datetime that is GMT no matter what timezone the system
is running under.

===== Example 1:
<eucode>
dt = now_gmt()
-- If local time was July 16th, 2008 at 10:34pm CST
-- dt would be July 17th, 2008 at 03:34pm GMT
</eucode>

===== See Also:
[[:now]]


@[:datetime:new|]
==== new
<eucode>
include std/datetime.e
namespace datetime
public function new(integer year = 0, integer month = 0, integer day = 0, integer hour = 0,
        integer minute = 0, atom second = 0)
</eucode>

  creates a new datetime value.

!! TODO: test default parameter usage

===== Parameters:
# ##year##   ~-- the full year.
# ##month##  ~-- the month (1-12).
# ##day##    ~-- the day of the month (1-31).
# ##hour##   ~-- the hour (0-23) (defaults to 0)
# ##minute## ~-- the minute (0-59) (defaults to 0)
# ##second## ~-- the second (0-59) (defaults to 0)

===== Example 1:
<eucode>
dt = new(2010, 1, 1, 0, 0, 0)
-- dt is Jan 1st, 2010
</eucode>

===== See Also:
[[:from_date]], [[:from_unix]], [[:now]], [[:new_time]]


@[:datetime:new_time|]
==== new_time
<eucode>
include std/datetime.e
namespace datetime
public function new_time(integer hour, integer minute, atom second)
</eucode>

  creates a new datetime value with a date of zeros.

===== Parameters:
# ##hour## : is the hour (0-23)
# ##minute## : is the minute (0-59)
# ##second## : is the second (0-59)

===== Example 1:
<eucode>
dt = new_time(10, 30, 55)
dt is 10:30:55 AM
</eucode>

===== See Also:
[[:from_date]], [[:from_unix]], [[:now]], [[:new]]


@[:datetime:weeks_day|]
==== weeks_day
<eucode>
include std/datetime.e
namespace datetime
public function weeks_day(datetime dt)
</eucode>

  gets the day of week of the datetime ##dt##.

===== Parameters:
# ##dt## : a datetime to be queried.

===== Returns:
An **integer**, between 1 (Sunday) and 7 (Saturday).

===== Example 1:
<eucode>
d = new(2008, 5, 2, 0, 0, 0)
day = weeks_day(d) -- day is 6 because May 2, 2008 is a Friday.
</eucode>


@[:datetime:years_day|]
==== years_day
<eucode>
include std/datetime.e
namespace datetime
public function years_day(datetime dt)
</eucode>

  gets the Julian day of year of the supplied date.

===== Parameters:
# ##dt## : a datetime to be queried.

===== Returns:
An **integer**, between 1 and 366.

===== Comments:
For dates earlier than 1800, this routine may give inaccurate results if the date
applies to a country other than United Kingdom or a former colony thereof. The
change from Julian to Gregorian calendar took place much earlier in some other
European countries.

===== Example 1:
<eucode>
d = new(2008, 5, 2, 0, 0, 0)
day = years_day(d) -- day is 123
</eucode>


@[:datetime:is_leap_year|]
==== is_leap_year
<eucode>
include std/datetime.e
namespace datetime
public function is_leap_year(datetime dt)
</eucode>

  determines if ##dt## falls within leap year.

===== Parameters:
# ##dt## : a datetime to be queried.

===== Returns:
An **integer**, of 1 if leap year, otherwise 0.

===== Example 1:
<eucode>
d = new(2008, 1, 1, 0, 0, 0)
? is_leap_year(d) -- prints 1
d = new(2005, 1, 1, 0, 0, 0)
? is_leap_year(d) -- prints 0
</eucode>

===== See Also:
[[:days_in_month]]


@[:datetime:days_in_month|]
==== days_in_month
<eucode>
include std/datetime.e
namespace datetime
public function days_in_month(datetime dt)
</eucode>

  returns the number of days in the month of ##dt##.

===== Comments:
This takes into account leap year.

===== Parameters:
# ##dt## : a datetime to be queried.

===== Example 1:
<eucode>
d = new(2008, 1, 1, 0, 0, 0)
? days_in_month(d) -- 31
d = new(2008, 2, 1, 0, 0, 0) -- Leap year
? days_in_month(d) -- 29
</eucode>

===== See Also:
[[:is_leap_year]]


@[:datetime:days_in_year|]
==== days_in_year
<eucode>
include std/datetime.e
namespace datetime
public function days_in_year(datetime dt)
</eucode>

  returns the number of days in the year of ##dt##.

===== Comments:
This takes into account leap year.

===== Parameters:
# ##dt## : a datetime to be queried.

===== Example 1:
<eucode>
d = new(2007, 1, 1, 0, 0, 0)
? days_in_year(d) -- 365
d = new(2008, 1, 1, 0, 0, 0) -- leap year
? days_in_year(d) -- 366
</eucode>

===== See Also:
[[:is_leap_year]], [[:days_in_month]]


@[:datetime:to_unix|]
==== to_unix
<eucode>
include std/datetime.e
namespace datetime
public function to_unix(datetime dt)
</eucode>

  converts a datetime value to the //Unix// numeric format (seconds since ##EPOCH_1970##).

===== Parameters:
# ##dt## : a datetime to be queried.

===== Returns:
An **atom**, so this will not overflow during the winter 2038-2039.


===== Example 1:
<eucode>
secs_since_epoch = to_unix(now())
-- secs_since_epoch is equal to the current seconds since epoch
</eucode>

===== See Also:
[[:from_unix]], [[:format]]


@[:datetime:from_unix|]
==== from_unix
<eucode>
include std/datetime.e
namespace datetime
public function from_unix(atom unix)
</eucode>

  creates a datetime value from the //Unix// numeric format (seconds since EPOCH).

===== Parameters:
# ##unix## : an atom, counting seconds elapsed since EPOCH.

===== Returns:
A **sequence**, more precisely a **datetime** representing the same moment
in time.

===== Example 1:
<eucode>
d = from_unix(0)
-- d is 1970-01-01 00:00:00  (zero seconds since EPOCH)
</eucode>

===== See Also:
[[:to_unix]], [[:from_date]], [[:now]], [[:new]]


@[:datetime:format|]
==== format
<eucode>
include std/datetime.e
namespace datetime
public function format(datetime d, sequence pattern = "%Y-%m-%d %H:%M:%S")
</eucode>

  formats the date according to the format pattern string.

===== Parameters:
# ##d## : a datetime which is to be printed out
# ##pattern## : a format string, similar to the ones ##sprintf## uses, but with
some Unicode encoding. The default is ##"%Y-%m-%d %H:%M:%S"##.

===== Returns:
A **string**, with the date ##d## formatted according to the specification in ##pattern##.

===== Comments:
Pattern string can include the following specifiers~:

* ##~%%## ~-- a literal %
* ##%a## ~-- locale's abbreviated weekday name (e.g., Sun)
* ##%A## ~-- locale's full weekday name (e.g., Sunday)
* ##%b## ~-- locale's abbreviated month name (e.g., Jan)
* ##%B## ~-- locale's full month name (e.g., January)
* ##%C## ~-- century; like %Y, except omit last two digits (e.g., 21)
* ##%d## ~-- day of month (e.g, 01)
* ##%H## ~-- hour (00..23)
* ##%I## ~-- hour (01..12)
* ##%j## ~-- day of year (001..366)
* ##%k## ~-- hour ( 0..23)
* ##%l## ~-- hour ( 1..12)
* ##%m## ~-- month (01..12)
* ##%M## ~-- minute (00..59)
* ##%p## ~-- locale's equivalent of either AM or PM; blank if not known
* ##%P## ~-- like %p, but lower case
* ##%s## ~-- seconds since 1970-01-01 00:00:00 UTC
* ##%S## ~-- second (00..60)
* ##%u## ~-- day of week (1..7); 1 is Monday
* ##%w## ~-- day of week (0..6); 0 is Sunday
* ##%y## ~-- last two digits of year (00..99)
* ##%Y## ~-- year

===== Example 1:
<eucode>
d = new(2008, 5, 2, 12, 58, 32)
s = format(d, "%Y-%m-%d %H:%M:%S")
-- s is "2008-05-02 12:58:32"
</eucode>

===== Example 2:
<eucode>
d = new(2008, 5, 2, 12, 58, 32)
s = format(d, "%A, %B %d '%y %H:%M%p")
-- s is "Friday, May 2 '08 12:58PM"
</eucode>

===== See Also:
[[:to_unix]], [[:parse]]



@[:datetime:parse|]
==== parse
<eucode>
include std/datetime.e
namespace datetime
public function parse(sequence val, sequence fmt = "%Y-%m-%d %H:%M:%S",
        integer yylower = - 80)
</eucode>

  parses a datetime string according to the given format.

===== Parameters:
# ##val## : string datetime value
# ##fmt## : datetime format. Default is ##"%Y-%m-%d %H:%M:%S"##
# ##yysplit## : Set the maximum difference from the current year when parsing
a two digit year. Defaults to -80/+20.

===== Returns:
A **datetime**, value.

===== Comments:
Only a subset of the format specification is currently supported~:

* ##%d## ~--  day of month (e.g, 01)
* ##%H## ~--  hour (00..23)
* ##%m## ~--  month (01..12)
* ##%M## ~--  minute (00..59)
* ##%S## ~--  second (00..60)
* ##%y## ~--  2-digit year (YY)
* ##%Y## ~--  4-digit year (CCYY)

More format codes will be added in future versions.

All non-format characters in the format string are ignored and are not
matched against the input string.

All non-digits in the input string are ignored.

Parsing Two Digit Years~:

When parsing a two digit year ##parse## has to make a decision if a given year
is in the past or future. For example, 10/18/44. Is that Oct 18, 1944 or
Oct 18, 2044. A common rule has come about for this purpose and that is the -80/+20
rule. Based on research it was found that more historical events are recorded than
future events, thus it favors history rather than future. Some other applications may
require a different rule, thus the ##yylower## parameter can be supplied.

Assuming today is 12/22/2010 here is an example of the -80/+20 rule~:
|| YY || Diff   || CCYY ||
| 18   | -92/+8  |  2018 |
| 95   | -15/+85 |  1995 |
| 33   | -77/+23 |  1933 |
| 29   | -81/+19 |  2029 |

Another rule in use is the -50/+50 rule. Therefore, if you supply -50 to the ##yylower##
to set the lower bounds, some examples may be (given that today is 12/22/2010)~:
|| YY || Diff   || CCYY ||
| 18   | -92/+8  |  2018 |
| 95   | -15/+85 |  1995 |
| 33   | -77/+23 |  2033 |
| 29   | -81/+19 |  2029 |

===== Note:
* Since 4.0.1 ~-- 2-digit year parsing and ##yylower## parameter.

===== Example 1:
<eucode>
datetime d = parse("05/01/2009 10:20:30", "%m/%d/%Y %H:%M:%S")
-- d is { 2009, 5, 1, 10, 20, 30 }
</eucode>

===== Example 2:
<eucode>
datetime d = parse("05/01/44", "%m/%d/%y", -50) -- -50/+50 rule
-- d is { 2044, 5, 14, 0, 0, 0 }
</eucode>

===== See Also:
[[:format]]



@[:datetime:add|]
==== add
<eucode>
include std/datetime.e
namespace datetime
public function add(datetime dt, object qty, integer interval)
</eucode>

  adds a number of //intervals// to a datetime.

===== Parameters:
# ##dt## : the base datetime
# ##qty## : the number of //intervals// to add. It should be positive.
# ##interval## : which kind of interval to add.

===== Returns:
A **sequence**, more precisely a **datetime** representing the new moment in time.

===== Comments:
Please see Constants for Date and Time for a reference of valid intervals.

Do not confuse the item access constants (such as ##YEAR##, ##MONTH##, ##DAY## ) with the
interval constants (##YEARS##, ##MONTHS##, ##DAYS## ).

When adding ##MONTHS##, it is a calendar based addition. For instance, a date of
5/2/2008 with 5 ##MONTHS## added will become 10/2/2008. ##MONTHS## does not compute the number
of days per each month and the average number of days per month.

When adding ##YEARS##, leap year is taken into account. Adding 4 ##YEARS## to a date may result
in a different day of month number due to leap year.

===== Example 1:
<eucode>
d2 = add(d1, 35, SECONDS) -- add 35 seconds to d1
d2 = add(d1, 7, WEEKS)    -- add 7 weeks to d1
d2 = add(d1, 19, YEARS)   -- add 19 years to d1
</eucode>

===== See Also:
[[:subtract]], [[:diff]]


@[:datetime:subtract|]
==== subtract
<eucode>
include std/datetime.e
namespace datetime
public function subtract(datetime dt, atom qty, integer interval)
</eucode>

  subtracts a number of //intervals// to a base datetime.

===== Parameters:
# ##dt## : the base datetime
# ##qty## : the number of //intervals// to subtract. It should be positive.
# ##interval## : which kind of interval to subtract.

===== Returns:
A **sequence**, more precisely a **datetime** representing the new moment
in time.

===== Comments:
Please see Constants for Date and Time for a reference of valid intervals.

See the function ##add## for more information on adding and subtracting date
intervals

===== Example 1:
<eucode>
dt2 = subtract(dt1, 18, MINUTES) -- subtract 18 minutes from dt1
dt2 = subtract(dt1, 7, MONTHS)   -- subtract 7 months from dt1
dt2 = subtract(dt1, 12, HOURS)   -- subtract 12 hours from dt1
</eucode>

===== See Also:
[[:add]], [[:diff]]


@[:datetime:diff|]
==== diff
<eucode>
include std/datetime.e
namespace datetime
public function diff(datetime dt1, datetime dt2)
</eucode>

  computes the difference, in seconds, between two dates.

===== Parameters:
# ##dt1## : the end datetime
# ##dt2## : the start datetime

===== Returns:
An **atom**, the number of seconds elapsed from ##dt2## to ##dt1##.

===== Comments:
##dt2## is subtracted from ##dt1##, therefore, you can come up with a negative
value.

===== Example 1:
<eucode>
d1 = now()
sleep(15)  -- sleep for 15 seconds
d2 = now()

i = diff(d1, d2) -- i is 15
</eucode>

===== See Also:
[[:add]], [[:subtract]]



!!CONTEXT:../include/std/filesys.e
!!namespace:filesys
%%output = std_filesys

== File System

Cross platform file operations for Euphoria

<<LEVELTOC level=2 depth=4>>


=== Constants


@[:filesys:SLASH|]
==== SLASH
<eucode>
public constant SLASH
</eucode>

Current platform's path separator character

===== Comments:
When on //Windows//, ##'~\\'##. When on //Unix//, ##'/'##.



@[:filesys:SLASHES|]
==== SLASHES
<eucode>
public constant SLASHES
</eucode>

Current platform's possible path separators. This is slightly different
in that on //Windows// the path separators variable contains
##~\~\## as well as ##~:## and ##/## as newer //Windows// versions support
##/## as a path separator. On //Unix// systems, it only contains ##/##.




@[:filesys:EOLSEP|]
==== EOLSEP
<eucode>
public constant EOLSEP
</eucode>

Current platform's newline string: ##"\n"## on //Unix//, else ##"\r\n"##.


@[:filesys:EOL|]
==== EOL
<eucode>
public constant EOL
</eucode>

All platform's newline character: ##'\n'##. When text lines are read the native
platform's EOLSEP string is replaced by a single character EOL.


@[:filesys:PATHSEP|]
==== PATHSEP
<eucode>
public constant PATHSEP
</eucode>

Current platform's path separator character: ##:## on //Unix//, else ##;##.


@[:filesys:NULLDEVICE|]
==== NULLDEVICE
<eucode>
public constant NULLDEVICE
</eucode>

Current platform's null device path: ##/dev/null## on //Unix//, else ##NUL:##.


@[:filesys:SHARED_LIB_EXT|]
==== SHARED_LIB_EXT
<eucode>
public constant SHARED_LIB_EXT
</eucode>

Current platform's shared library extension. For instance it can be ##dll##,
##so## or ##dylib## depending on the platform.






























=== Directory Handling


@[:filesys:D_NAME|]
==== D_NAME
<eucode>
include std/filesys.e
namespace filesys
public enum D_NAME
</eucode>





@[:filesys:D_ATTRIBUTES|]
==== D_ATTRIBUTES
<eucode>
include std/filesys.e
namespace filesys
public enum D_ATTRIBUTES
</eucode>





@[:filesys:D_SIZE|]
==== D_SIZE
<eucode>
include std/filesys.e
namespace filesys
public enum D_SIZE
</eucode>





@[:filesys:D_YEAR|]
==== D_YEAR
<eucode>
include std/filesys.e
namespace filesys
public enum D_YEAR
</eucode>





@[:filesys:D_MONTH|]
==== D_MONTH
<eucode>
include std/filesys.e
namespace filesys
public enum D_MONTH
</eucode>





@[:filesys:D_DAY|]
==== D_DAY
<eucode>
include std/filesys.e
namespace filesys
public enum D_DAY
</eucode>





@[:filesys:D_HOUR|]
==== D_HOUR
<eucode>
include std/filesys.e
namespace filesys
public enum D_HOUR
</eucode>





@[:filesys:D_MINUTE|]
==== D_MINUTE
<eucode>
include std/filesys.e
namespace filesys
public enum D_MINUTE
</eucode>





@[:filesys:D_SECOND|]
==== D_SECOND
<eucode>
include std/filesys.e
namespace filesys
public enum D_SECOND
</eucode>





@[:filesys:D_MILLISECOND|]
==== D_MILLISECOND
<eucode>
include std/filesys.e
namespace filesys
public enum D_MILLISECOND
</eucode>





@[:filesys:D_ALTNAME|]
==== D_ALTNAME
<eucode>
include std/filesys.e
namespace filesys
public enum D_ALTNAME
</eucode>





@[:filesys:W_BAD_PATH|]
==== W_BAD_PATH
<eucode>
public constant W_BAD_PATH
</eucode>

Bad path error code. See [[:walk_dir]]


@[:filesys:W_SKIP_DIRECTORY|]
==== W_SKIP_DIRECTORY
<eucode>
public constant W_SKIP_DIRECTORY
</eucode>




@[:filesys:dir|]
==== dir
<eucode>
include std/filesys.e
namespace filesys
public function dir(sequence name)
</eucode>

  returns directory information for the specified file or directory.

===== Parameters:
# ##name## : a sequence, the name to be looked up in the file system.

===== Returns:
An **object**,  -1 if no match found, else a sequence of sequence entries

===== Errors:
The length of ##name## should not exceed 1_024 characters.

===== Comments:
##name## can also contain ##*## and ##?## wildcards to select multiple files.

The returned information is similar to what you would get from the DIR command. A sequence
is returned where each element is a sequence that describes one file or subdirectory.

If ##name## refers to a **directory** you may have entries for "." and "..", just as with the
DIR command. If it refers to an existing **file**, and has no wildcards, then the returned
sequence will have just one entry (that is its length will be ##1##). If ##name## contains wildcards
you may have multiple entries.

Each entry contains the name, attributes and file size as well as
the time of the last modification.

You can refer to the elements of an entry with the following constants~:

<eucode>
public constant 
    -- File Attributes
    D_NAME       = 1,
    D_ATTRIBUTES = 2,
    D_SIZE       = 3,
    D_YEAR       = 4,
    D_MONTH      = 5,
    D_DAY        = 6,
    D_HOUR       = 7,
    D_MINUTE     = 8,
    D_SECOND     = 9,
    D_MILLISECOND = 10,
    D_ALTNAME    = 11
</eucode>

The attributes element is a string sequence containing characters chosen from~:

|| Attribute || Description ||
| 'd'         | directory
| 'r'         | read only file
| 'h'         | hidden file
| 's'         | system file
| 'v'         | volume-id entry
| 'a'         | archive file
| 'c'         | compressed file
| 'e'         | encrypted file
| 'N'         | not indexed
| 'D'         | a device name
| 'O'         | offline
| 'R'         | reparse point or symbolic link
| 'S'         | sparse file
| 'T'         | temporary file
| 'V'         | virtual file

A normal file without special attributes would just have an empty string, ##""##, in this field.

The top level directory ( therefore c:\ does not have "." or ".." entries).

This function is often used just to test if a file or directory exists.

Under //Windows//, the argument can have a long file or directory name anywhere in
the path.

Under //Unix//, the only attribute currently available is ##'d'## and the milliseconds
are always zero.

//Windows//: The file name returned in ##[D_NAME]## will be a long file name. If ##[D_ALTNAME]##
is not zero, it contains the 'short' name of the file.

===== Example 1:
<eucode>
d = dir(current_dir())

-- d might have:
--  {
--    {".",    "d",     0  1994, 1, 18,  9, 30, 02},
--    {"..",   "d",     0  1994, 1, 18,  9, 20, 14},
--    {"fred", "ra", 2350, 1994, 1, 22, 17, 22, 40},
--    {"sub",  "d" ,    0, 1993, 9, 20,  8, 50, 12}
--  }

d[3][D_NAME] would be "fred"
</eucode>

===== See Also:
[[:walk_dir]]



@[:filesys:current_dir|]
==== current_dir
<eucode>
include std/filesys.e
namespace filesys
public function current_dir()
</eucode>

  Return the name of the current working directory.

===== Returns:
A **sequence**, the name of the current working directory

===== Comments:
There will be no slash or backslash on the end of the current directory, except under
//Windows//, at the top-level of a drive (such as ##C:\##).

===== Example 1:
<eucode>
sequence s
s = current_dir()
-- s would have "C:\EUPHORIA\DOC" if you were in that directory
</eucode>

===== See Also:
[[:dir]], [[:chdir]]


@[:filesys:chdir|]
==== chdir
<eucode>
include std/filesys.e
namespace filesys
public function chdir(sequence newdir)
</eucode>

  sets a new value for the current directory.

===== Parameters:
##newdir## : a sequence, the name for the new working directory.

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
By setting the current directory, you can refer to files in that directory using just
the file name.

The [[:current_dir]] function will return the name of the current directory.

On //Windows// the current directory is a public property shared
by all the processes running under one shell. On //Unix// a subprocess
can change the current directory for itself, but this will not
affect the current directory of its parent process.

===== Example 1:
<eucode>
if chdir("c:\\euphoria") then
    f = open("readme.doc", "r")
else
    puts(STDERR, "Error: No euphoria directory?\n")
end if
</eucode>

===== See Also:
[[:current_dir]], [[:dir]]


@[:filesys:my_dir|]
==== my_dir
<eucode>
include std/filesys.e
namespace filesys
public integer my_dir
</eucode>

  **Deprecated**, so therefore not documented.


@[:filesys:walk_dir|]
==== walk_dir
<eucode>
include std/filesys.e
namespace filesys
public function walk_dir(sequence path_name, object your_function,
        integer scan_subdirs = types :FALSE,
        object dir_source = types :NO_ROUTINE_ID)
</eucode>

  Generalized Directory Walker

===== Parameters:
# ##path_name## : a sequence, the name of the directory to walk through
# ##your_function## : the routine id of a function that will receive each path
returned from the result of ##dir_source##, one at a time.
Optionally, to include extra data for your function, ##your_function##
can be a 2 element sequence, with the routine_id as the first element and other data
as the second element.
# ##scan_subdirs## : an optional integer, ##1## to also walk though subfolders, ##0## (the default) to skip them all.
# ##dir_source## : an optional integer. A routine_id of a user-defined routine that
returns the list of paths to pass to ##your_function##. If omitted,
the [[:dir]]() function is used. If your routine requires an extra parameter,
##dir_source## may be a 2 element sequence where the first element is the
routine id and the second is the extra data to be passed as the second parameter
to your function.

===== Returns:
An **object**,
* ##0## on success
* ##W_BAD_PATH##  an error occurred
* anything else the custom function returned something to stop [[:walk_dir]].

===== Comments:
This routine will "walk" through a directory named ##path_name##. For each entry in the
directory, it will call a function, whose routine_id is ##your_function##.
If ##scan_subdirs## is non-zero (TRUE), then the subdirectories in
##path_name## will be walked through recursively in the very same way.

The routine that you supply should accept two sequences, the //path name// and //dir// entry for
each file and subdirectory. It should return ##0## to keep going, ##W_SKIP_DIRECTORY## to avoid
scan the contents of the supplied path name (if a directory), or non-zero to stop
##walk_dir##. Returning ##W_BAD_PATH## is taken as denoting some error.

This mechanism allows you to write a simple function that handles one file at a time,
while ##walk_dir## handles the process of walking through all the files and subdirectories.

By default, the files and subdirectories will be visited in alphabetical order. To use
a different order, use the ##dir_source## to pass the routine_id of your own modified
[[:dir]] function that sorts the directory entries differently.

The path that you supply to ##walk_dir## must not contain wildcards (##*## or ##?##). Only a
single directory (and its subdirectories) can be searched at one time.

For //Windows// systems, any ##'/'## characters in ##path_name## are replaced with ##'\'##.

All trailing slash and whitespace characters are removed from ##path_name##.

===== Example 1:
<eucode>
function look_at(sequence path_name, sequence item)
-- this function accepts two sequences as arguments
-- it displays all C/C++ source files and their sizes
    if find('d', item[D_ATTRIBUTES]) then
        -- Ignore directories
        if find('s', item[D_ATTRIBUTES]) then
           return W_SKIP_DIRECTORY -- Don't recurse a system directory
        else
           return 0 -- Keep processing as normal
        end if
    end if
    if not find(fileext(item[D_NAME]), {"c","h","cpp","hpp","cp"}) then
        return 0 -- ignore non-C/C++ files
    end if
    printf(STDOUT, "%s%s%s: %d\n",
           {path_name, {SLASH}, item[D_NAME], item[D_SIZE]})
    return 0 -- keep going
end function

function mysort(sequence path)
	object d
	
	d = dir(path)
	if atom(d) then
		return d
	end if
	-- Sort in descending file size.
 return sort_columns(d, {-D_SIZE})
end function

exit_code = walk_dir("C:\\MYFILES\\", routine_id("look_at"), TRUE, 
                                                        routine_id("mysort"))
</eucode>

===== See Also:
[[:dir]], [[:sort]], [[:sort_columns]]


@[:filesys:create_directory|]
==== create_directory
<eucode>
include std/filesys.e
namespace filesys
public function create_directory(sequence name, integer mode = 448, integer mkparent = 1)
</eucode>

  creates a new directory.

===== Parameters:
# ##name## : a sequence, the name of the new directory to create
# ##mode## : on //Unix// systems, permissions for the new directory. Default is
##448## (all rights for owner, none for others).
# ##mkparent## : If true (default) the parent directories are also created
if needed.

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
##mode## is ignored on //Windows// platforms.

===== Example 1:
<eucode>
if not create_directory("the_new_folder") then
	crash("Filesystem problem - could not create the new folder")
end if

-- This example will also create "myapp/" and "myapp/interface/" 
-- if they don't exist.
if not create_directory("myapp/interface/letters") then
	crash("Filesystem problem - could not create the new folder")
end if

-- This example will NOT create "myapp/" and "myapp/interface/" 
-- if they don't exist.
if not create_directory("myapp/interface/letters",,0) then
	crash("Filesystem problem - could not create the new folder")
end if
</eucode>

===== See Also:
[[:remove_directory]], [[:chdir]]


@[:filesys:create_file|]
==== create_file
<eucode>
include std/filesys.e
namespace filesys
public function create_file(sequence name)
</eucode>

  Create a new file.

===== Parameters:
# ##name## : a sequence, the name of the new file to create

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
* The created file will be empty, that is it has a length of zero.
* The created file will not be open when this returns.

===== Example 1:
<eucode>
if not create_file("the_new_file") then
	crash("Filesystem problem - could not create the new file")
end if
</eucode>

===== See Also:
[[:create_directory]]


@[:filesys:delete_file|]
==== delete_file
<eucode>
include std/filesys.e
namespace filesys
public function delete_file(sequence name)
</eucode>

  deletes a file.

===== Parameters:
# ##name## : a sequence, the name of the file to delete.

===== Returns:
An **integer**, ##0## on failure, ##1## on success.


@[:filesys:curdir|]
==== curdir
<eucode>
include std/filesys.e
namespace filesys
public function curdir(integer drive_id = 0)
</eucode>

  Returns the current directory, with a trailing SLASH

===== Parameters:
# ##drive_id## : For //Windows// systems only. This is the Drive letter to
to get the current directory of. If omitted, the current drive is used.

===== Returns:
A **sequence**, the current directory.

===== Comments:
//Windows// maintains a current directory for each disk drive. You
would use this routine if you wanted the current directory for a drive that
may not be the current drive.

For //Unix// systems, this is simply ignored because there is only one current
directory at any time on //Unix//.

===== Note:
This always ensures that the returned value has a trailing //SLASH//
character.

===== Example 1:
<eucode>
res = curdir('D') -- Find the current directory on the D: drive.
-- res might be "D:\backup\music\"
res = curdir()    -- Find the current directory on the current drive.
-- res might be "C:\myapp\work\"
</eucode>


@[:filesys:init_curdir|]
==== init_curdir
<eucode>
include std/filesys.e
namespace filesys
public function init_curdir()
</eucode>

  returns the original current directory.

===== Parameters:
# None.

===== Returns:
A **sequence**, the current directory at the time the program started running.

===== Comments:
You would use this if the program might change the current directory during
its processing and you wanted to return to the original directory.

===== Note:
This always ensures that the returned value has a trailing ##SLASH##
character.

===== Example 1:
<eucode>
res = init_curdir() -- Find the original current directory.
</eucode>


@[:filesys:clear_directory|]
==== clear_directory
<eucode>
include std/filesys.e
namespace filesys
public function clear_directory(sequence path, integer recurse = 1)
</eucode>

  clears (deletes) a directory of all files, but retaining sub-directories.

===== Parameters:
# ##name## : a sequence, the name of the directory whose files you want to remove.
# ##recurse## : an integer, whether or not to remove files in the
directory's sub-directories. If ##0## then this function is identical
to ##remove_directory##. If ##1##, then we recursively delete the
directory and its contents. Defaults to ##1## .

===== Returns:
An **integer**, ##0## on failure, otherwise the number of files plus ##1## .

===== Comments:
This never removes a directory. It only ever removes files. It is used to
clear a directory structure of all existing files, leaving the structure
intact.

===== Example 1:
<eucode>
integer cnt = clear_directory("the_old_folder")
if cnt = 0 then
	crash("Filesystem problem - could not remove one or more of the files.")
end if
printf(1, "Number of files removed: %d\n", cnt - 1)
</eucode>

===== See Also:
[[:remove_directory]], [[:delete_file]]


@[:filesys:remove_directory|]
==== remove_directory
<eucode>
include std/filesys.e
namespace filesys
public function remove_directory(sequence dir_name, integer force = 0)
</eucode>

  removes a directory.

===== Parameters:
# ##name## : a sequence, the name of the directory to remove.
# ##force## : an integer, if ##1## this will also remove files and
sub-directories in the directory. The default is
##0##, which means that it will only remove the
directory if it is already empty.

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Example 1:
<eucode>
if not remove_directory("the_old_folder") then
	crash("Filesystem problem - could not remove the old folder")
end if
</eucode>

===== See Also:
[[:create_directory]], [[:chdir]], [[:clear_directory]]


=== File Name Parsing


@[:filesys:PATH_DIR|]
==== PATH_DIR
<eucode>
include std/filesys.e
namespace filesys
public enum PATH_DIR
</eucode>





@[:filesys:PATH_FILENAME|]
==== PATH_FILENAME
<eucode>
include std/filesys.e
namespace filesys
public enum PATH_FILENAME
</eucode>





@[:filesys:PATH_BASENAME|]
==== PATH_BASENAME
<eucode>
include std/filesys.e
namespace filesys
public enum PATH_BASENAME
</eucode>





@[:filesys:PATH_FILEEXT|]
==== PATH_FILEEXT
<eucode>
include std/filesys.e
namespace filesys
public enum PATH_FILEEXT
</eucode>





@[:filesys:PATH_DRIVEID|]
==== PATH_DRIVEID
<eucode>
include std/filesys.e
namespace filesys
public enum PATH_DRIVEID
</eucode>





@[:filesys:pathinfo|]
==== pathinfo
<eucode>
include std/filesys.e
namespace filesys
public function pathinfo(sequence path, integer std_slash = 0)
</eucode>

  parses a fully qualified pathname.
===== Parameters:
# ##path## : a sequence, the path to parse

===== Returns:
A **sequence**, of length five. Each of these elements is a string:
* The path name. For //Windows// this excludes the drive id.
* The full unqualified file name
* the file name, without extension
* the file extension
* the drive id

===== Comments:

The host operating system path separator is used in the parsing.

===== Example 1:
<eucode>
-- WINDOWS
info = pathinfo("C:\\euphoria\\docs\\readme.txt")
-- info is {"C:\\euphoria\\docs", "readme.txt", "readme", "txt", "C"}
</eucode>

===== Example 2:
<eucode>
-- Unix variants
info = pathinfo("/opt/euphoria/docs/readme.txt")
-- info is {"/opt/euphoria/docs", "readme.txt", "readme", "txt", ""}
</eucode>

===== Example 3:
<eucode>
-- no extension
info = pathinfo("/opt/euphoria/docs/readme")
-- info is {"/opt/euphoria/docs", "readme", "readme", "", ""}
</eucode>

===== See Also:
[[:driveid]], [[:dirname]], [[:filename]], [[:fileext]],
[[:PATH_BASENAME]], [[:PATH_DIR]], [[:PATH_DRIVEID]], [[:PATH_FILEEXT]],
[[:PATH_FILENAME]]


@[:filesys:dirname|]
==== dirname
<eucode>
include std/filesys.e
namespace filesys
public function dirname(sequence path, integer pcd = 0)
</eucode>

  returns the directory name of a fully qualified filename.

===== Parameters:
# ##path## : the path from which to extract information
# ##pcd## : If not zero and there is no directory name in ##path##
then "." is returned. The default (##0##) will just return
any directory name in ##path##.

===== Returns:
A **sequence**, the full file name part of ##path##.

===== Comments:
The host operating system path separator is used.

===== Example 1:
<eucode>
fname = dirname("/opt/euphoria/docs/readme.txt")
-- fname is "/opt/euphoria/docs"
</eucode>

===== See Also:
[[:driveid]], [[:filename]], [[:pathinfo]]


@[:filesys:pathname|]
==== pathname
<eucode>
include std/filesys.e
namespace filesys
public function pathname(sequence path)
</eucode>

  returns the directory name of a fully qualified filename.

===== Parameters:
# ##path## : the path from which to extract information
# ##pcd## : If not zero and there is no directory name in ##path##
then "." is returned. The default (##0##) will just return
any directory name in ##path##.

===== Returns:
A **sequence**, the full file name part of ##path##.

===== Comments:
The host operating system path separator is used.

===== Example 1:
<eucode>
fname = dirname("/opt/euphoria/docs/readme.txt")
-- fname is "/opt/euphoria/docs"
</eucode>

===== See Also:
[[:driveid]], [[:filename]], [[:pathinfo]]


@[:filesys:filename|]
==== filename
<eucode>
include std/filesys.e
namespace filesys
public function filename(sequence path)
</eucode>

  returns the file name portion of a fully qualified filename.

===== Parameters:
# ##path## : the path from which to extract information

===== Returns:
A **sequence**, the file name part of ##path##.

===== Comments:
The host operating system path separator is used.

===== Example 1:
<eucode>
fname = filename("/opt/euphoria/docs/readme.txt")
-- fname is "readme.txt"
</eucode>

===== See Also:
[[:pathinfo]], [[:filebase]], [[:fileext]]


@[:filesys:filebase|]
==== filebase
<eucode>
include std/filesys.e
namespace filesys
public function filebase(sequence path)
</eucode>

  returns the base filename of path.

===== Parameters:
# ##path## : the path from which to extract information

===== Returns:
A **sequence**, the base file name part of ##path##.

TODO: Test

===== Example 1:
<eucode>
base = filebase("/opt/euphoria/readme.txt")
-- base is "readme"
</eucode>

===== See Also:
[[:pathinfo]], [[:filename]], [[:fileext]]


@[:filesys:fileext|]
==== fileext
<eucode>
include std/filesys.e
namespace filesys
public function fileext(sequence path)
</eucode>

  returns the file extension of a fully qualified filename.

===== Parameters:
# ##path## : the path from which to extract information

===== Returns:
A **sequence**, the file extension part of ##path##.

===== Comments:
The host operating system path separator is used.

===== Example 1:
<eucode>
fname = fileext("/opt/euphoria/docs/readme.txt")
-- fname is "txt"
</eucode>

===== See Also:
[[:pathinfo]], [[:filename]], [[:filebase]]


@[:filesys:driveid|]
==== driveid
<eucode>
include std/filesys.e
namespace filesys
public function driveid(sequence path)
</eucode>

  returns the drive letter of the path on //Windows// platforms.

===== Parameters:
# ##path## : the path from which to extract information

===== Returns:
A **sequence**, the file extension part of ##path##.

TODO: Test

===== Example 1:
<eucode>
letter = driveid("C:\\EUPHORIA\\Readme.txt")
-- letter is "C"
</eucode>

===== See Also:
[[:pathinfo]], [[:dirname]], [[:filename]]


@[:filesys:defaultext|]
==== defaultext
<eucode>
include std/filesys.e
namespace filesys
public function defaultext(sequence path, sequence defext)
</eucode>

  returns the supplied filepath with the supplied extension, if
the filepath does not have an extension already.

===== Parameters:
# ##path## : the path to check for an extension.
# ##defext## : the extension to add if ##path## does not have one.

===== Returns:
A **sequence**, the path with an extension.

===== Example 1:
<eucode>
 -- ensure that the supplied path has an extension, 
 -- but if it doesn't use "tmp".
theFile = defaultext(UserFileName, "tmp")
</eucode>

===== See Also:
[[:pathinfo]]


@[:filesys:absolute_path|]
==== absolute_path
<eucode>
include std/filesys.e
namespace filesys
public function absolute_path(sequence filename)
</eucode>

  determines if the supplied string is an absolute path or a relative path.

===== Parameters:
# ##filename## : a sequence, the name of the file path

===== Returns:
An **integer**, ##0## if ##filename## is a relative path or ##1## otherwise.

===== Comments:
A //relative// path is one which is relative to the current directory and
an //absolute// path is one that doesn't need to know the current directory
to find the file.

===== Example 1:
<eucode>
? absolute_path("") -- returns 0
? absolute_path("/usr/bin/abc") -- returns 1
? absolute_path("\\temp\\somefile.doc") -- returns 1
? absolute_path("../abc") -- returns 0
? absolute_path("local/abc.txt") -- returns 0
? absolute_path("abc.txt") -- returns 0
? absolute_path("c:..\\abc") -- returns 0

-- The next two examples return 
-- 0 on Unix platforms and 
-- 1 on Microsoft platforms
? absolute_path("c:\\windows\\system32\\abc")
? absolute_path("c:/windows/system32/abc")
</eucode>


@[:filesys:AS_IS|]
==== AS_IS
<eucode>
include std/filesys.e
namespace filesys
public enum AS_IS
</eucode>





@[:filesys:TO_LOWER|]
==== TO_LOWER
<eucode>
include std/filesys.e
namespace filesys
public enum TO_LOWER
</eucode>





@[:filesys:CORRECT|]
==== CORRECT
<eucode>
include std/filesys.e
namespace filesys
public enum CORRECT
</eucode>





@[:filesys:TO_SHORT|]
==== TO_SHORT
<eucode>
include std/filesys.e
namespace filesys
public enum TO_SHORT
</eucode>





@[:filesys:case_flagset_type|]
==== case_flagset_type
<eucode>
include std/filesys.e
namespace filesys
public type case_flagset_type(integer x)
</eucode>



@[:filesys:canonical_path|]
==== canonical_path
<eucode>
include std/filesys.e
namespace filesys
public function canonical_path(sequence path_in, integer directory_given = 0,
        case_flagset_type case_flags = AS_IS)
</eucode>

  returns the full path and file name of the supplied file name.

===== Parameters:
# ##path_in## : A sequence. This is the file name whose full path you want.
#   ##directory_given## : An integer. This is zero if ##path_in## is
to be interpreted as a file specification otherwise it is assumed to be a
directory specification. The default is zero.
# ##case_flags## : An integer. This is a combination of flags.
AS_IS      =  Includes no flags
TO_LOWER   =  If passed will convert the part of the path not affected by
other case flags to lowercase.
CORRECT    =  If passed will correct the parts of the filepath that
exist in the current filesystem in parts of the filesystem
that is case insensitive.  This should  work on //Windows//
or SMB mounted volumes on //Unix// and all OS X filesystems.

TO_LOWER    =  If passed alone the entire path is converted to lowercase.
or_bits(TO_LOWER,CORRECT) = If these flags are passed together the the part that
exists has the case of that of the filesystem.  The part that
does not is converted to lower case.
TO_SHORT    =  If passed the elements of the path that exist are also converted
to their //Windows// short names if avaliable.

===== Returns:
A **sequence**, the full path and file name.

===== Comments:
* The supplied file/directory does not have to actually exist.
* ##path_in## can be enclosed in quotes, which will be stripped off.
* If ##path_in## begins with a tilde ##'~~'## then that is replaced by the
contents of ##$HOME## in //Unix// platforms and ##%HOMEDRIVE%%HOMEPATH%## in //Windows//.
* In //Windows// all ##'/'## characters are replaced by ##'\'## characters.
* Does not (yet) handle UNC paths or //Unix// links.


===== Example 1:
<eucode>
-- Assuming the current directory is "/usr/foo/bar" 
res = canonical_path("../abc.def")
-- res is now "/usr/foo/abc.def"
</eucode>

===== Example 2:
<eucode>
-- res is "C:\Program Files" on systems that have that directory.
res = canonical_path("c:\pRoGrAm FiLeS", CORRECT)
-- on Windows Vista this would be "c:\Program Files" for Vista uses lowercase for its drives.
</eucode>


@[:filesys:abbreviate_path|]
==== abbreviate_path
<eucode>
include std/filesys.e
namespace filesys
public function abbreviate_path(sequence orig_path, sequence base_paths = {})
</eucode>

  returns a path string to the supplied file which is shorter than the
given path string.

===== Parameters:
# ##orig_path## : A sequence. This is the path to a file.
# ##base_paths## : A sequence. This is an optional list of paths that may
prefix the original path. The default is an empty list.

===== Returns:
A **sequence**, an equivalent path to ##orig_path## which is shorter
than the supplied path. If a shorter one cannot be formed, then the
original path is returned.

===== Comments:
* This function is primarily used to get the shortest form of a file path
for output to a file or screen.
* It works by first trying to find if the ##orig_path## begins with any
of the ##base_paths##. If so it returns the parameter minus the
base path prefix.
* Next it checks if the ##orig_path## begins with the current directory path.
If so it returns the parameter minus the current directory path.
* Next it checks if it can form a relative path from the current directory
to the supplied file which is shorter than the parameter string.
* Failing all of that, it returns the original parameter.
* In //Windows// the shorter result has all ##'/'## characters are replaced by ##'\'##
characters.
* The supplied path does not have to actually exist.
* ##orig_path## can be enclosed in quotes, which will be stripped off.
* If ##orig_path## begins with a tilde ##'~~'## then that is replaced by the
contents of ##$HOME## in //Unix// platforms and ##%HOMEDRIVE%%HOMEPATH%## in //Windows//.


===== Example 1:
<eucode>
-- Assuming the current directory is "/usr/foo/bar" 
res = abbreviate_path("/usr/foo/abc.def")
-- res is now "../abc.def"
res = abbreviate_path("/usr/foo/bar/inc/abc.def")
-- res is now "inc/abc.def"
res = abbreviate_path("abc.def", {"/usr/foo"})
-- res is now "bar/abc.def"
</eucode>


@[:filesys:split_path|]
==== split_path
<eucode>
include std/filesys.e
namespace filesys
public function split_path(sequence fname)
</eucode>

  split a filename into path segments.

===== Parameters:
* ##fname## ~-- Filename to split

===== Returns:
A sequence of strings representing each path element found in ##fname##.

===== Example 1:
<eucode>
sequence path_elements = split_path("/usr/home/john/hello.txt")
-- path_elements would be { "usr", "home", "john", "hello.txt" }
</eucode>

===== Versioning:
* Added in 4.0.1

===== See Also:
[[:join_path]]



@[:filesys:join_path|]
==== join_path
<eucode>
include std/filesys.e
namespace filesys
public function join_path(sequence path_elements)
</eucode>

  Join multiple path segments into a single path/filename

===== Parameters:
* ##path_elements## ~-- Sequence of path elements

===== Returns:
A string representing the path elements on the given platform

===== Example 1:
<eucode>
sequence fname = join_path({ "usr", "home", "john", "hello.txt" })
-- fname would be "/usr/home/john/hello.txt" on Unix
-- fname would be "\\usr\\home\\john\\hello.txt" on Windows
</eucode>

===== Versioning:
* Added in 4.0.1

===== See Also:
[[:split_path]]



=== File Types


@[:filesys:FILETYPE_UNDEFINED|]
==== FILETYPE_UNDEFINED
<eucode>
include std/filesys.e
namespace filesys
public enum FILETYPE_UNDEFINED
</eucode>





@[:filesys:FILETYPE_NOT_FOUND|]
==== FILETYPE_NOT_FOUND
<eucode>
include std/filesys.e
namespace filesys
public enum FILETYPE_NOT_FOUND
</eucode>





@[:filesys:FILETYPE_FILE|]
==== FILETYPE_FILE
<eucode>
include std/filesys.e
namespace filesys
public enum FILETYPE_FILE
</eucode>





@[:filesys:FILETYPE_DIRECTORY|]
==== FILETYPE_DIRECTORY
<eucode>
include std/filesys.e
namespace filesys
public enum FILETYPE_DIRECTORY
</eucode>





@[:filesys:file_type|]
==== file_type
<eucode>
include std/filesys.e
namespace filesys
public function file_type(sequence filename)
</eucode>

  gets the type of a file.

===== Parameters:
# ##filename## : the name of the file to query. It must not have wildcards.

===== Returns:
An **integer**,
* FILETYPE_UNDEFINED (-1) if file could be multiply defined (i.e., contains any wildcards - '*' or '?')
* FILETYPE_NOT_FOUND (0) if filename does not exist
* FILETYPE_FILE (1) if filename is a file
* FILETYPE_DIRECTORY (2) if filename is a directory

===== See Also:
[[:dir]], [[:FILETYPE_DIRECTORY]], [[:FILETYPE_FILE]], [[:FILETYPE_NOT_FOUND]],
[[:FILETYPE_UNDEFINED]]


=== File Handling



@[:filesys:SECTORS_PER_CLUSTER|]
==== SECTORS_PER_CLUSTER
<eucode>
include std/filesys.e
namespace filesys
public enum SECTORS_PER_CLUSTER
</eucode>





@[:filesys:BYTES_PER_SECTOR|]
==== BYTES_PER_SECTOR
<eucode>
include std/filesys.e
namespace filesys
public enum BYTES_PER_SECTOR
</eucode>





@[:filesys:NUMBER_OF_FREE_CLUSTERS|]
==== NUMBER_OF_FREE_CLUSTERS
<eucode>
include std/filesys.e
namespace filesys
public enum NUMBER_OF_FREE_CLUSTERS
</eucode>





@[:filesys:TOTAL_NUMBER_OF_CLUSTERS|]
==== TOTAL_NUMBER_OF_CLUSTERS
<eucode>
include std/filesys.e
namespace filesys
public enum TOTAL_NUMBER_OF_CLUSTERS
</eucode>





@[:filesys:TOTAL_BYTES|]
==== TOTAL_BYTES
<eucode>
include std/filesys.e
namespace filesys
public enum TOTAL_BYTES
</eucode>





@[:filesys:FREE_BYTES|]
==== FREE_BYTES
<eucode>
include std/filesys.e
namespace filesys
public enum FREE_BYTES
</eucode>





@[:filesys:USED_BYTES|]
==== USED_BYTES
<eucode>
include std/filesys.e
namespace filesys
public enum USED_BYTES
</eucode>





@[:filesys:COUNT_DIRS|]
==== COUNT_DIRS
<eucode>
include std/filesys.e
namespace filesys
public enum COUNT_DIRS
</eucode>





@[:filesys:COUNT_FILES|]
==== COUNT_FILES
<eucode>
include std/filesys.e
namespace filesys
public enum COUNT_FILES
</eucode>





@[:filesys:COUNT_SIZE|]
==== COUNT_SIZE
<eucode>
include std/filesys.e
namespace filesys
public enum COUNT_SIZE
</eucode>





@[:filesys:COUNT_TYPES|]
==== COUNT_TYPES
<eucode>
include std/filesys.e
namespace filesys
public enum COUNT_TYPES
</eucode>





@[:filesys:EXT_NAME|]
==== EXT_NAME
<eucode>
include std/filesys.e
namespace filesys
public enum EXT_NAME
</eucode>





@[:filesys:EXT_COUNT|]
==== EXT_COUNT
<eucode>
include std/filesys.e
namespace filesys
public enum EXT_COUNT
</eucode>





@[:filesys:EXT_SIZE|]
==== EXT_SIZE
<eucode>
include std/filesys.e
namespace filesys
public enum EXT_SIZE
</eucode>





@[:filesys:file_exists|]
==== file_exists
<eucode>
include std/filesys.e
namespace filesys
public function file_exists(object name)
</eucode>

  checks to see if a file exists.

===== Parameters:
# ##name## :  filename to check existence of

===== Returns:
An **integer**, ##1## on yes, ##0## on no.

===== Example 1:
<eucode>
if file_exists("abc.e") then
    puts(1, "abc.e exists already\n")
end if
</eucode>


@[:filesys:file_timestamp|]
==== file_timestamp
<eucode>
include std/filesys.e
namespace filesys
public function file_timestamp(sequence fname)
</eucode>

  gets the timestamp of the file.

===== Parameters:
# ##name## : the filename to get the date of

===== Returns:
A valid **datetime type**, representing the files date and time or ##-1## if the
file's date and time could not be read.



@[:filesys:copy_file|]
==== copy_file
<eucode>
include std/filesys.e
namespace filesys
public function copy_file(sequence src, sequence dest, integer overwrite = 0)
</eucode>

  copies a file.

===== Parameters:
# ##src## : a sequence, the name of the file or directory to copy
# ##dest## : a sequence, the new name or location of the file
# ##overwrite## : an integer; ##0## (the default) will prevent an existing destination
file from being overwritten. Non-zero will overwrite the
destination file.

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
If ##overwrite## is true, and if ##dest## file already exists,
the function overwrites the existing file and succeeds.

===== See Also:
[[:move_file]], [[:rename_file]]


@[:filesys:rename_file|]
==== rename_file
<eucode>
include std/filesys.e
namespace filesys
public function rename_file(sequence old_name, sequence new_name, integer overwrite = 0)
</eucode>

  rename a file.

===== Parameters:
# ##old_name## : a sequence, the name of the file or directory to rename.
# ##new_name## : a sequence, the new name for the renamed file
# ##overwrite## : an integer, ##0## (the default) to prevent renaming if destination file exists,
##1## to delete existing destination file first

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
*	If ##new_name## contains a path specification, this is equivalent to moving the file, as
well as possibly changing its name. However, the path must be on the same drive for
this to work.
* If ##overwrite## was requested but the rename fails, any existing destination
file is preserved.

===== See Also:
[[:move_file]], [[:copy_file]]


@[:filesys:move_file|]
==== move_file
<eucode>
include std/filesys.e
namespace filesys
public function move_file(sequence src, sequence dest, integer overwrite = 0)
</eucode>

  moves a file to another location.

===== Parameters:
# ##src## : a sequence, the name of the file or directory to move
# ##dest## : a sequence, the new location for the file
# ##overwrite## : an integer, ##0## (the default) to prevent overwriting an existing destination file,
##1## to overwrite existing destination file

===== Returns:
An **integer**, ##0## on failure, ##1## on success.

===== Comments:
If ##overwrite## was requested but the move fails, any existing destination file is preserved.

===== See Also:
[[:rename_file]], [[:copy_file]]


@[:filesys:file_length|]
==== file_length
<eucode>
include std/filesys.e
namespace filesys
public function file_length(sequence filename)
</eucode>

  returns the size of a file.

===== Parameters:
# ##filename## : the name of the queried file

===== Returns:
An **atom**, the file size, or ##-1## if file is not found.

===== Comments:
This function does not compute the total size for a directory, and returns ##0## instead.
===== See Also:
[[:dir]]


@[:filesys:locate_file|]
==== locate_file
<eucode>
include std/filesys.e
namespace filesys
public function locate_file(sequence filename, sequence search_list = {},
        sequence subdir = {})
</eucode>

  locates a file by looking in a set of directories for it.

===== Parameters:
# ##filename## : a sequence, the name of the file to search for.
# ##search_list## : a sequence, the list of directories to look in. By
default this is ##""##, meaning that a predefined set of directories
is scanned. See comments below.
# ##subdir## : a sequence, the sub directory within the search directories
to check. This is optional.

===== Returns:
A **sequence**, the located file path if found, else the original file name.

===== Comments:
If ##filename## is an absolute path, it is just returned and no searching
takes place.

If ##filename## is located, the full path of the file is returned.

If ##search_list## is supplied, it can be either a sequence of directory names,
of a string of directory names delimited by ##':'## in //Unix// and ##';'## in //Windows//.

If the ##search_list## is omitted or ##""##, this will look in the following places~:
* The current directory
* The directory that the program is run from.
* The directory in ##$HOME## (##$HOMEDRIVE & $HOMEPATH## in //Windows//)
* The parent directory of the current directory
* The directories returned by ##include_paths##
* $EUDIR/bin
* $EUDIR/docs
* $EUDIST/
* $EUDIST/etc
* $EUDIST/data
* The directories listed in $USERPATH
* The directories listed in $PATH

If the ##subdir## is supplied, the function looks in this sub directory for each
of the directories in the search list.

===== Example 1:
<eucode>
 res = locate_file("abc.def", {"/usr/bin", "/u2/someapp", "/etc"})
 res = locate_file("abc.def", "/usr/bin:/u2/someapp:/etc")
 res = locate_file("abc.def") 
       -- Scan default locations.
 res = locate_file("abc.def", , "app") 
       -- Scan the 'app' sub directory in the default locations.
</eucode>


@[:filesys:disk_metrics|]
==== disk_metrics
<eucode>
include std/filesys.e
namespace filesys
public function disk_metrics(object disk_path)
</eucode>

  returns some information about a disk drive.

===== Parameters:
# ##disk_path## : A sequence. This is the path that identifies the disk to inquire upon.

===== Returns:
A **sequence**, containing ##SECTORS_PER_CLUSTER##, ##BYTES_PER_SECTOR##,
##NUMBER_OF_FREE_CLUSTERS##, and ##TOTAL_NUMBER_OF_CLUSTERS##

===== Example 1:
<eucode>
res = disk_metrics("C:\\")
min_file_size = res[SECTORS_PER_CLUSTER] * res[BYTES_PER_SECTOR]
</eucode>


@[:filesys:disk_size|]
==== disk_size
<eucode>
include std/filesys.e
namespace filesys
public function disk_size(object disk_path)
</eucode>

  returns the amount of space for a disk drive.

===== Parameters:
# ##disk_path## : A sequence. This is the path that identifies the disk to inquire upon.

===== Returns:
A **sequence**, containing ##TOTAL_BYTES##, ##USED_BYTES##, ##FREE_BYTES##, and a string which represents the filesystem name

===== Example 1:
<eucode>
res = disk_size("C:\\")
printf(1, "Drive %s has %3.2f%% free space\n", { 
    "C:", res[FREE_BYTES] / res[TOTAL_BYTES]
})
</eucode>


@[:filesys:dir_size|]
==== dir_size
<eucode>
include std/filesys.e
namespace filesys
public function dir_size(sequence dir_path, integer count_all = 0)
</eucode>

  returns the amount of space used by a directory.

===== Parameters:
# ##dir_path## : A sequence. This is the path that identifies the directory to inquire upon.
# ##count_all## : An integer. Used by //Windows// systems. If zero (the default)
it will not include //system// or //hidden// files in the
count, otherwise they are included.

===== Returns:
A **sequence**, containing four elements; the number of sub-directories ##[COUNT_DIRS]##,
the number of files ##[COUNT_FILES]##, the total space used by the directory ##[COUNT_SIZE]##,
and breakdown of the file contents by file extension ##[COUNT_TYPES]##.

===== Comments:
* The total space used by the directory does not include space used by any sub-directories.
* The file breakdown is a sequence of three-element sub-sequences. Each sub-sequence
contains the extension ##[EXT_NAME]##, the number of files of this extension ##[EXT_COUNT]##,
and the space used by these files ##[EXT_SIZE]##. The sub-sequences are presented in
extension name order. On //Windows// the extensions are all in lowercase.

===== Example 1:
<eucode>
res = dir_size("/usr/localbin")
printf(1, "Directory %s contains %d files\n", {
        "/usr/localbin", res[COUNT_FILES]
    })
for i = 1 to length(res[COUNT_TYPES]) do
    printf(1, "Type: %s (%d files %d bytes)\n", {
        res[COUNT_TYPES][i][EXT_NAME],
        res[COUNT_TYPES][i][EXT_COUNT],
        res[COUNT_TYPES][i][EXT_SIZE]
    })
end for
</eucode>


@[:filesys:temp_file|]
==== temp_file
<eucode>
include std/filesys.e
namespace filesys
public function temp_file(sequence temp_location = "", sequence temp_prefix = "",
        sequence temp_extn = "_T_", integer reserve_temp = 0)
</eucode>

  returns a file name that can be used as a temporary file.

===== Parameters:
# ##temp_location## : A sequence. A directory where the temporary file is expected
to be created.
** If omitted (the default) the 'temporary' directory
will be used. The temporary directory is defined in the "TEMP"
environment symbol, or failing that the "TMP" symbol and failing
that "C:\TEMP\" is used on //Windows// systems and "/tmp/" is used
on //Unix// systems.
** If ##temp_location## was supplied,
*** If it is an existing file, that file's directory is used.
*** If it is an existing directory, it is used.
*** If it doesn't exist, the directory name portion is used.
# ##temp_prefix## : A sequence: The is prepended to the start of the generated file name.
The default is ##""## .
# ##temp_extn## : A sequence: The is a file extention used in the generated file.
The default is ##"_T_"## .
# ##reserve_temp## : An integer: If not zero an empty file is created using the
generated name. The default is not to reserve (create) the file.

===== Returns:
A **sequence**, A generated file name.

===== Example 1:
<eucode>
temp_file("/usr/space", "myapp", "tmp") --> /usr/space/myapp736321.tmp
temp_file() --> /tmp/277382._T_
temp_file("/users/me/abc.exw") --> /users/me/992831._T_
</eucode>



@[:filesys:checksum|]
==== checksum
<eucode>
include std/filesys.e
namespace filesys
public function checksum(sequence filename, integer size = 4, integer usename = 0,
        integer return_text = 0)
</eucode>

  returns a checksum value for the specified file.

===== Parameters:
# ##filename## : A sequence. The name of the file whose checksum you want.
# ##size## : An integer. The number of atoms to return. Default is 4
# ##usename##: An integer. If not zero then the actual text of ##filename## will
affect the resulting checksum. The default (##0##) will not use the name of
the file.
# ##return_text##: An integer. If not zero, the check sum is returned as a
text string of hexadecimal digits otherwise (the default) the check sum
is returned as a sequence of ##size## atoms.

===== Returns:
A **sequence** containing ##size## atoms.

===== Comments:
* The larger the ##size## value, the more unique will the checksum be. For
most files and uses, a single atom will be sufficient as this gives a 32-bit
file signature. However, if you require better proof that the content of two
files are different then use higher values for ##size##. For example,
##size = 8## gives you 256 bits of file signature.
* If ##size## is zero or negative, an empty sequence is returned.
* All files of zero length will return the same checksum value when ##usename##
is zero.

===== Example 1:
<eucode>
 -- Example values. The exact values depend on the contents of the file.
 include std/console.e
 display( checksum("myfile", 1) ) --> {92837498}
 display( checksum("myfile", 2) ) --> {1238176, 87192873}
 display( checksum("myfile", 2,,1)) --> "0012E480 05327529"
 display( checksum("myfile", 4) ) --> {23448, 239807, 79283749, 427370}
 display( checksum("myfile") )    --> {23448, 239807, 79283749, 427370} -- default
</eucode>



!!CONTEXT:../include/std/io.e
!!namespace:io
%%output = std_io

== I/O

<<LEVELTOC level=2 depth=4>>


=== Constants


@[:io:STDIN|]
==== STDIN
<eucode>
include std/io.e
namespace io
public constant STDIN
</eucode>

  Standard Input


@[:io:STDOUT|]
==== STDOUT
<eucode>
include std/io.e
namespace io
public constant STDOUT
</eucode>

  Standard Output


@[:io:STDERR|]
==== STDERR
<eucode>
include std/io.e
namespace io
public constant STDERR
</eucode>

  Standard Error


@[:io:SCREEN|]
==== SCREEN
<eucode>
include std/io.e
namespace io
public constant SCREEN
</eucode>

  Screen (Standard Out)


@[:io:EOF|]
==== EOF
<eucode>
include std/io.e
namespace io
public constant EOF
</eucode>

  End of file


=== Read and Write Routines


@[q_print|]
@[:eu:##?##|]
==== ##?##
<eucode>
<built-in> procedure ##?##
</eucode>

displays an object using numbers and braces.

===== Note:
There are no parenthesis delimiting the single argument to this procedure.
This is a unique shortcut in Euphoria syntax.

===== Comments:
This is a shorthand way of writing ##pretty_print(STDOUT, x, {})##. An object or an expression is printed
to the standard output with braces and indentation to show the structure.

===== Example 1:
<eucode>
? {1, 2} + {3, 4}  -- will display {4, 6}
</eucode>

===== See Also:
[[:print]]


@[:eu:print|]
==== print
<eucode>
<built-in> procedure print(integer fn, object x)
</eucode>

displays an object using numbers and braces.

===== Comments:
All data objects are in //binary// format within computer hardware; something that is easy to forget. An output
routine must convert these binary values into "text" to be human readable.
The procedures ##print## and ##?## produce a "text" representation of an object that is output to a file or device.
The text shows the __numerical form__ of the object.
If the object ##x## is a sequence it uses braces **##{ , , , }##** to
show the structure.

===== Parameters:
# ##fn## : an integer, the handle to a file or device to output to
# ##x## : the object to print

===== Errors:
The target file or device must be open and able to be written to.

===== Comments:
This is not used to write to "binary" files as it only outputs text.

===== Example 1:
<eucode>
include std/io.e
print(STDOUT, "ABC")   -- output is:  "{65,66,67}"
puts (STDOUT, "ABC")    -- output is:  "ABC"
print(STDOUT, "65")    -- output is:  "65"
puts (STDOUT, 65)       -- output is:  "A"  (ASCII-65 ==> 'A')
print(STDOUT, 65.1234) -- output is:  "65.1234"
puts (STDOUT, 65.1234)  -- output is:  "A" (Converts to integer first)
</eucode>

===== Example 2:
<eucode>
include std/io.e
print(STDOUT, repeat({10,20}, 3)) -- output is: {{10,20},{10,20},{10,20}}
</eucode>

===== See Also:
[[:q_print|?]], [[:puts]]


@[:eu:printf|]
==== printf
<eucode>
<built-in> procedure printf(integer fn, sequence format, object values)
</eucode>

prints one or more values to a file or device, using a format string to embed them in and define how they should be represented.

===== Parameters:
# ##fn## : an integer, the handle to a file or device to output to
# ##format## : a sequence, the text to print. This text may contain format specifiers.
# ##values## : usually, a sequence of values. It should have as many elements as format specifiers in ##format##, as these values will be substituted to the specifiers.

===== Errors:
If there are less values to show than format specifiers, a run time error will occur.

The target file or device must be open.

===== Comments:
A **format specifier** is a string of characters starting with a percent sign ( ~%~ ) and ending
in a letter. Some extra information may come in between those.

This procedure writes out the ##format## text to the output file ##fn##,
replacing format specifiers with the corresponding data from the ##values##
parameter. Whenever a format specifiers is found in ##format##, the n-th item
in ##values## will be turned into a string according to the format specifier. The resulting
string will the format specifier. This means that the first format specifier uses the
first item in ##values##, the second format specifier the second item, and so on.

You must have at least as many items in ##values## as there are format specifiers
in ##format##. This means that if there is only one format specifier then ##values##
can be either an atom, integer or a non-empty sequence. And when there are more
than one format specifier in ##format## then ##values## must be a sequence with
a length that is greater than or equal to the number of format specifiers present.

This way, ##printf## always takes exactly three arguments no matter how many
values are to be printed.

The basic format specifiers are~:

* ##%d## ~-- print an atom as a decimal integer
* ##%x## ~-- print an atom as a hexadecimal integer. Negative numbers are printed
in two's complement, so -1 will print as ##FFFFFFFF##
* ##%o## ~-- print an atom as an octal integer
* ##%s## ~-- print a sequence as a string of characters, or print an atom as a single
character
* ##%e## ~-- print an atom as a floating-point number with exponential notation
* ##%f## ~-- print an atom as a floating-point number with a decimal point but no exponent
* ##%g## ~-- print an atom as a floating-point number using whichever format seems
appropriate, given the magnitude of the number
* ##~%~%## ~-- print the ##'%'## character itself. This is not an actual format specifier.

Field widths can be added to the basic formats (for example: ## %5d, %8.2f, %10.4s##). The number
before the decimal point is the minimum field width to be used. The number after
the decimal point is the precision to be used for numeric values.

If the field width is negative (for example ##%-5d##) then the value will be left-justified
within the field. Normally it will be right-justified, even strings. If the field width
starts with a leading 0 (for example ##%08d##) then leading zeros will be supplied to fill up
the field. If the field width starts with a ##'+'## (for example ##%+7d## ) then a plus sign will
be printed for positive values.

===== Comments:
Watch out for the following common mistake. The intention is to
output all the characters in the third argument but actually only
outputs the first character~:

<eucode>
include std/io.e
sequence name="John Smith"
printf(STDOUT, "My name is %s", name)
   --> My name is J
</eucode>

The output of this will be //##My name is J##// because each format specifier
uses exactly //one// item from the ##values## parameter. In this case we have
only one specifier so it uses the first item in the ##values## parameter, which
is the character ##'J'##. To fix this situation, you must ensure that the first
item in the ##values## parameter is the entire text string and not just a
character, so you need code this instead~:

<eucode>
include std/io.e
name="John Smith"
printf(STDOUT, "My name is %s", {name})
   --> My name is John Smith
</eucode>

Now, the third argument of ##printf## is a one-element sequence containing all
the text to be formatted.

Also note that if there is only one format specifier then ##values## can
simply be an atom or integer.

===== Example 1:
<eucode>
include std/io.e
atom rate = 7.875
printf(STDOUT, "The interest rate is: %8.2f\n", rate)

--      The interest rate is:     7.88
</eucode>

===== Example 2:
<eucode>
include std/io.e
sequence name="John Smith"
integer score=97
printf(STDOUT, "%15s, %5d\n", {name, score})

-- "     John Smith,    97"
</eucode>

===== Example 3:
<eucode>
include std/io.e
printf(STDOUT, "%-10.4s $ %s", {"ABCDEFGHIJKLMNOP", "XXX"})
--      ABCD       $ XXX
</eucode>

===== Example 4:
<eucode>
include std/io.e
printf(STDOUT, "%d  %e  %f  %g", repeat(7.75, 4)) 
                  -- same value in different formats

--      7  7.750000e+000  7.750000  7.75
</eucode>

**//NOTE//** that ##printf## cannot use an item in ##values## that contains
nested sequences. Thus this is an error ...
<eucode>
include std/io.e
sequence name = {"John", "Smith"}
printf(STDOUT, "%s", {name} )
</eucode>
because the item that is used from the ##values## parameter contains two
subsequences (strings in this case). To get the correct output you would
need to do this instead ...

<eucode>
include std/io.e
sequence name = {"John", "Smith"}
printf(STDOUT, "%s %s", {name[1], name[2]} )
</eucode>

===== See Also:
[[:sprintf]], [[:sprint]], [[:print]]


@[:eu:puts|]
==== puts
<eucode>
<built-in> procedure puts(integer fn, object text)
</eucode>

outputs text characters to a screen or file.

===== Parameters:
# ##fn## : an integer, the handle to an opened file or device
# ##text## : an object, either a single character or a sequence of characters.

===== Errors:
The target file or device must be open.

===== Comments:
This procedures outputs, to a file or device, a single byte (atom) or sequence of bytes. The low order
8-bits of each value is actually sent out. If outputting to the screen you will see text
characters displayed.

When you output a sequence of bytes it must not have any sub-sequences within it. It
must be a sequence of atoms only. (Typically a string of ASCII codes).

Avoid outputting 0's to the screen or to standard output. Your output might get truncated.

Remember that if the output file was opened in text mode, //Windows// will change ##\n## (10)
to ##\r\n## ##(13 10)##. Open the file in binary mode if this is not what you want.

===== Example 1:
<eucode>
include std/io.e
puts(SCREEN, "Enter your first name: ")
</eucode>

===== Example 2:
<eucode>
puts(output, 'A')  -- the single byte 65 will be sent to output
</eucode>

===== See Also:
[[:print]]


@[:eu:getc|]
==== getc
<eucode>
<built-in> function getc(integer fn)
</eucode>

gets the next character (byte) from a file or device ##fn##.

===== Parameters:
# ##fn## : an integer, the handle of the file or device to read from.

===== Returns:
An **integer**, the character read from the file, in the 0..255 range.
If no character is left to read, [[:EOF]] is returned instead.

===== Errors:
The target file or device must be open.

===== Comments:
File input using ##getc## is buffered, that means ##getc## does not actually go out to the disk
for each character. Instead, a large block of characters will be read in at one time
and returned to you one by one from a memory buffer.

When ##getc## reads from the keyboard, it will not see any characters until the user
presses Enter. Note that the user can type Control+Z, which the operating system treats
as "end of file" returning [[:EOF]].

===== See Also:
[[:gets]], [[:get_key]]


@[:eu:gets|]
==== gets
<eucode>
<built-in> function gets(integer fn)
</eucode>

gets a sequence of characters.

===== Parameters:
# ##fn## : an integer, the handle of the file or device to read from.

===== Returns:
An **object**, either [[:EOF]] on end of file, or the next line of text from the file.

===== Errors:
The file or device must be open.

===== Comments:
This function gets the next sequence (one line, including ##'\n'##) of characters from a file or device.
The characters will have values from 0 to 255.

If the line had an end of line marker, a ##~'\n'~## terminates the line. The last line of a file needs not have an end of line marker.

After reading a line of text from the keyboard, you should normally output a ##\n## character,
(for example  ##puts(1, '\n')## ), before printing something. Only on the last line of the screen does the
operating system automatically scroll the screen and advance to the next line.

When your program reads from the keyboard, the user can type Control+Z, which the operating
system treats as "end of file". [[:EOF]] will be returned.

===== Example 1:
<eucode>
sequence buffer
object line
integer fn

-- read a text file into a sequence
fn = open("my_file.txt", "r")
if fn = -1 then
    puts(1, "Couldn't open my_file.txt\n")
    abort(1)
end if

buffer = {}
while 1 do
    line = gets(fn)
    if atom(line) then
        exit   -- EOF is returned at end of file
    end if
    buffer = append(buffer, line)
end while
</eucode>

===== Example 2:
<eucode>
object line

puts(1, "What is your name?\n")
line = gets(0)  -- read standard input (keyboard)
line = line[1..$-1] -- get rid of \n character at end
puts(1, '\n')   -- necessary
puts(1, line & " is a nice name.\n")
</eucode>

===== See Also:
[[:getc]], [[:read_lines]]


@[:io:get_bytes|]
==== get_bytes
<eucode>
include std/io.e
namespace io
public function get_bytes(integer fn, integer n)
</eucode>

  reads the next bytes from a file.

===== Parameters:
# ##fn## : an integer, the handle to an open file to read from.
# ##n## : a positive integer, the number of bytes to read.

===== Returns:
A **sequence**, of length at most ##n##, made of the bytes that could be read from the file.

===== Comments:
When ##n## ##> 0## and the function returns a sequence of length less than ##n## you know
you have reached the end of file. Eventually, an
empty sequence will be returned.

This function is normally used with files opened in binary mode, ##"rb"##.
This avoids the confusing situation in text mode where //Windows// will convert CR LF
pairs to LF.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "rb")  -- an existing file

sequence whole_file
whole_file = {}

sequence chunk

while 1 do
    chunk = get_bytes(fn, 100) -- read 100 bytes at a time
    whole_file &= chunk        -- chunk might be empty, that's ok
    if length(chunk) < 100 then
        exit
    end if
end while

close(fn)
? length(whole_file)  -- should match DIR size of "temp"
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_integer32]], [[:get_dstring]]


@[:io:get_integer32|]
==== get_integer32
<eucode>
include std/io.e
namespace io
public function get_integer32(integer fh)
</eucode>

  reads the next four bytes from a file and returns them as a single integer.

===== Parameters:
# ##fh## : an integer, the handle to an open file to read from.

===== Returns:
An **atom**, between ##-1## and ##power(2,32)-1##, made of the bytes that could be read from the file.
When an end of file is encountered, it returns ##-1##.

===== Comments:
* This function is normally used with files opened in binary mode, ##"rb"##.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "rb")  -- an existing file

atom file_type_code
file_type_code = get_integer32(fn)
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]


@[:io:get_integer16|]
==== get_integer16
<eucode>
include std/io.e
namespace io
public function get_integer16(integer fh)
</eucode>

  reads the next two bytes from a file and returns them as a single integer.

===== Parameters:
# ##fh## : an integer, the handle to an open file to read from.

===== Returns:
An **integer**, made of the bytes that could be read from the file.
When an end of file is encountered, it returns ##-1##.

===== Comments:
* This function is normally used with files opened in binary mode, ##"rb"##.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "rb")  -- an existing file

atom file_type_code
file_type_code = get_integer16(fn)
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]


@[:io:put_integer32|]
==== put_integer32
<eucode>
include std/io.e
namespace io
public procedure put_integer32(integer fh, atom val)
</eucode>

  writes the supplied integer as four bytes to a file.

===== Parameters:
# ##fh## : an integer, the handle to an open file to write to.
# ##val## : an integer

===== Comments:
* This function is normally used with files opened in binary mode, ##"wb"##.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "wb")

put_integer32(fn, 1234)
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]


@[:io:put_integer16|]
==== put_integer16
<eucode>
include std/io.e
namespace io
public procedure put_integer16(integer fh, atom val)
</eucode>

  writes the supplied integer as two bytes to a file.

===== Parameters:
# ##fh## : an integer, the handle to an open file to write to.
# ##val## : an integer

===== Comments:
* This function is normally used with files opened in binary mode, ##"wb"##.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "wb")

put_integer16(fn, 1234)
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]


@[:io:get_dstring|]
==== get_dstring
<eucode>
include std/io.e
namespace io
public function get_dstring(integer fh, integer delim = 0)
</eucode>

  read a delimited byte string from an opened file.

===== Parameters:
# ##fh## : an integer, the handle to an open file to read from.
# ##delim## : an integer, the delimiter that marks the end of a byte string.
If omitted, a zero is assumed.

===== Returns:
An **sequence**, made of the bytes that could be read from the file.

===== Comments:
* If the end-of-file is found before the delimiter, the delimiter is appended
to the returned string.

===== Example 1:
<eucode>

integer fn
fn = open("temp", "rb")  -- an existing file

sequence text
text = get_dstring(fn)	-- Get a zero-delimited string
text = get_dstring(fn, '$')	-- Get a '$'-delimited string
</eucode>

===== See Also:
[[:getc]], [[:gets]], [[:get_bytes]], [[:get_integer32]]


=== Low Level File and Device Handling


@[:io:LOCK_SHARED|]
==== LOCK_SHARED
<eucode>
include std/io.e
namespace io
public enum LOCK_SHARED
</eucode>





@[:io:LOCK_EXCLUSIVE|]
==== LOCK_EXCLUSIVE
<eucode>
include std/io.e
namespace io
public enum LOCK_EXCLUSIVE
</eucode>





@[:io:file_number|]
==== file_number
<eucode>
include std/io.e
namespace io
public type file_number(object f)
</eucode>

  File number type


@[:io:file_position|]
==== file_position
<eucode>
include std/io.e
namespace io
public type file_position(object p)
</eucode>

  File position type


@[:io:lock_type|]
==== lock_type
<eucode>
include std/io.e
namespace io
public type lock_type(object t)
</eucode>

  Lock Type


@[:io:byte_range|]
==== byte_range
<eucode>
include std/io.e
namespace io
public type byte_range(object r)
</eucode>

  Byte Range Type


@[:eu:open|]
==== open
<eucode>
<built-in> function open(sequence path, sequence mode, integer cleanup = 0)
</eucode>

opens a file or device, to get the file number.

===== Parameters:
# ##path## : a string, the path to the file or device to open.
# ##mode## : a string, the mode being used o open the file.
# ##cleanup## : an integer, if 0, then the file must be manually closed by the
coder.  If 1, then the file will be closed when either the file handle's references
goes to 0, or if called as a parameter to ##delete##.

===== Returns:
A small **integer**, -1 on failure, else 0 or more.

===== Errors:
There is a limit on the number of files that can be simultaneously opened, currently 40.
After this limit is reached the next call to ##open## will produce an error.

The length of ##path## should not exceed 1_024 characters.

===== Comments:
Possible modes are~:

* ##"r"## ~-- open text file for reading
* ##"rb"## ~-- open binary file for reading
* ##"w"## ~-- create text file for writing
* ##"wb"## ~-- create binary file for writing
* ##"u"## ~-- open text file for update (reading and writing)
* ##"ub"## ~-- open binary file for update
* ##"a"## ~-- open text file for appending
* ##"ab"## ~-- open binary file for appending

Files opened for read or update must already exist. Files opened for write or append will
be created if necessary. A file opened for write will be set to 0 bytes. Output to a
file opened for append will start at the end of file.

On //Windows//, output to text files will have carriage-return characters automatically
added before linefeed characters. On input, these carriage-return characters are removed.
A Control+Z character (ASCII 26) will signal an immediate end of file.

I/O to binary files is not modified in any way. Any byte values from 0 to 255 can be
read or written. On //Unix//, all files are binary files, so ##"r"## mode and ##"rb"##
mode are equivalent, as are ##"w"## and ##"wb"##, ##"u"## and ##"ub"##, and ##"a"## and ##"ab"##.

Some typical devices that you can open on //Windows// are~:

* ##"CON"## ~-- the console (screen)
* ##"AUX"## ~-- the serial auxiliary port
* ##"COM1"## ~-- serial port 1
* ##"COM2"## ~-- serial port 2
* ##"PRN"## ~-- the printer on the parallel port
* ##"NUL"## ~-- a non-existent device that accepts and discards output

Close a file or device when done with it, flushing out any still-buffered characters prior.

//Windows// and //Unix//: Long filenames are fully supported for reading and writing and
creating.

//Windows//: Be careful not to use the special device names in a file name, even if you add an
extension. For example: ##CON.TXT##, ##CON.DAT##, ##CON.JPG## all refer to the ##CON## device and
//not// to a file.

===== Example 1:
<eucode>
integer file_num, file_num95
sequence first_line
constant ERROR = 2

file_num = open("my_file", "r")
if file_num = -1 then
    puts(ERROR, "couldn't open my_file\n")
else
    first_line = gets(file_num)
end if

file_num = open("PRN", "w") -- open printer for output

-- on Windows 95:
file_num95 = open("big_directory_name\\very_long_file_name.abcdefg",
                  "r")
if file_num95 != -1 then
    puts(STDOUT, "it worked!\n")
end if
</eucode>


@[:eu:close|]
==== close
<eucode>
<built-in> procedure close(atom fn)
</eucode>

closes a file or device and flushes out any still-buffered characters.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to query.

===== Errors:
The target file or device must be open.

===== Comments:
Any still-open files will be closed automatically when your program terminates.


@[:io:seek|]
==== seek
<eucode>
include std/io.e
namespace io
public function seek(file_number fn, file_position pos)
</eucode>

  Seek (move) to any byte position in a file.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to ##seek##
# ##pos## : an atom, either an absolute 0-based position or -1 to seek to end of file.

===== Returns:
An **integer**, 0 on success, 1 on failure.

===== Errors:
The target file or device must be open.

===== Comments:
For each open file, there is a current byte position that is updated as a result of I/O
operations on the file. The initial file position is 0 for files opened for read, write
or update. The initial position is the end of file for files opened for append.
It is possible to seek past the end of a file. If you seek past the end of the file, and
write some data, undefined bytes will be inserted into the gap between the original end
of file and your new data.

After seeking and reading (writing) a series of bytes, you may need to call ##seek##
explicitly before you switch to writing (reading) bytes, even though the file position
should already be what you want.

This function is normally used with files opened in binary mode. In text mode, //Windows//
converts CR LF to LF on input, and LF to CR LF on output, which can cause great confusion
when you are trying to count bytes because ##seek## counts the //Windows// end of line sequences
as two bytes, even if the file has been opened in text mode.

===== Example 1:
<eucode>
include std/io.e

integer fn
fn = open("my.data", "rb")
-- read and display first line of file 3 times:
for i = 1 to 3 do
    puts(STDOUT, gets(fn))
    if seek(fn, 0) then
        puts(STDOUT, "rewind failed!\n")
    end if
end for
</eucode>

===== See Also:
[[:get_bytes]], [[:puts]], [[:where]]


@[:io:where|]
==== where
<eucode>
include std/io.e
namespace io
public function where(file_number fn)
</eucode>

  retrieves the current file position for an opened file or device.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to query.


===== Returns:
An **atom**, the current byte position in the file.

===== Errors:
The target file or device must be open.


===== Comments:
The file position is is the place in the file where the next byte will be read from, or
written to. It is updated by reads, writes and seeks on the file. This procedure always
counts //Windows// end of line sequences (CR LF) as two bytes even when the file number has
been opened in text mode.



@[:io:flush|]
==== flush
<eucode>
include std/io.e
namespace io
public procedure flush(file_number fn)
</eucode>

  forces writing any buffered data to an open file or device.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to close.

===== Errors:
The target file or device must be open.

===== Comments:
When you write data to a file, Euphoria normally stores the data
in a memory buffer until a large enough chunk of data has accumulated.
This large chunk can then be written to disk very efficiently.
Sometimes you may want to force, or flush, all data out immediately,
even if the memory buffer is not full. To do this you must call ##flush(fn)##,
where fn is the file number of a file open for writing or appending.

When a file is closed, (see ##[[:close]]##), all buffered data is flushed out.
When a program terminates, all open files are flushed and closed
automatically. Use ##flush## when another process may need to
see all of the data written so far, but you are not ready
to close the file yet. ##flush## is also used in crash routines, where files may not be closed in the cleanest possible way.

===== Example 1:
<eucode>
f = open("file.log", "w")
puts(f, "Record#1\n")
puts(STDOUT, "Press Enter when ready\n")

flush(f)  -- This forces "Record #1" into "file.log" on disk.
          -- Without this, "file.log" will appear to have
          -- 0 characters when we stop for keyboard input.

s = gets(0) -- wait for keyboard input
</eucode>

===== See Also:
[[:close]], [[:crash_routine]]


@[:io:lock_file|]
==== lock_file
<eucode>
include std/io.e
namespace io
public function lock_file(file_number fn, lock_type t, byte_range r = {})
</eucode>

  locks a file so access is restricted.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to (partially) lock.
# ##t## : an integer which defines the kind of lock to apply.
# ##r## : a sequence, defining a section of the file to be locked, or ##{}## for the whole file (the default).

===== Returns:
An **integer**, 0 on failure, 1 on success.

===== Errors:
The target file or device must be open.

===== Comments:
When multiple processes can simultaneously access a
file, some kind of locking mechanism may be needed to avoid mangling
the contents of the file, or causing erroneous data to be read from the file.

##lock_file## attempts to place a lock on an open file, ##fn##, to stop
other processes from using the file while your program is reading it
or writing it.

There are two types of locks that
you can request using the ##t## parameter.
Ask for a **shared** lock when you intend to read a file, and you want to
temporarily block other processes from writing it. Ask for an
**exclusive** lock when you intend to write to a file and you want to temporarily
block other processes from reading or writing it. It is ok for many processes to
simultaneously have shared locks on the same file, but only one process
can have an exclusive lock, and that can happen only when no other
process has any kind of lock on the file. ##io.e## contains the following declarations:

<eucode>
public enum
    LOCK_SHARED,
    LOCK_EXCLUSIVE
</eucode>

On ///Windows// you can lock a specified portion of a file using the ##r##  parameter.
##r## is a sequence of the form: ##{first_byte, last_byte}##. It indicates the first byte and
last byte in the file,  that the lock applies to. Specify the empty sequence ##{}##,
if you want to lock the whole file, or don't specify it at all, as this is the default. In the current release for //Unix//, locks
always apply to the whole file, and you should use this default value.

##lock_file## does not wait
for other processes to relinquish their locks. You may have to call it repeatedly,
before the lock request is granted.

On //Unix//, these locks are called advisory locks, which means they are not enforced
by the operating system. It is up to the processes that use a particular file to cooperate
with each other. A process can access a file without first obtaining a lock on it. On
//Windows// locks are enforced by the operating system.

===== Example 1:
<eucode>
include std/io.e
integer v
atom t
v = open("visitor_log", "a")  -- open for append
t = time()
while not lock_file(v, LOCK_EXCLUSIVE, {}) do
    if time() > t + 60 then
        puts(STDOUT, "One minute already ... I can't wait forever!\n")
        abort(1)
    end if
    sleep(5) -- let other processes run
end while
puts(v, "Yet another visitor\n")
unlock_file(v, {})
close(v)
</eucode>

===== See Also:
[[:unlock_file]]


@[:io:unlock_file|]
==== unlock_file
<eucode>
include std/io.e
namespace io
public procedure unlock_file(file_number fn, byte_range r = {})
</eucode>

  unlock (a portion of) an open file.

===== Parameters:
# ##fn## : an integer, the handle to the file or device to (partially) lock.
# ##r## : a sequence, defining a section of the file to be locked, or ##{}## for the whole file (the default).

===== Errors:
The target file or device must be open.

===== Comments:
You must have previously locked the
file using ##lock_file##. On //Windows// you can unlock a range of bytes within a
file by specifying the ##r## as ##{first_byte, last_byte}##. The same range of bytes
must have been locked by a previous call to [[:lock_file]]. On //Unix// you can
currently only lock or unlock an entire file. ##r## should be ##{}## when you
want to unlock an entire file. On //Unix//, ##r## must always be ##{}##, which is the default.

You should unlock a file as soon as possible so other processes can use it.

Any files that you have locked, will automatically be unlocked when your program
terminates.

===== See Also:
[[:lock_file]]


=== File Reading and Writing


@[:io:read_lines|]
==== read_lines
<eucode>
include std/io.e
namespace io
public function read_lines(object file)
</eucode>

  reads the contents of a file as a sequence of lines.

===== Parameters:
##file## : an object, either a file path or the handle to an open file.
If this is an empty string, STDIN (the console) is used.

===== Returns:
-1 on error or a **sequence**, made of lines from the file, as [[:gets]] could read them.

===== Comments:
If ##file## was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.

===== Example 1:
<eucode>
data = read_lines("my_file.txt")
-- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
-- {"Line 1", "Line 2", "Line 3"}
</eucode>

===== Example 2:
<eucode>
fh = open("my_file.txt", "r")
data = read_lines(fh)
close(fh)

-- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
-- {"Line 1", "Line 2", "Line 3"}
</eucode>

===== See Also:
[[:gets]], [[:write_lines]], [[:read_file]]


@[:io:process_lines|]
==== process_lines
<eucode>
include std/io.e
namespace io
public function process_lines(object file, integer proc, object user_data = 0)
</eucode>

  processes the contents of a file, one line at a time.

===== Parameters:
# ##file## : an object. Either a file path or the handle to an open file. An
empty string signifies ##STDIN## ~-- the console keyboard.
# ##proc## : an integer. The routine_id of a function that will process the line.
# ##user_data## : on object. This is passed untouched to ##proc## for each line.

===== Returns:
An object. If 0 then all the file was processed successfully. Anything else
means that something went wrong and this is whatever value was returned by ##proc##.

===== Comments:
* The function ##proc## must accept three parameters~:
** A sequence: The line to process. It will **not** contain an end-of-line character.
** An integer: The line number.
** An object : This is the ##user_data## that was passed to ##process_lines##.
* If ##file## was a sequence, the file will be closed on completion.
Otherwise, it will remain open, and be positioned where ever reading stopped.

===== Example 1:
<eucode>
-- Format each supplied line according to the format pattern supplied as well.
function show(sequence aLine, integer line_no, object data)
  writefln( data[1], {line_no, aLine})
  if data[2] > 0 and line_no = data[2] then
  	return 1
  else
  	return 0
  end if
end function
-- Show the first 20 lines.
process_lines("sample.txt", routine_id("show"), {"[1z:4] : [2]", 20})
</eucode>

===== See Also:
[[:gets]], [[:read_lines]], [[:read_file]]


@[:io:write_lines|]
==== write_lines
<eucode>
include std/io.e
namespace io
public function write_lines(object file, sequence lines)
</eucode>

  write a sequence of lines to a file.

===== Parameters:
# ##file## : an object, either a file path or the handle to an open file.
# ##lines## : the sequence of lines to write

===== Returns:
An **integer**, 1 on success, -1 on failure.

===== Errors:
If [[:puts]] cannot write some line of text, a runtime error will occur.

===== Comments:
If ##file## was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.

Whatever integer the lines in ##lines## holds will be truncated to its 8 lowest bits so as to fall in the 0..255 range.

===== Example 1:
<eucode>
if write_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
    puts(STDERR, "Failed to write data\n")
end if
</eucode>

===== See Also:
[[:read_lines]], [[:write_file]], [[:puts]]


@[:io:append_lines|]
==== append_lines
<eucode>
include std/io.e
namespace io
public function append_lines(sequence file, sequence lines)
</eucode>

  appends a sequence of lines to a file.

===== Parameters:
# ##file## : an object, either a file path or the handle to an open file.
# ##lines## : the sequence of lines to write

===== Returns:
An **integer**, 1 on success, -1 on failure.

===== Errors:
If [[:puts]] cannot write some line of text, a runtime error will occur.

===== Comments:
##file## is opened, written to and then closed.

===== Example 1:
<eucode>
if append_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
    puts(STDERR, "Failed to append data\n")
end if
</eucode>

===== See Also:
[[:write_lines]], [[:puts]]


@[:io:BINARY_MODE|]
==== BINARY_MODE
<eucode>
include std/io.e
namespace io
public enum BINARY_MODE
</eucode>





@[:io:TEXT_MODE|]
==== TEXT_MODE
<eucode>
include std/io.e
namespace io
public enum TEXT_MODE
</eucode>





@[:io:UNIX_TEXT|]
==== UNIX_TEXT
<eucode>
include std/io.e
namespace io
public enum UNIX_TEXT
</eucode>





@[:io:DOS_TEXT|]
==== DOS_TEXT
<eucode>
include std/io.e
namespace io
public enum DOS_TEXT
</eucode>





@[:io:read_file|]
==== read_file
<eucode>
include std/io.e
namespace io
public function read_file(object file, integer as_text = BINARY_MODE)
</eucode>

  reads the contents of a file as a single sequence of bytes.

===== Parameters:
# ##file## : an object, either a file path or the handle to an open file.
# ##as_text## : integer, ##BINARY_MODE## (the default) assumes //binary mode// that
causes every byte to be read in,
and ##TEXT_MODE## assumes //text mode// that ensures that
lines end with just a Control+J (NewLine) character,
and the first byte value of 26 (Control+Z) is interpreted as End-Of-File.

===== Returns:
A **sequence**, holding the entire file.

Comments
* When using ##BINARY_MODE##, each byte in the file is returned as an element in
the return sequence.
* When not using ##BINARY_MODE##, the file will be interpreted as a text file. This
means that all line endings will be transformed to a single ##0x0A## character and
the first ##0x1A## character (Control+Z) will indicate the end of file (all data after this
will not be returned to the caller.)

===== Example 1:
<eucode>
data = read_file("my_file.txt")
-- data contains the entire contents of ##my_file.txt##
</eucode>

===== Example 2:
<eucode>
fh = open("my_file.txt", "r")
data = read_file(fh)
close(fh)

-- data contains the entire contents of ##my_file.txt##
</eucode>

===== See Also:
[[:write_file]], [[:read_lines]]


@[:io:write_file|]
==== write_file
<eucode>
include std/io.e
namespace io
public function write_file(object file, sequence data, integer as_text = BINARY_MODE)
</eucode>

  write a sequence of bytes to a file.

===== Parameters:
# ##file## : an object, either a file path or the handle to an open file.
# ##data## : the sequence of bytes to write
# ##as_text## : integer
** ##BINARY_MODE## (the default) assumes //binary mode// that
causes every byte to be written out as is,
** ##TEXT_MODE## assumes //text mode// that causes a NewLine
to be written out according to the operating system's
end of line convention. On //Unix// this is Control+J and on
//Windows// this is the pair ##{Ctrl-L, Ctrl-J}##.
** ##UNIX_TEXT## ensures that lines are written out with //Unix// style
line endings (Control+J).
** ##DOS_TEXT## ensures that lines are written out with //Windows// style
line endings ##{Ctrl-L, Ctrl-J}##.
===== Returns:
An **integer**, 1 on success, -1 on failure.

===== Errors:
If [[:puts]] cannot write ##data##, a runtime error will occur.

===== Comments:
* When ##file## is a file handle, the file is not closed after writing is finished. When ##file## is a
file name, it is opened, written to and then closed.
* Note that when writing the file in ony of the text modes, the file is truncated
at the first Control+Z character in the input data.

===== Example 1:
<eucode>
if write_file("data.txt", "This is important data\nGoodbye") = -1 then
    puts(STDERR, "Failed to write data\n")
end if
</eucode>

===== See Also:
[[:read_file]], [[:write_lines]]


@[:io:writef|]
==== writef
<eucode>
include std/io.e
namespace io
public procedure writef(object fm, object data = {}, object fn = 1, object data_not_string = 0)
</eucode>

  writes formatted text to a file.

===== Parameters:
There are two ways to pass arguments to this function~:

# Traditional way with first arg being a file handle.
## : integer, The file handle.
## : sequence, The format pattern.
## : object, The data that will be formatted.
## ##data_not_string##: object, If not 0 then the ##data## is not a string.
By default this is 0 meaning that ##data## could be a single string.

# Alternative way with first argument being the format pattern.
## : sequence, Format pattern.
## : sequence, The data that will be formatted,
## : object, The file to receive the formatted output. Default is
to the STDOUT device (console).
## ##data_not_string##: object, If not 0 then the ##data## is not a string.
By default this is 0 meaning that ##data## could be a single string.

===== Comments:
* With the traditional arguments, the first argument must be an integer file handle.
* With the alternative arguments, the thrid argument can be a file name string,
in which case it is opened for output, written to and then closed.
* With the alternative arguments, the third argument can be a two-element sequence
containing a file name string and an output type (##"a"## for append, ##"w"## for write),
in which case it is opened accordingly, written to and then closed.
* With the alternative arguments, the third argument can a file handle,
in which case it is written to only
* The format pattern uses the formatting codes defined in [[:text:format]].
* When the data to be formatted is a single text string, it does not have to
be enclosed in braces,

===== Example 1:
<eucode>
-- To console
writef("Today is [4], [u2:3] [3:02], [1:4].", 
       {Year, MonthName, Day, DayName})
-- To "sample.txt"
writef("Today is [4], [u2:3] [3:02], [1:4].", 
       {Year, MonthName, Day, DayName}, "sample.txt")
-- To "sample.dat"
integer dat = open("sample.dat", "w")
writef("Today is [4], [u2:3] [3:02], [1:4].", 
       {Year, MonthName, Day, DayName}, dat)
-- Appended to "sample.log"
writef("Today is [4], [u2:3] [3:02], [1:4].", 
       {Year, MonthName, Day, DayName}, {"sample.log", "a"})
-- Simple message to console
writef("A message")
-- Another console message
writef(STDERR, "This is a []", "message")
-- Outputs two numbers
writef(STDERR, "First [], second []", {65, 100}, 1)
     -- Note that {65, 100} is also "Ad"
</eucode>

===== See Also:
[[:text:format]], [[:writefln]], [[:write_lines]]


@[:io:writefln|]
==== writefln
<eucode>
include std/io.e
namespace io
public procedure writefln(object fm, object data = {}, object fn = 1,
        object data_not_string = 0)
</eucode>

  writes formatted text to a file, ensuring that a new line is also output.

===== Parameters:
# ##fm## : sequence, Format pattern.
# ##data## : sequence, The data that will be formatted,
# ##fn## : object, The file to receive the formatted output. Default is
to the ##STDOUT## device (console).
# ##data_not_string##: object, If not 0 then the ##data## is not a string.
By default this is 0 meaning that ##data## could be a single string.

===== Comments:
* This is the same as [[:writef]], except that it always adds a New Line to
the output.
* When ##fn## is a file name string, it is opened for output,
written to and then closed.
* When ##fn## is a two-element sequence containing a file name string and
an output type (##"a"## for append, ##"w"## for write), it is opened accordingly,
written to and then closed.
* When ##fn## is a file handle, it is written to only
* The ##fm## uses the formatting codes defined in [[:text:format]].

===== Example 1:
<eucode>
-- To console
writefln("Today is [4], [u2:3] [3:02], [1:4].", 
         {Year, MonthName, Day, DayName})
-- To "sample.txt"
writefln("Today is [4], [u2:3] [3:02], [1:4].", 
         {Year, MonthName, Day, DayName}, "sample.txt")
-- Appended to "sample.log"
writefln("Today is [4], [u2:3] [3:02], [1:4].", 
         {Year, MonthName, Day, DayName}, {"sample.log", "a"})
</eucode>

===== See Also:
[[:text:format]], [[:writef]], [[:write_lines]]



!!CONTEXT:../include/std/os.e
!!namespace:os
%%output = std_os

== Operating System Helpers

<<LEVELTOC level=2 depth=4>>



@[:os:CMD_SWITCHES|]
==== CMD_SWITCHES
<eucode>
include std/os.e
namespace os
public constant CMD_SWITCHES
</eucode>







=== Operating System Constants



@[:os:WIN32|]
==== WIN32
<eucode>
include std/os.e
namespace os
public enum WIN32
</eucode>





@[:os:WINDOWS|]
==== WINDOWS
<eucode>
include std/os.e
namespace os
public enum WINDOWS
</eucode>





@[:os:LINUX|]
==== LINUX
<eucode>
include std/os.e
namespace os
public enum LINUX
</eucode>





@[:os:OSX|]
==== OSX
<eucode>
include std/os.e
namespace os
public enum OSX
</eucode>





@[:os:OPENBSD|]
==== OPENBSD
<eucode>
include std/os.e
namespace os
public enum OPENBSD
</eucode>





@[:os:NETBSD|]
==== NETBSD
<eucode>
include std/os.e
namespace os
public enum NETBSD
</eucode>





@[:os:FREEBSD|]
==== FREEBSD
<eucode>
include std/os.e
namespace os
public enum FREEBSD
</eucode>





These constants are returned by the [[:platform]] function.

* ##WIN32##   ~-- Host operating system is Windows
* ##LINUX##   ~-- Host operating system is Linux
* ##FREEBSD## ~-- Host operating system is FreeBSD
* ##OSX##     ~-- Host operating system is Mac OS X
* ##OPENBSD## ~-- Host operating system is OpenBSD
* ##NETBSD##  ~-- Host operating system is NetBSD

===== Note:
In most situations you are better off to test the host platform by using
the [[:ifdef statement]]. It is faster.



=== Environment


@[:os:instance|]
==== instance
<eucode>
include std/os.e
namespace os
public function instance()
</eucode>

  returns ##hInstance## on //Windows// and Process ID (pid) on //Unix//.

===== Comments:
On //Windows// the ##hInstance## can be passed around to various
//Windows// routines.


@[:os:get_pid|]
==== get_pid
<eucode>
include std/os.e
namespace os
public function get_pid()
</eucode>

  returns the ID of the current Process (pid).

===== Returns:
An atom: The current id for a process.

===== Example 1:
<eucode>
mypid = get_pid()
</eucode>


@[:os:uname|]
==== uname
<eucode>
include std/os.e
namespace os
public function uname()
</eucode>

  retrieves the name of the host OS.

===== Returns:
A **sequence**, starting with the OS name. If identification fails, returns
an OS name of ##UNKNOWN##. Extra information depends on the OS.

On //Unix// returns the same information as the ##uname## syscall in the same
order as the struct ##utsname##. This information is:
{{{
OS Name/Kernel Name
Local Hostname
Kernel Version/Kernel Release
Kernel Specific Version information (This is usually the date that the
kernel was compiled on and the name of the host that performed the compiling.)
Architecture Name (Usually a string of i386 vs x86_64 vs ARM vs etc)
}}}

On //Windows// returns the following in order:
{{{
Windows Platform (out of WinCE, Win9x, WinNT, Win32s, or Unknown Windows)
Name of Windows OS (Windows 3.1, Win95, WinXP, etc)
Platform Number
Build Number
Minor OS version number
Major OS version number
}}}

On ##UNKNOWN## returns an OS name of ##"UNKNOWN"##. No other information is returned.

Returns an empty string of "" if an internal error has occured.

===== Comments:
On //Unix//  ##M_UNAME## is defined as a ##machine_func## and this is passed to the C
backend. If the ##M_UNAME## call fails, the raw ##machine_func## returns -1.
On non-//Unix// platforms, calling the ##machine_func## directly returns 0.


@[:os:is_win_nt|]
==== is_win_nt
<eucode>
include std/os.e
namespace os
public function is_win_nt()
</eucode>

  reports whether the host system is a newer Windows version (NT/2K/XP/Vista).

===== Returns:
An **integer**, 1 if host system is a newer Windows (NT/2K/XP/Vista), else 0.


@[:eu:getenv|]
==== getenv
<eucode>
<built-in> function getenv(sequence var_name)
</eucode>

returns the value of an environment variable.

===== Parameters:
# ##var_name## : a string, the name of the variable being queried.

===== Returns:
An **object**, -1 if the variable does not exist, else a sequence holding its value.

===== Comments:

Both the argument and the return value, may, or may not be, case sensitive. You might need to test this on your own system.

===== Example 1:
<eucode>
 e = getenv("EUDIR")
-- e will be "C:\EUPHORIA" -- or perhaps D:, E: etc.
</eucode>

===== See Also:
[[:setenv]], [[:command_line]]


@[:os:setenv|]
==== setenv
<eucode>
include std/os.e
namespace os
public function setenv(sequence name, sequence val, integer overwrite = 1)
</eucode>

  sets an environment variable.

===== Parameters:

# ##name## : a string, the environment variable name
# ##val## : a string, the value to set to
# ##overwrite## : an integer, nonzero to overwrite an existing variable, 0 to disallow this.

===== Example 1:
<eucode>
? setenv("NAME", "John Doe")
? setenv("NAME", "Jane Doe")
? setenv("NAME", "Jim Doe", 0)
</eucode>

===== See Also:
[[:getenv]], [[:unsetenv]]


@[:os:unsetenv|]
==== unsetenv
<eucode>
include std/os.e
namespace os
public function unsetenv(sequence env)
</eucode>

  unsets an environment variable.

===== Parameters:
# ##name## : name of environment variable to unset

===== Example 1:
<eucode>
? unsetenv("NAME")
</eucode>

===== See Also:
[[:setenv]], [[:getenv]]


@[:eu:platform|]
==== platform
<eucode>
<built-in> function platform()
</eucode>

indicates the platform that the program is being executed on.

===== Returns:
An **integer**,
<eucode>
public constant
    WIN32 = WINDOWS,
    LINUX,
    FREEBSD,
    OSX,
   OPENBSD,
    NETBSD,
    FREEBSD
</eucode>

===== Comments:
The [[:ifdef statement]] is much more versatile and in most cases supersedes ##platform##.

##platform## used to be the way to execute different code depending on which platform the program
is running on. Additional platforms will be added as Euphoria is ported to new machines and
operating environments.

===== Example 1:
<eucode>
 ifdef WINDOWS then
    -- call system Beep routine
    err = c_func(Beep, {0,0})
elsedef
    -- do nothing (Linux/FreeBSD)
end if
</eucode>

===== See Also:
[[:Platform-Specific Issues]], [[:ifdef statement]]


=== Interacting with the OS



@[:eu:system|]
==== system
<eucode>
<built-in> procedure system(sequence command, integer mode=0)
</eucode>

passes a command string to the operating system command interpreter.

===== Parameters:
# ##command## : a string to be passed to the shell
# ##mode## : an integer, indicating the manner in which to return from the call.

===== Errors:
##command## should not exceed 1_024 characters.

===== Comments:
Allowable values for ##mode## are~:
* 0: the previous graphics mode is restored and the screen is cleared.
* 1: a beep sound will be made and the program will wait for the user to press a key before the previous graphics mode is restored.
* 2: the graphics mode is not restored and the screen is not cleared.

##mode## = 2 should only be used when it is known that the command executed by ##system## will not change the graphics mode.

You can use Euphoria as a sophisticated "batch" (.bat) language by making calls to ##system## and ##system_exec##.

##system## will start a new command shell.

##system## allows you to use command-line redirection of standard input and output in
##command##.

===== Example 1:
<eucode>
 system("copy temp.txt a:\\temp.bak", 2)
-- note use of double backslash in literal string to get
-- single backslash
</eucode>

===== Example 2:
<eucode>
 system("eui \\test\\myprog.ex < indata > outdata", 2)
-- executes myprog by redirecting standard input and
-- standard output
</eucode>

===== See Also:
[[:system_exec]], [[:command_line]], [[:current_dir]], [[:getenv]]



@[:eu:system_exec|]
==== system_exec
<eucode>
<built-in> function system_exec(sequence command, integer mode=0)
</eucode>

tries to run the a shell executable command.

===== Parameters:
# ##command## : a string to be passed to the shell, representing an executable command
# ##mode## : an integer, indicating the manner in which to return from the call.

===== Returns:
An **integer**, basically the exit or return code from the called process.

===== Errors:
##command## should not exceed 1_024 characters.

===== Comments:

Allowable values for ##mode## are~:
* 0 ~-- the previous graphics mode is restored and the screen is cleared.
* 1 ~-- a beep sound will be made and the program will wait for the user to press a key before the previous graphics mode is restored.
* 2 ~-- the graphics mode is not restored and the screen is not cleared.

If it is not possible to run the program, ##system_exec## will return -1.

On //Windows// ##system_exec## will only run ##.exe## and ##.com## programs.
To run ##.bat## files, or built-in shell commands, you need [[:system]]. Some commands,
such as ##DEL##, are not programs, they are actually built-in to the command interpreter.

On //Windows// ##system_exec## does not allow the use of command-line redirection in ##command##.
Nor does it allow you to quote strings that contain blanks, such as file names.

exit codes from //Windows// programs are normally in the range 0 to 255, with 0 indicating "success".

You can run a Euphoria program using ##system_exec##. A Euphoria program can return an exit code using [[:abort]].

##system_exec## does not start a new command shell.

===== Example 1:
<eucode>
 integer exit_code
exit_code = system_exec("xcopy temp1.dat temp2.dat", 2)

if exit_code = -1 then
    puts(2, "\n couldn't run xcopy.exe\n")
elsif exit_code = 0 then
    puts(2, "\n xcopy succeeded\n")
else
    printf(2, "\n xcopy failed with code %d\n", exit_code)
end if
</eucode>

===== Example 2:
<eucode>
 -- executes myprog with two file names as arguments
if system_exec("eui \\test\\myprog.ex indata outdata", 2) then
    puts(2, "failure!\n")
end if
</eucode>

===== See Also:
[[:system]], [[:abort]]



=== Miscellaneous


@[:os:sleep|]
==== sleep
<eucode>
include std/os.e
namespace os
public procedure sleep(atom t)
</eucode>

  suspend thread execution for ##t## seconds.

===== Parameters:
# ##t## : an atom, the number of seconds for which to sleep.

===== Comments:
The operating system will suspend your process and schedule other processes.

With multiple tasks, the whole program sleeps, not just the current task. To make
just the current task sleep, you can call ##[[:task_schedule]]([[:task_self]](), {i, i})##
and then execute [[:task_yield]]. Another option is to call [[:task_delay]].

===== Example 1:
<eucode>
puts(1, "Waiting 15 seconds and a quarter...\n")
sleep(15.25)
puts(1, "Done.\n")
</eucode>

===== See Also:
[[:task_schedule]], [[:task_yield]], [[:task_delay]]



!!CONTEXT:../include/std/pipeio.e
!!namespace:pipeio
%%output = std_pipeio

== Pipe Input and Output

<<LEVELTOC level=2 depth=4>>

=== Notes
Due to a bug, Euphoria does not handle ##STDERR## properly.
##STDERR## cannot captured for Euphoria programs (other programs will work fully)
The IO functions currently work with file handles, a future version might wrap them in streams
so that they can be used directly alongside other file/socket/other-streams with a
##stream_select## function.



=== Accessor Constants


@[:pipeio:STDIN|]
==== STDIN
<eucode>
include std/pipeio.e
namespace pipeio
public enum STDIN
</eucode>

 Child processes standard input



@[:pipeio:STDOUT|]
==== STDOUT
<eucode>
include std/pipeio.e
namespace pipeio
public enum STDOUT
</eucode>

 Child processes standard output



@[:pipeio:STDERR|]
==== STDERR
<eucode>
include std/pipeio.e
namespace pipeio
public enum STDERR
</eucode>

 Child processes standard error



@[:pipeio:PID|]
==== PID
<eucode>
include std/pipeio.e
namespace pipeio
public enum PID
</eucode>

 Process ID



@[:pipeio:PARENT|]
==== PARENT
<eucode>
include std/pipeio.e
namespace pipeio
public enum PARENT
</eucode>

 Set of pipes that are for the use of the parent



@[:pipeio:CHILD|]
==== CHILD
<eucode>
include std/pipeio.e
namespace pipeio
public enum CHILD
</eucode>

 Set of pipes that are given to the child ~-- should not be used by the parent



=== Opening and Closing


@[:pipeio:process|]
==== process
<eucode>
include std/pipeio.e
namespace pipeio
public type process(object o)
</eucode>

  Process Type


@[:pipeio:close|]
==== close
<eucode>
include std/pipeio.e
namespace pipeio
public function close(atom fd)
</eucode>

  closes handle ##fd##.

===== Returns:
An **integer**, 0 on success, -1 on failure

===== Example 1:
<eucode>
integer status = pipeio:close(p[STDIN])
</eucode>



@[:pipeio:kill|]
==== kill
<eucode>
include std/pipeio.e
namespace pipeio
public procedure kill(process p, atom signal = 15)
</eucode>

  closes pipes and kills process ##p## with signal signal (default 15).

===== Comments:
Signal is ignored on //Windows//.

===== Example 1:
<eucode>
kill(p)
</eucode>



=== Read and Write Process


@[:pipeio:read|]
==== read
<eucode>
include std/pipeio.e
namespace pipeio
public function read(atom fd, integer bytes)
</eucode>

  reads ##bytes## bytes from handle ##fd##.

===== Returns:
A **sequence**, containing data, an empty sequence on EOF or an error code.
Similar to [[:get_bytes]].

===== Example 1:
<eucode>
sequence data=read(p[STDOUT],256)
</eucode>



@[:pipeio:write|]
==== write
<eucode>
include std/pipeio.e
namespace pipeio
public function write(atom fd, sequence str)
</eucode>

  writes ##bytes## to handle ##fd##.

===== Returns:
An **integer**, number of bytes written, or -1 on error

===== Example 1:
<eucode>
integer bytes_written = write(p[STDIN],"Hello World!")
</eucode>



@[:pipeio:error_no|]
==== error_no
<eucode>
include std/pipeio.e
namespace pipeio
public function error_no()
</eucode>

  gets error no from last call to a pipe function.

===== Comments:
Value returned will be OS-specific, and is not always set on //Windows// at least

===== Example 1:
<eucode>
integer error = error_no()
</eucode>



@[:pipeio:create|]
==== create
<eucode>
include std/pipeio.e
namespace pipeio
public function create()
</eucode>

  creates pipes for inter-process communication.

===== Returns:
A **handle**, process handles { {parent side pipes},{child side pipes} }

===== Example 1:
<eucode>
object p = exec("dir", create())
</eucode>



@[:pipeio:exec|]
==== exec
<eucode>
include std/pipeio.e
namespace pipeio
public function exec(sequence cmd, sequence pipe)
</eucode>

  opens process with command line cmd.

===== Returns:
A **handle**, process handles { [[:PID]], [[:STDIN]], [[:STDOUT]], [[:STDERR]] }

===== Example 1:
<eucode>
object p = exec("dir", create())
</eucode>








!!CONTEXT:../include/std/pretty.e
!!namespace:pretty
%%output = std_pretty

== Pretty Printing

<<LEVELTOC level=2 depth=4>>



@[:pretty:PRETTY_DEFAULT|]
==== PRETTY_DEFAULT
<eucode>
include std/pretty.e
namespace pretty
public constant PRETTY_DEFAULT
</eucode>







@[:pretty:DISPLAY_ASCII|]
==== DISPLAY_ASCII
<eucode>
include std/pretty.e
namespace pretty
public enum DISPLAY_ASCII
</eucode>





@[:pretty:INDENT|]
==== INDENT
<eucode>
include std/pretty.e
namespace pretty
public enum INDENT
</eucode>





@[:pretty:START_COLUMN|]
==== START_COLUMN
<eucode>
include std/pretty.e
namespace pretty
public enum START_COLUMN
</eucode>





@[:pretty:WRAP|]
==== WRAP
<eucode>
include std/pretty.e
namespace pretty
public enum WRAP
</eucode>





@[:pretty:INT_FORMAT|]
==== INT_FORMAT
<eucode>
include std/pretty.e
namespace pretty
public enum INT_FORMAT
</eucode>





@[:pretty:FP_FORMAT|]
==== FP_FORMAT
<eucode>
include std/pretty.e
namespace pretty
public enum FP_FORMAT
</eucode>





@[:pretty:MIN_ASCII|]
==== MIN_ASCII
<eucode>
include std/pretty.e
namespace pretty
public enum MIN_ASCII
</eucode>





@[:pretty:MAX_ASCII|]
==== MAX_ASCII
<eucode>
include std/pretty.e
namespace pretty
public enum MAX_ASCII
</eucode>





@[:pretty:MAX_LINES|]
==== MAX_LINES
<eucode>
include std/pretty.e
namespace pretty
public enum MAX_LINES
</eucode>





@[:pretty:LINE_BREAKS|]
==== LINE_BREAKS
<eucode>
include std/pretty.e
namespace pretty
public enum LINE_BREAKS
</eucode>





=== Routines


@[:pretty:pretty_print|]
==== pretty_print
<eucode>
include std/pretty.e
namespace pretty
public procedure pretty_print(integer fn, object x, sequence options = PRETTY_DEFAULT)
</eucode>

  prints an object to a file or device using braces ##{ , , , }##, indentation, and multiple lines
to show the structure.

===== Parameters:
# ##fn## : an integer, the file or device number to write to
# ##x## : the object to display or convert to printable form
# ##options## : is an (up to) 10-element options sequence.

===== Comments:

Pass ##{}## in ##options## to select the defaults, or set options as below:
# display ASCII characters:
** 0 ~-- never
** 1 ~-- alongside any integers in printable ASCII range (default)
** 2 ~--  display as "string" when all integers of a sequence
are in ASCII range
** 3 ~-- show strings, and quoted characters (only) for any integers
in ASCII range as well as the characters: \t \r \n
# amount to indent for each level of sequence nesting ~-- default: 2
# column we are starting at ~-- default: 1
# approximate column to wrap at ~-- default: 78
# format to use for integers ~-- default: "%d"
# format to use for floating-point numbers ~-- default: "%.10g"
# minimum value for printable ASCII ~-- default 32
# maximum value for printable ASCII ~-- default 127
# maximum number of lines to output
# line breaks between elements   ~-- default 1 (0 = no line breaks, -1 = line breaks to wrap only)

If the length is less than ten, unspecified options at
the end of the sequence will keep the default values.
For example: ##{0, 5}## will choose ##"never display ASCII"##,
plus 5-character indentation, with defaults for everything else.

The default options can be applied using the public constant ##PRETTY_DEFAULT##, and the
elements may be accessed using the following public enum~:

# ##DISPLAY_ASCII##
# ##INDENT##
# ##START_COLUMN##
# ##WRAP##
# ##INT_FORMAT##
# ##FP_FORMAT##
# ##MIN_ASCII##
# ##MAX_ASCII##
# ##MAX_LINES##
# ##LINE_BREAKS##

The display will start at the current cursor position. Normally you will want to call
##pretty_print## when the cursor is in column 1 (after printing a ##\n## character).
If you want to start in a different column, you should call ##position## and specify a value
for option ##[3]##. This will ensure that the first and last braces in a sequence line up
vertically.

When specifying the format to use for integers and floating-point numbers, you can add
some decoration. For example: ##"(%d)"## or ##"$ %.2f"## .

===== Example 1:
<eucode>
pretty_print(1, "ABC", {})    

{65'A',66'B',67'C'}
</eucode>

===== Example 2:
<eucode>
pretty_print(1, {{1,2,3}, {4,5,6}}, {})  

{
  {1,2,3},
  {4,5,6}
}
</eucode>

===== Example 3:
<eucode>
pretty_print(1, {"Euphoria", "Programming", "Language"}, {2})  

{
  "Euphoria",
  "Programming",
  "Language"
}
</eucode>

===== Example 4:
<eucode>
puts(1, "word_list = ") -- moves cursor to column 13
pretty_print(1, 
    {{"Euphoria", 8, 5.3}, 
     {"Programming", 11, -2.9}, 
     {"Language", 8, 9.8}}, 
     {2, 4, 13, 78, "%03d", "%.3f"}) -- first 6 of 8 options

word_list = {
    {
        "Euphoria",
        008,
        5.300
    },
    {
        "Programming",
        011,
        -2.900
    },
    {
        "Language",
        008,
        9.800
    }
}
</eucode>

===== See Also:
[[:print]], [[:sprint]], [[:printf]], [[:sprintf]], [[:pretty_sprint]]



@[:pretty:pretty_sprint|]
==== pretty_sprint
<eucode>
include std/pretty.e
namespace pretty
public function pretty_sprint(object x, sequence options = PRETTY_DEFAULT)
</eucode>

  formats an object using braces { , , , }, indentation, and multiple lines to show the structure.

===== Parameters:
# ##x## : the object to display
# ##options## : is an (up to) 10-element options sequence: Pass {} to select the defaults, or
set options

===== Returns:
A **sequence**, of printable characters, representing ##x## in an human-readable form.

===== Comments:

This function formats objects the same as [[:pretty_print]] but returns the sequence obtained instead of sending it to some file..

===== See Also:
[[:pretty_print]], [[:sprint]]



!!CONTEXT:../include/std/task.e
!!namespace:task
%%output = std_task

== Multi-Tasking

<<LEVELTOC level=2 depth=4>>

=== General Notes

For a complete overview of the task system, please see the mini-guide
[[:Multitasking in Euphoria]].

=== Warning

The task system does not yet function in a shared library. Task routine
calls that are compiled into a shared library are emitted as a NOP (no
operation) and will therefore have no effect.

It is planned to allow the task system to function in shared libraries
in future versions of OpenEuphoria.

=== Routines


@[:task:task_delay|]
==== task_delay
<eucode>
include std/task.e
namespace task
public procedure task_delay(atom delaytime)
</eucode>

  suspends a task for a short period, allowing other tasks to run in the meantime.

===== Parameters:
# ##delaytime## : an atom, the duration of the delay in seconds.

===== Comments:

This procedure is similar to [[:sleep]] but allows for other tasks to run by yielding on a regular basis.
Like [[:sleep]] its argument needs not being an integer.

===== See Also:
[[:sleep]]


@[:eu:task_clock_start|]
==== task_clock_start
<eucode>
<built-in> procedure task_clock_start()
</eucode>

restarts the clock used for scheduling real-time tasks.

===== Comments:

Call this routine, some time after calling ##task_clock_stop##, when you want scheduling of real-time tasks to continue.

[[:task_clock_stop]] and ##task_clock_start## can be used to freeze the scheduling of real-time tasks.

##task_clock_start## causes the scheduled times of all real-time tasks to be incremented by
the amount of time since [[:task_clock_stop]] was called. This allows a game,
simulation, or other program to continue smoothly.

Time-shared tasks are not affected.

===== Example 1:
<eucode>
 -- freeze the game while the player answers the phone
task_clock_stop()
while get_key() = -1 do
end while
task_clock_start()
</eucode>

===== See Also:
[[:task_clock_stop]], [[:task_schedule]], [[:task_yield]], [[:task_suspend]],
[[:task_delay]]



@[:eu:task_clock_stop|]
==== task_clock_stop
<eucode>
<built-in> procedure task_clock_stop()
</eucode>

stops the scheduling of real-time tasks.

===== Comments:

Call ##task_clock_stop## when you want to take time out from scheduling real-time tasks.
For instance, you want to temporarily suspend a game or simulation for a period of time.

Scheduling will resume when [[:task_clock_start]] is called.

Time-shared tasks can continue. The current task can also continue, unless it is a real-time task and it yields.

The [[:time]] function is not affected by this.

===== See Also:
[[:task_clock_start]], [[:task_schedule]], [[:task_yield]], [[:task_suspend]],
[[:task_delay]]



@[:eu:task_create|]
==== task_create
<eucode>
<built-in> function task_create(integer rid, sequence args)
</eucode>

creates a new task, given a home procedure and the arguments passed to it.

===== Parameters:
# ##rid## : an integer, the routine_id of a user-defined Euphoria procedure.
# ##args## : a sequence, the list of arguments that will be passed to this procedure when the task starts executing.

===== Returns:
An **atom**, a task identifier, created by the system. It can be used to identify this task to the other Euphoria multitasking routines.

===== Errors:
There must be at most 12 parameters in ##args##.

===== Comments:

##task_create## creates a new task, but does not start it executing. You must call [[:task_schedule]] for this purpose.

Each task has its own set of private variables and its own call stack. Global and local variables are shared between all tasks.

If a run-time error is detected, the traceback will include information on all tasks, with the offending task listed first.

Many tasks can be created that all run the same procedure, possibly with different parameters.

A task cannot be based on a function, since there would be no way of using the function result.

Each task id is unique. ##task_create## never returns the same task id as it did before.
Task id's are integer-valued atoms and can be as large as the largest integer-valued atom (15 digits).

===== Example 1:
<eucode>
 mytask = task_create(routine_id("myproc"), {5, 9, "ABC"})
</eucode>

===== See Also:
[[:task_schedule]], [[:task_yield]], [[:task_suspend]], [[:task_self]]



@[:eu:task_list|]
==== task_list
<eucode>
<built-in> function task_list()
</eucode>

gets a sequence containing the task id's for all active or suspended tasks.

===== Returns:
A **sequence**, of atoms, the list of all task that are or may be scheduled.

===== Comments:

This function lets you find out which tasks currently exist. Tasks that have terminated are not included.
You can pass a task id to [[:task_status]] to find out more about a particular task.

===== Example 1:
<eucode>
 sequence tasks

tasks = task_list()
for i = 1 to length(tasks) do
    if task_status(tasks[i]) > 0 then
        printf(1, "task %d is active\n", tasks[i])
    end if
end for
</eucode>

===== See Also:
[[:task_status]], [[:task_create]], [[:task_schedule]], [[:task_yield]], [[:task_suspend]]



@[:eu:task_schedule|]
==== task_schedule
<eucode>
<built-in> procedure task_schedule(atom task_id, object schedule)
</eucode>

schedules a task to run using a scheduling parameter.

===== Parameters:
# ##task_id## : an atom, the identifier of a task that did not terminate yet.
# ##schedule## : an object, describing when and how often to run the task.

===== Comments:

##task_id## must have been returned by [[:task_create]].

The task scheduler, which is built-in to the Euphoria run-time system,
will use ##schedule##
as a guide when scheduling this task. It may not always be possible to achieve the desired
number of consecutive runs, or the desired time frame. For instance, a task might take so
long before yielding control, that another task misses its desired time window.

##schedule## is being interpreted as follows~:

##schedule## is an integer~:

This defines ##task_id## as time shared, and tells the task scheduler how many times it
should the task in one burst before it considers running other tasks. ##schedule## must be greater than zero then.

Increasing this count will increase the percentage of CPU time given to the selected task,
while decreasing the percentage given to other time-shared tasks. Use trial and error to find the optimal trade off.
It will also increase the efficiency of the program, since each actual task switch wastes a bit of time.

##schedule## is a sequence~:

In this case, it must be a pair of positive atoms, the first one not being less than the second one.
This defines ##task_id## as a real time task.
The pair states the minimum and maximum times, in seconds, to wait before running the task.
The pair also sets the time interval for subsequent runs of the task, until the next call to ##task_schedule## or [[:task_suspend]].

Real-time tasks have a higher priority. Time-shared tasks are run when no real-time task is ready to execute.

----

A task can switch back and forth between real-time and time-shared. It all depends on the last call to ##task_schedule## for that task.
The scheduler never runs a real-time task before the start of its time frame (min value in the ##{min, max}## pair),
and it tries to avoid missing the task's deadline (max value).

For precise timing, you can specify the same value for min and max. However, by specifying a range of times,
you give the scheduler some flexibility. This allows it to schedule tasks more efficiently,
and avoid non-productive delays.
When the scheduler must delay, it calls [[:sleep]], unless the required delay is very short.
[[:sleep]] lets the operating system run other programs.

The min and max values can be fractional. If the min value is smaller than the resolution of the scheduler's clock
(currently ##0.01## seconds on //Windows// or //Unix//) then accurate time scheduling cannot be performed, but the
scheduler will try to run the task several times in a row to approximate what is desired.

For example, if you ask for a min time of ##0.002## seconds, then the scheduler will try to run your task
##0.01/0.002 = 5## times in a row before waiting for the clock to "click" ahead by ##0.01## .
During the next ##0.01## seconds it will run your task (up to) another 5 times etc. provided
your task can be completed 5 times in one clock period.

At program start-up there is a single task running. Its task id is 0, and initially it is a time-shared task
allowed 1 run per [[:task_yield]]. No other task can run until task 0 executes a [[:task_yield]].

If task 0 (top-level) runs off the end of the main file, the whole program terminates,
regardless of what other tasks may still be active.

If the scheduler finds that no task is active, i.e. no task will ever run again (not even task 0),
it terminates the program with a 0 exit code, similar to ##abort(0)##.

===== Example 1:
<eucode>
-- Task t1 will be executed up to 10 times in a row before
-- other time-shared tasks are given control. If a real-time
-- task needs control, t1 will lose control to the real-time task.
task_schedule(t1, 10)

-- Task t2 will be scheduled to run some time between 4 and 5 seconds
-- from now. Barring any rescheduling of t2, it will continue to
-- execute every 4 to 5 seconds thereafter.
task_schedule(t2, {4, 5})
</eucode>

===== See Also:
[[:task_create]], [[:task_yield]], [[:task_suspend]]



@[:eu:task_self|]
==== task_self
<eucode>
<built-in> function task_self()
</eucode>

returns the task id of the current task.

===== Comments:

This value may be needed, if a task wants to schedule or suspend itself.

===== Example 1:
<eucode>
 -- schedule self
task_schedule(task_self(), {5.9, 6.0})
</eucode>

===== See Also:
[[:task_create]], [[:task_schedule]], [[:task_yield]], [[:task_suspend]]



@[:eu:task_status|]
==== task_status
<eucode>
<built-in> function task_status(atom task_id)
</eucode>

returns the status of a task.

===== Parameters:
# ##task_id## : an atom, the id of the task being queried.

===== Returns:
An **integer**,
* -1 ~-- task does not exist, or terminated
* 0 ~-- task is suspended
* 1 ~-- task is active

===== Comments:

A task might want to know the status of one or more other tasks when deciding whether to proceed with some processing.

===== Example 1:
<eucode>
 integer s

s = task_status(tid)
if s = 1 then
    puts(1, "ACTIVE\n")
elsif s = 0 then
    puts(1, "SUSPENDED\n")
else
    puts(1, "DOESN'T EXIST\n")
end if
</eucode>

===== See Also:
[[:task_list]], [[:task_create]], [[:task_schedule]], [[:task_suspend]]



@[:eu:task_suspend|]
==== task_suspend
<eucode>
<built-in> procedure task_suspend(atom task_id)
</eucode>

suspends execution of a task.

===== Parameters:
# ##task_id## : an atom, the id of the task to suspend.

===== Comments:

A suspended task will not be executed again unless there is a call to [[:task_schedule]] for the task.

##task_id## is a task id returned from [[:task_create]].
-
Any task can suspend any other task. If a task suspends itself, the suspension will start as soon as the task calls [[:task_yield]].

Suspending a task and never scheduling it again is how to kill a task. There is no
##task_kill## primitives because undead tasks were creating too much trouble and confusion.
As a general fact, nothing that impacts a running task can be effective as long as the task has not yielded.

===== Example 1:
<eucode>
 -- suspend task 15
task_suspend(15)

-- suspend current task
task_suspend(task_self())
</eucode>

===== See Also:
[[:task_create]], [[:task_schedule]], [[:task_self]], [[:task_yield]]



@[:eu:task_yield|]
==== task_yield
<eucode>
<built-in> procedure task_yield()
</eucode>

yields control to the scheduler. The scheduler can then choose another task to run, or
perhaps let the current task continue running.

===== Comments:

Tasks should call ##task_yield## periodically so other tasks will have a chance to run.
Only when ##task_yield## is called, is there a way for the scheduler to take back control
from a task. This is what is known as cooperative multitasking.

A task can have calls to ##task_yield## in many different places in its code, and at any depth of subroutine call.

The scheduler will use the current scheduling parameter (see [[:task_schedule]]),
in determining when to return to the current task.

When control returns, execution will continue with the statement that follows ##task_yield##.
The call-stack and all private variables will remain as they were when ##task_yield## was called.
Global and local variables may have changed, due to the execution of other tasks.

Tasks should try to call ##task_yield## often enough to avoid causing real-time tasks to miss their time window,
and to avoid blocking time-shared tasks for an excessive period of time. On the other hand,
there is a bit of overhead in calling ##task_yield##, and this overhead is slightly larger
when an actual switch to a different task takes place.
A ##task_yield## where the same task continues executing takes less time.

A task should avoid calling ##task_yield## when it is in the middle of a delicate operation
that requires exclusive access to some data. Otherwise a race condition could occur, where
one task might interfere with an operation being carried out by another task.
In some cases a task might need to mark some data as "locked" or "unlocked" in order to prevent this possibility.
With cooperative multitasking, these concurrency issues are much less of a problem than with
the preemptive multitasking that other languages support.

===== Example 1:
<eucode>
 -- From Language war game.
-- This small task deducts life support energy from either the
-- large Euphoria ship or the small shuttle.
-- It seems to run "forever" in an infinite loop, 
-- but it's actually a real-time task that is called
-- every 1.7 to 1.8 seconds throughout the game.
-- It deducts either 3 units or 13 units of life support energy each time.

procedure task_life()
-- independent task: subtract life support energy 
    while TRUE do
        if shuttle then
            p_energy(-3)
        else
            p_energy(-13)
        end if
        task_yield()
    end while
end procedure
</eucode>

===== See Also:
[[:task_create]], [[:task_schedule]], [[:task_suspend]]



!!CONTEXT:../include/std/types.e
!!namespace:types
%%output = std_types

== Types - Extended

<<LEVELTOC level=2 depth=4>>


@[:types:OBJ_UNASSIGNED|]
==== OBJ_UNASSIGNED
<eucode>
include std/types.e
namespace types
public constant OBJ_UNASSIGNED
</eucode>

  Object not assigned


@[:types:OBJ_INTEGER|]
==== OBJ_INTEGER
<eucode>
include std/types.e
namespace types
public constant OBJ_INTEGER
</eucode>

  Object is integer


@[:types:OBJ_ATOM|]
==== OBJ_ATOM
<eucode>
include std/types.e
namespace types
public constant OBJ_ATOM
</eucode>

  Object is atom


@[:types:OBJ_SEQUENCE|]
==== OBJ_SEQUENCE
<eucode>
include std/types.e
namespace types
public constant OBJ_SEQUENCE
</eucode>

  Object is sequence


@[:eu:object|]
==== object
<eucode>
<built-in> type object(object x)
</eucode>

returns information about the object type of the supplied argument ##x##.

===== Returns:
# An **integer**,
** ##OBJ_UNASSIGNED## if ##x## has not been assigned anything yet.
** ##OBJ_INTEGER## if ##x## holds an integer value.
** ##OBJ_ATOM## if ##x## holds a number that is not an integer.
** ##OBJ_SEQUENCE## if ##x## holds a sequence value.

===== Example 1:
<eucode>
? object(1) --> OBJ_INTEGER
? object(1.1) --> OBJ_ATOM
? object("1") --> OBJ_SEQUENCE
object x
? object(x) --> OBJ_UNASSIGNED
</eucode>

===== See Also:
[[:sequence]], [[:integer]], [[:atom]]


@[:eu:integer|]
==== integer
<eucode>
<built-in> type integer(object x)
</eucode>

tests the supplied argument ##x## to see if it is an integer or not.

===== Returns:
# An **integer**.
** 1 if ##x## is an integer.
** 0 if ##x## is not an integer.

===== Example 1:
<eucode>
? integer(1) --> 1
? integer(1.1) --> 0
? integer("1") --> 0
</eucode>

===== See Also:
[[:sequence]], [[:object]], [[:atom]]


@[:eu:atom|]
==== atom
<eucode>
<built-in> type atom(object x)
</eucode>

tests the supplied argument ##x## to see if it is an atom or not.

===== Returns:
# An **integer**,
** 1 if ##x## is an atom.
** 0 if ##x## is not an atom.

===== Example 1:
<eucode>
? atom(1) --> 1
? atom(1.1) --> 1
? atom("1") --> 0
</eucode>

===== See Also:
[[:sequence]], [[:object]], [[:integer]]


@[:eu:sequence|]
==== sequence
<eucode>
<built-in> type sequence( object x)
</eucode>

tests the supplied argument ##x## to see if it is a sequence or not.

===== Returns:
# An **integer*,
** 1 if ##x## is a sequence.
** 0 if ##x## is not an sequence.

===== Example 1:
<eucode>
? sequence(1) --> 0
? sequence({1}) --> 1
? sequence("1") --> 1
</eucode>

===== See Also:
[[:integer]], [[:object]], [[:atom]]


@[:types:FALSE|]
==== FALSE
<eucode>
include std/types.e
namespace types
public constant FALSE
</eucode>

  Boolean FALSE value


@[:types:TRUE|]
==== TRUE
<eucode>
include std/types.e
namespace types
public constant TRUE
</eucode>

  Boolean TRUE value


=== Predefined Character Sets


@[:types:CS_FIRST|]
==== CS_FIRST
<eucode>
include std/types.e
namespace types
public enum CS_FIRST
</eucode>





@[:types:CS_Consonant|]
==== CS_Consonant
<eucode>
include std/types.e
namespace types
public enum CS_Consonant
</eucode>





@[:types:CS_Vowel|]
==== CS_Vowel
<eucode>
include std/types.e
namespace types
public enum CS_Vowel
</eucode>





@[:types:CS_Hexadecimal|]
==== CS_Hexadecimal
<eucode>
include std/types.e
namespace types
public enum CS_Hexadecimal
</eucode>





@[:types:CS_Whitespace|]
==== CS_Whitespace
<eucode>
include std/types.e
namespace types
public enum CS_Whitespace
</eucode>





@[:types:CS_Punctuation|]
==== CS_Punctuation
<eucode>
include std/types.e
namespace types
public enum CS_Punctuation
</eucode>





@[:types:CS_Printable|]
==== CS_Printable
<eucode>
include std/types.e
namespace types
public enum CS_Printable
</eucode>





@[:types:CS_Displayable|]
==== CS_Displayable
<eucode>
include std/types.e
namespace types
public enum CS_Displayable
</eucode>





@[:types:CS_Lowercase|]
==== CS_Lowercase
<eucode>
include std/types.e
namespace types
public enum CS_Lowercase
</eucode>





@[:types:CS_Uppercase|]
==== CS_Uppercase
<eucode>
include std/types.e
namespace types
public enum CS_Uppercase
</eucode>





@[:types:CS_Alphanumeric|]
==== CS_Alphanumeric
<eucode>
include std/types.e
namespace types
public enum CS_Alphanumeric
</eucode>





@[:types:CS_Identifier|]
==== CS_Identifier
<eucode>
include std/types.e
namespace types
public enum CS_Identifier
</eucode>





@[:types:CS_Alphabetic|]
==== CS_Alphabetic
<eucode>
include std/types.e
namespace types
public enum CS_Alphabetic
</eucode>





@[:types:CS_ASCII|]
==== CS_ASCII
<eucode>
include std/types.e
namespace types
public enum CS_ASCII
</eucode>





@[:types:CS_Control|]
==== CS_Control
<eucode>
include std/types.e
namespace types
public enum CS_Control
</eucode>





@[:types:CS_Digit|]
==== CS_Digit
<eucode>
include std/types.e
namespace types
public enum CS_Digit
</eucode>





@[:types:CS_Graphic|]
==== CS_Graphic
<eucode>
include std/types.e
namespace types
public enum CS_Graphic
</eucode>





@[:types:CS_Bytes|]
==== CS_Bytes
<eucode>
include std/types.e
namespace types
public enum CS_Bytes
</eucode>





@[:types:CS_SpecWord|]
==== CS_SpecWord
<eucode>
include std/types.e
namespace types
public enum CS_SpecWord
</eucode>





@[:types:CS_Boolean|]
==== CS_Boolean
<eucode>
include std/types.e
namespace types
public enum CS_Boolean
</eucode>





@[:types:CS_LAST|]
==== CS_LAST
<eucode>
include std/types.e
namespace types
public enum CS_LAST
</eucode>





=== Support Functions



@[:types:char_test|]
==== char_test
<eucode>
include std/types.e
namespace types
public function char_test(object test_data, sequence char_set)
</eucode>

  determines whether one or more characters are in a given character set.

===== Parameters:
# ##test_data## : an object to test, either a character or a string
# ##char_set## : a sequence, either a list of allowable characters, or a list of pairs representing allowable ranges.

===== Returns:
An **integer**, 1 if all characters are allowed, else 0.

===== Comments:

##pCharset## is either a simple sequence of characters (such as ##"qwertyuiop[]\"##)
or a sequence of character pairs, which represent allowable ranges
of characters. For example  Alphabetic is defined as ##{{'a','z'}, {'A', 'Z'}}##.

To add an isolated character to a character set which is defined using ranges, present it as a range of length 1, like in ##{%,%}##.

===== Example 1:
<eucode>
char_test("ABCD", {{'A', 'D'}})
-- TRUE, every char is in the range 'A' to 'D'

char_test("ABCD", {{'A', 'C'}})
-- FALSE, not every char is in the range 'A' to 'C'

char_test("Harry", {{'a', 'z'}, {'D', 'J'}})
-- TRUE, every char is either in the range 'a' to 'z', 
--       or in the range 'D' to 'J'

char_test("Potter", "novel")
-- FALSE, not every character is in the set 'n', 'o', 'v', 'e', 'l'
</eucode>


@[:types:set_default_charsets|]
==== set_default_charsets
<eucode>
include std/types.e
namespace types
public procedure set_default_charsets()
</eucode>

  sets all the defined character sets to their default definitions.

===== Example 1:
<eucode>
set_default_charsets()
</eucode>


@[:types:get_charsets|]
==== get_charsets
<eucode>
include std/types.e
namespace types
public function get_charsets()
</eucode>

  gets the definition for each of the defined character sets.

===== Returns:
A **sequence**, of pairs. The first element of each pair
is the character set id ( such as ##CS_Whitespace## ) and the second is the definition
of that character set.

===== Comments:
This is the same format required for the [[:set_charsets]] routine.

===== Example 1:
<eucode>
sequence sets
sets = get_charsets()
</eucode>

===== See Also:
[[:set_charsets]], [[:set_default_charsets]]


@[:types:set_charsets|]
==== set_charsets
<eucode>
include std/types.e
namespace types
public procedure set_charsets(sequence charset_list)
</eucode>

  sets the definition for one or more defined character sets.

===== Parameters:
# ##charset_list## : a sequence of zero or more character set definitions.

===== Comments:
##charset_list## must be a sequence of pairs. The first element of each pair
is the character set id (such as ##CS_Whitespace##) and the second is the definition
of that character set.

This is the same format returned by the [[:get_charsets]] routine.

You cannot create new character sets using this routine.

===== Example 1:
<eucode>
set_charsets({{CS_Whitespace, " \t"}})
t_space('\n') --> FALSE

t_specword('$') --> FALSE
set_charsets({{CS_SpecWord, "_-#$%"}})
t_specword('$') --> TRUE
</eucode>

===== See Also:
[[:get_charsets]]


=== Types



@[:types:boolean|]
==== boolean
<eucode>
include std/types.e
namespace types
public type boolean(object test_data)
</eucode>

  test for an integer boolean.

===== Returns:
Returns TRUE if argument is 1 or 0

Returns FALSE if the argument is anything else other than 1 or 0.

===== Example 1:
<eucode>
boolean(-1)            -- FALSE
boolean(0)             -- TRUE
boolean(1)             -- TRUE
boolean(1.234)         -- FALSE
boolean('A')           -- FALSE
boolean('9')           -- FALSE
boolean('?')           -- FALSE
boolean("abc")         -- FALSE
boolean("ab3")         -- FALSE
boolean({1,2,"abc"})   -- FALSE
boolean({1, 2, 9.7)    -- FALSE
boolean({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_boolean|]
==== t_boolean
<eucode>
include std/types.e
namespace types
public type t_boolean(object test_data)
</eucode>

  tests elements for boolean.

===== Returns:
Returns TRUE if argument is boolean (1 or 0) or if every element of
the argument is boolean.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-boolean elements

===== Example 1:
<eucode>
t_boolean(-1)            -- FALSE
t_boolean(0)             -- TRUE
t_boolean(1)             -- TRUE
t_boolean({1, 1, 0})     -- TRUE
t_boolean({1, 1, 9.7})    -- FALSE
t_boolean({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_alnum|]
==== t_alnum
<eucode>
include std/types.e
namespace types
public type t_alnum(object test_data)
</eucode>

  tests for  alphanumeric character.

===== Returns:
Returns TRUE if argument is an alphanumeric character or if every element of
the argument is an alphanumeric character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-alphanumeric elements

===== Example 1:
<eucode>
t_alnum(-1)            -- FALSE
t_alnum(0)             -- FALSE
t_alnum(1)             -- FALSE
t_alnum(1.234)         -- FALSE
t_alnum('A')           -- TRUE
t_alnum('9')           -- TRUE
t_alnum('?')           -- FALSE
t_alnum("abc")         -- TRUE (every element is alphabetic or a digit)
t_alnum("ab3")         -- TRUE
t_alnum({1, 2, "abc"}) -- FALSE (contains a sequence)
t_alnum({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_alnum({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_identifier|]
==== t_identifier
<eucode>
include std/types.e
namespace types
public type t_identifier(object test_data)
</eucode>

  tests string if it is an valid identifier.

===== Returns:
Returns TRUE if argument is an alphanumeric character or if every element of
the argument is an alphanumeric character and that the first character is not
numeric and the whole group of characters are not all numeric.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-alphanumeric elements

===== Example 1:
<eucode>
t_identifier(-1)            -- FALSE
t_identifier(0)             -- FALSE
t_identifier(1)             -- FALSE
t_identifier(1.234)         -- FALSE
t_identifier('A')           -- TRUE
t_identifier('9')           -- FALSE
t_identifier('?')           -- FALSE
t_identifier("abc")         -- TRUE (every element is alphabetic or a digit)
t_identifier("ab3")         -- TRUE
t_identifier("ab_3")        -- TRUE (underscore is allowed)
t_identifier("1abc")        -- FALSE (identifier cannot start with a number)
t_identifier("102")         -- FALSE (identifier cannot be all numeric)
t_identifier({1, 2, "abc"}) -- FALSE (contains a sequence)
t_identifier({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_identifier({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_alpha|]
==== t_alpha
<eucode>
include std/types.e
namespace types
public type t_alpha(object test_data)
</eucode>

  tests for alphabetic characters.

===== Returns:
Returns TRUE if argument is an alphabetic character or if every element of
the argument is an alphabetic character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-alphabetic elements

===== Example 1:
<eucode>
t_alpha(-1)            -- FALSE
t_alpha(0)             -- FALSE
t_alpha(1)             -- FALSE
t_alpha(1.234)         -- FALSE
t_alpha('A')           -- TRUE
t_alpha('9')           -- FALSE
t_alpha('?')           -- FALSE
t_alpha("abc")         -- TRUE (every element is alphabetic)
t_alpha("ab3")         -- FALSE
t_alpha({1, 2, "abc"}) -- FALSE (contains a sequence)
t_alpha({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_alpha({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_ascii|]
==== t_ascii
<eucode>
include std/types.e
namespace types
public type t_ascii(object test_data)
</eucode>

  tests for ASCII characters.

===== Returns:
Returns TRUE if argument is an ASCII character or if every element of
the argument is an ASCII character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-ASCII elements

===== Example 1:
<eucode>
t_ascii(-1)            -- FALSE
t_ascii(0)             -- TRUE
t_ascii(1)             -- TRUE
t_ascii(1.234)         -- FALSE
t_ascii('A')           -- TRUE
t_ascii('9')           -- TRUE
t_ascii('?')           -- TRUE
t_ascii("abc")         -- TRUE (every element is ascii)
t_ascii("ab3")         -- TRUE
t_ascii({1, 2, "abc"}) -- FALSE (contains a sequence)
t_ascii({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_ascii({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_cntrl|]
==== t_cntrl
<eucode>
include std/types.e
namespace types
public type t_cntrl(object test_data)
</eucode>

  tests for control characters.

===== Returns:
Returns TRUE if argument is an Control character or if every element of
the argument is an Control character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-Control elements

===== Example 1:
<eucode>
t_cntrl(-1)            -- FALSE
t_cntrl(0)             -- TRUE
t_cntrl(1)             -- TRUE
t_cntrl(1.234)         -- FALSE
t_cntrl('A')           -- FALSE
t_cntrl('9')           -- FALSE
t_cntrl('?')           -- FALSE
t_cntrl("abc")         -- FALSE (every element is ascii)
t_cntrl("ab3")         -- FALSE
t_cntrl({1, 2, "abc"}) -- FALSE (contains a sequence)
t_cntrl({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_cntrl({1, 2, 'a'})    -- FALSE (contains a non-control)
t_cntrl({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_digit|]
==== t_digit
<eucode>
include std/types.e
namespace types
public type t_digit(object test_data)
</eucode>

  tests for digits.

===== Returns:
Returns TRUE if argument is an digit character or if every element of
the argument is an digit character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-digits

===== Example 1:
<eucode>
t_digit(-1)            -- FALSE
t_digit(0)             -- FALSE
t_digit(1)             -- FALSE
t_digit(1.234)         -- FALSE
t_digit('A')           -- FALSE
t_digit('9')           -- TRUE
t_digit('?')           -- FALSE
t_digit("abc")         -- FALSE
t_digit("ab3")         -- FALSE
t_digit("123")         -- TRUE
t_digit({1, 2, "abc"}) -- FALSE (contains a sequence)
t_digit({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_digit({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_digit({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_graph|]
==== t_graph
<eucode>
include std/types.e
namespace types
public type t_graph(object test_data)
</eucode>

  test for glyphs (printable) characters.

===== Returns:
Returns TRUE if argument is a glyph character or if every element of
the argument is a glyph character. (One that is visible when displayed)

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-glyph

===== Example 1:
<eucode>
t_graph(-1)            -- FALSE
t_graph(0)             -- FALSE
t_graph(1)             -- FALSE
t_graph(1.234)         -- FALSE
t_graph('A')           -- TRUE
t_graph('9')           -- TRUE
t_graph('?')           -- TRUE
t_graph(' ')           -- FALSE
t_graph("abc")         -- TRUE
t_graph("ab3")         -- TRUE
t_graph("123")         -- TRUE
t_graph({1, 2, "abc"}) -- FALSE (contains a sequence)
t_graph({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_graph({1, 2, 'a'})    -- FALSE (control chars (1,2) don't have glyphs)
t_graph({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_specword|]
==== t_specword
<eucode>
include std/types.e
namespace types
public type t_specword(object test_data)
</eucode>

  tests for a special word character.

===== Returns:
Returns TRUE if argument is a special word character or if every element of
the argument is a special word character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-special-word characters.

===== Comments:
A //special word character// is any character that is not normally part of
a word but in certain cases may be considered. This is most commonly used
when looking for words in programming source code which allows an underscore
as a word character.

===== Example 1:
<eucode>
t_specword(-1)            -- FALSE
t_specword(0)             -- FALSE
t_specword(1)             -- FALSE
t_specword(1.234)         -- FALSE
t_specword('A')           -- FALSE
t_specword('9')           -- FALSE
t_specword('?')           -- FALSE
t_specword('_')           -- TRUE
t_specword("abc")         -- FALSE
t_specword("ab3")         -- FALSE
t_specword("123")         -- FALSE
t_specword({1, 2, "abc"}) -- FALSE (contains a sequence)
t_specword({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_specword({1, 2, 'a'})    -- FALSE (control chars (1,2) don't have glyphs)
t_specword({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_bytearray|]
==== t_bytearray
<eucode>
include std/types.e
namespace types
public type t_bytearray(object test_data)
</eucode>

  tests for bytes.

===== Returns:
Returns TRUE if argument is a byte or if every element of
the argument is a byte. (Integers from 0 to 255)

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-byte

===== Example 1:
<eucode>
t_bytearray(-1)            -- FALSE (contains value less than zero)
t_bytearray(0)             -- TRUE
t_bytearray(1)             -- TRUE
t_bytearray(10)            -- TRUE
t_bytearray(100)           -- TRUE
t_bytearray(1000)          -- FALSE (greater than 255)
t_bytearray(1.234)         -- FALSE (contains a floating number)
t_bytearray('A')           -- TRUE
t_bytearray('9')           -- TRUE
t_bytearray('?')           -- TRUE
t_bytearray(' ')           -- TRUE
t_bytearray("abc")         -- TRUE
t_bytearray("ab3")         -- TRUE
t_bytearray("123")         -- TRUE
t_bytearray({1, 2, "abc"}) -- FALSE (contains a sequence)
t_bytearray({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_bytearray({1, 2, 'a'})    -- TRUE
t_bytearray({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_lower|]
==== t_lower
<eucode>
include std/types.e
namespace types
public type t_lower(object test_data)
</eucode>

  tests for lowercase characters.

===== Returns:
Returns TRUE if argument is a lowercase character or if every element of
the argument is an lowercase character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-lowercase

===== Example 1:
<eucode>
t_lower(-1)            -- FALSE
t_lower(0)             -- FALSE
t_lower(1)             -- FALSE
t_lower(1.234)         -- FALSE
t_lower('A')           -- FALSE
t_lower('9')           -- FALSE
t_lower('?')           -- FALSE
t_lower("abc")         -- TRUE
t_lower("ab3")         -- FALSE
t_lower("123")         -- TRUE
t_lower({1, 2, "abc"}) -- FALSE (contains a sequence)
t_lower({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_lower({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_lower({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_print|]
==== t_print
<eucode>
include std/types.e
namespace types
public type t_print(object test_data)
</eucode>

  tests for ASCII glyph characters.

===== Returns:
Returns TRUE if argument is a character that has an ASCII glyph or if every element of
the argument is a character that has an ASCII glyph.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains characters that do not have an ASCII glyph.

===== Example 1:
<eucode>
t_print(-1)            -- FALSE
t_print(0)             -- FALSE
t_print(1)             -- FALSE
t_print(1.234)         -- FALSE
t_print('A')           -- TRUE
t_print('9')           -- TRUE
t_print('?')           -- TRUE
t_print("abc")         -- TRUE
t_print("ab3")         -- TRUE
t_print("123")         -- TRUE
t_print("123 ")        -- FALSE (contains a space)
t_print("123\n")       -- FALSE (contains a new-line)
t_print({1, 2, "abc"}) -- FALSE (contains a sequence)
t_print({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_print({1, 2, 'a'})    -- FALSE
t_print({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_display|]
==== t_display
<eucode>
include std/types.e
namespace types
public type t_display(object test_data)
</eucode>

  tests for printable characters.

===== Returns:
Returns TRUE if argument is a character that can be displayed or if every element of
the argument is a character that can be displayed.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains characters that cannot be displayed.

===== Example 1:
<eucode>
t_display(-1)            -- FALSE
t_display(0)             -- FALSE
t_display(1)             -- FALSE
t_display(1.234)         -- FALSE
t_display('A')           -- TRUE
t_display('9')           -- TRUE
t_display('?')           -- TRUE
t_display("abc")         -- TRUE
t_display("ab3")         -- TRUE
t_display("123")         -- TRUE
t_display("123 ")        -- TRUE
t_display("123\n")       -- TRUE
t_display({1, 2, "abc"}) -- FALSE (contains a sequence)
t_display({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_display({1, 2, 'a'})    -- FALSE
t_display({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_punct|]
==== t_punct
<eucode>
include std/types.e
namespace types
public type t_punct(object test_data)
</eucode>

  tests for punctuation characters.

===== Returns:
Returns TRUE if argument is an punctuation character or if every element of
the argument is an punctuation character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-punctuation symbols.

===== Example 1:
<eucode>
t_punct(-1)            -- FALSE
t_punct(0)             -- FALSE
t_punct(1)             -- FALSE
t_punct(1.234)         -- FALSE
t_punct('A')           -- FALSE
t_punct('9')           -- FALSE
t_punct('?')           -- TRUE
t_punct("abc")         -- FALSE
t_punct("(-)")         -- TRUE
t_punct("123")         -- TRUE
t_punct({1, 2, "abc"}) -- FALSE (contains a sequence)
t_punct({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_punct({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_punct({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_space|]
==== t_space
<eucode>
include std/types.e
namespace types
public type t_space(object test_data)
</eucode>

  tests for whitespace characters.

===== Returns:
Returns TRUE if argument is a whitespace character or if every element of
the argument is an whitespace character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-whitespace character.

===== Example 1:
<eucode>
t_space(-1)            -- FALSE
t_space(0)             -- FALSE
t_space(1)             -- FALSE
t_space(1.234)         -- FALSE
t_space('A')           -- FALSE
t_space('9')           -- FALSE
t_space('\t')          -- TRUE
t_space("abc")         -- FALSE
t_space("123")         -- FALSE
t_space({1, 2, "abc"}) -- FALSE (contains a sequence)
t_space({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_space({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_space({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_upper|]
==== t_upper
<eucode>
include std/types.e
namespace types
public type t_upper(object test_data)
</eucode>

  tests for uppercase characters.

===== Returns:
Returns TRUE if argument is an uppercase character or if every element of
the argument is an uppercase character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-uppercase characters.

===== Example 1:
<eucode>
t_upper(-1)            -- FALSE
t_upper(0)             -- FALSE
t_upper(1)             -- FALSE
t_upper(1.234)         -- FALSE
t_upper('A')           -- TRUE
t_upper('9')           -- FALSE
t_upper('?')           -- FALSE
t_upper("abc")         -- FALSE
t_upper("ABC")         -- TRUE
t_upper("123")         -- FALSE
t_upper({1, 2, "abc"}) -- FALSE (contains a sequence)
t_upper({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_upper({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_upper({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_xdigit|]
==== t_xdigit
<eucode>
include std/types.e
namespace types
public type t_xdigit(object test_data)
</eucode>

  tests for hexadecimal characters.

===== Returns:
Returns TRUE if argument is an hexadecimal digit character or if every element of
the argument is an hexadecimal digit character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-hexadecimal character.

===== Example 1:
<eucode>
t_xdigit(-1)            -- FALSE
t_xdigit(0)             -- FALSE
t_xdigit(1)             -- FALSE
t_xdigit(1.234)         -- FALSE
t_xdigit('A')           -- TRUE
t_xdigit('9')           -- TRUE
t_xdigit('?')           -- FALSE
t_xdigit("abc")         -- TRUE
t_xdigit("fgh")         -- FALSE
t_xdigit("123")         -- TRUE
t_xdigit({1, 2, "abc"}) -- FALSE (contains a sequence)
t_xdigit({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_xdigit({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_xdigit({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_vowel|]
==== t_vowel
<eucode>
include std/types.e
namespace types
public type t_vowel(object test_data)
</eucode>

  tests for vowel characters.

===== Returns:
Returns TRUE if argument is a vowel or if every element of
the argument is a vowel character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-vowels

===== Example 1:
<eucode>
t_vowel(-1)            -- FALSE
t_vowel(0)             -- FALSE
t_vowel(1)             -- FALSE
t_vowel(1.234)         -- FALSE
t_vowel('A')           -- TRUE
t_vowel('9')           -- FALSE
t_vowel('?')           -- FALSE
t_vowel("abc")         -- FALSE
t_vowel("aiu")         -- TRUE
t_vowel("123")         -- FALSE
t_vowel({1, 2, "abc"}) -- FALSE (contains a sequence)
t_vowel({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_vowel({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_vowel({})            -- FALSE (empty sequence)
</eucode>


@[:types:t_consonant|]
==== t_consonant
<eucode>
include std/types.e
namespace types
public type t_consonant(object test_data)
</eucode>

  tests for consonant characters.

===== Returns:
Returns TRUE if argument is a consonant character or if every element of
the argument is an consonant character.

Returns FALSE if the argument is an empty sequence, or contains sequences,
or contains non-consonant character.

===== Example 1:
<eucode>
t_consonant(-1)            -- FALSE
t_consonant(0)             -- FALSE
t_consonant(1)             -- FALSE
t_consonant(1.234)         -- FALSE
t_consonant('A')           -- FALSE
t_consonant('9')           -- FALSE
t_consonant('?')           -- FALSE
t_consonant("abc")         -- FALSE
t_consonant("rTfM")        -- TRUE
t_consonant("123")         -- FALSE
t_consonant({1, 2, "abc"}) -- FALSE (contains a sequence)
t_consonant({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_consonant({1, 2, 'a'})    -- FALSE (contains a non-digit)
t_consonant({})            -- FALSE (empty sequence)
</eucode>


@[:types:integer_array|]
==== integer_array
<eucode>
include std/types.e
namespace types
public type integer_array(object x)
</eucode>

  tests for integer elements.

===== Returns:
TRUE if argument is a sequence that only contains zero or more integers.

===== Example 1:
<eucode>
integer_array(-1)            -- FALSE (not a sequence)
integer_array("abc")         -- TRUE (all single characters)
integer_array({1, 2, "abc"}) -- FALSE (contains a sequence)
integer_array({1, 2, 9.7})    -- FALSE (contains a non-integer)
integer_array({1, 2, 'a'})    -- TRUE
integer_array({})            -- TRUE
</eucode>


@[:types:t_text|]
==== t_text
<eucode>
include std/types.e
namespace types
public type t_text(object x)
</eucode>

  tests for text characters.

===== Returns:
TRUE if argument is a sequence that only contains zero or more characters.

===== Comments:
A **character** is defined as a positive integer or zero. This is a broad
definition that may be refined once proper UNICODE support is implemented.

===== Example 1:
<eucode>
t_text(-1)            -- FALSE (not a sequence)
t_text("abc")         -- TRUE (all single characters)
t_text({1, 2, "abc"}) -- FALSE (contains a sequence)
t_text({1, 2, 9.7})    -- FALSE (contains a non-integer)
t_text({1, 2, 'a'})    -- TRUE
t_text({1, -2, 'a'})   -- FALSE (contains a negative integer)
t_text({})            -- TRUE
</eucode>


@[:types:number_array|]
==== number_array
<eucode>
include std/types.e
namespace types
public type number_array(object x)
</eucode>

  tests for atom elements.

===== Returns:
TRUE if argument is a sequence that only contains zero or more numbers.

===== Example 1:
<eucode>
number_array(-1)            -- FALSE (not a sequence)
number_array("abc")         -- TRUE (all single characters)
number_array({1, 2, "abc"}) -- FALSE (contains a sequence)
number_array(1, 2, 9.7})    -- TRUE
number_array(1, 2, 'a'})    -- TRUE
number_array({})            -- TRUE
</eucode>


@[:types:sequence_array|]
==== sequence_array
<eucode>
include std/types.e
namespace types
public type sequence_array(object x)
</eucode>

  tests for sequence with possible nested sequences.

===== Returns:
TRUE if argument is a sequence that only contains zero or more sequences.

===== Example 1:
<eucode>
sequence_array(-1)            -- FALSE (not a sequence)
sequence_array("abc")         -- FALSE (all single characters)
sequence_array({1, 2, "abc"}) -- FALSE (contains some atoms)
sequence_array({1, 2, 9.7})   -- FALSE
sequence_array({1, 2, 'a'})   -- FALSE
sequence_array({"abc", {3.4, 99182.78737}}) -- TRUE
sequence_array({})            -- TRUE
</eucode>


@[:types:ascii_string|]
==== ascii_string
<eucode>
include std/types.e
namespace types
public type ascii_string(object x)
</eucode>

  tests for ASCII elements.

===== Returns:
TRUE if argument is a sequence that only contains zero or more ASCII characters.

===== Comments:
An ASCII 'character' is defined as a integer in the range [0 to 127].

===== Example 1:
<eucode>
ascii_string(-1)            -- FALSE (not a sequence)
ascii_string("abc")         -- TRUE (all single ASCII characters)
ascii_string({1, 2, "abc"}) -- FALSE (contains a sequence)
ascii_string({1, 2, 9.7})    -- FALSE (contains a non-integer)
ascii_string({1, 2, 'a'})    -- TRUE
ascii_string({1, -2, 'a'})   -- FALSE (contains a negative integer)
ascii_string({})            -- TRUE
</eucode>


@[:types:string|]
==== string
<eucode>
include std/types.e
namespace types
public type string(object x)
</eucode>

  tests for a string sequence.

===== Returns:
TRUE if argument is a sequence that only contains zero or more byte characters.

===== Comments:
A byte 'character' is defined as a integer in the range [0 to 255].

===== Example 1:
<eucode>
string(-1)            -- FALSE (not a sequence)
string("abc'6")       -- TRUE (all single byte characters)
string({1, 2, "abc'6"}) -- FALSE (contains a sequence)
string({1, 2, 9.7})    -- FALSE (contains a non-integer)
string({1, 2, 'a'})    -- TRUE
string({1, 2, 'a', 0}) -- TRUE (even though it contains a null byte)
string({1, -2, 'a'})   -- FALSE (contains a negative integer)
string({})            -- TRUE
</eucode>


@[:types:cstring|]
==== cstring
<eucode>
include std/types.e
namespace types
public type cstring(object x)
</eucode>

  tests for a string sequence (that has no null character).

===== Returns:
TRUE if argument is a sequence that only contains zero or more non-null byte characters.

===== Comments:
A non-null byte 'character' is defined as a integer in the range [1 to 255].

===== Example 1:
<eucode>
cstring(-1)            -- FALSE (not a sequence)
cstring("abc'6")       -- TRUE (all single byte characters)
cstring({1, 2, "abc'6"}) -- FALSE (contains a sequence)
cstring({1, 2, 9.7})    -- FALSE (contains a non-integer)
cstring({1, 2, 'a'})    -- TRUE
cstring({1, 2, 'a', 0}) -- FALSE (contains a null byte)
cstring({1, -2, 'a'})   -- FALSE (contains a negative integer)
cstring({})            -- TRUE
</eucode>


@[:types:INVALID_ROUTINE_ID|]
==== INVALID_ROUTINE_ID
<eucode>
include std/types.e
namespace types
public constant INVALID_ROUTINE_ID
</eucode>

  Value returned from [[:routine_id]]
when the routine does not exist or is out of scope.
This is typically seen as -1 in legacy code.


@[:types:NO_ROUTINE_ID|]
==== NO_ROUTINE_ID
<eucode>
include std/types.e
namespace types
public constant NO_ROUTINE_ID
</eucode>

  To be used as a flag for no [[:routine_id]] supplied.


@[:types:t_integer32|]
==== t_integer32
<eucode>
include std/types.e
namespace types
public type t_integer32(object o)
</eucode>

  tests for Euphoria integer.

===== Returns:
TRUE if the argument is a valid 31-bit Euphoria integer.

===== Comments:
This function is the same as ##integer(o)## on 32-bit Euphoria,
but is portable to 64-bit architectures.



!!CONTEXT:../include/std/utils.e
!!namespace:utils
%%output = std_utils

== Utilities

<<LEVELTOC level=2 depth=4>>


=== Routines


@[:utils:iif|]
==== iif
<eucode>
include std/utils.e
namespace utils
public function iif(atom test, object ifTrue, object ifFalse)
</eucode>

  Used to embed an 'if' test inside an expression. ##iif## stands for inline if or
immediate if.

===== Parameters:
# ##test## : an atom, the result of a boolean expression
# ##ifTrue## : an object, returned if ##test## is **non-zero **
# ##ifFalse## : an object, returned if ##test## is zero

===== Returns:
An object. Either ##ifTrue## or ##ifFalse## is returned depending on
the value of ##test##.

Warning Note:\\
You must take care when using this function because just like all other
Euphoria routines, this does not do any //lazy evaluation//.
All parameter expressions are evaluated **before**
the function is called, thus, it cannot be used when one of the
parameters could fail to evaluate correctly. For example, this is
an **improper** use of the ##iif## statement~:
<eucode>
  first = iif(sequence(var), var[1], var)
</eucode>
The reason for this is that both ##var[1]## and ##var## will be evaluated.
Therefore if ##var## happens to be an atom, the ##var[1]## statement will fail.
\\In situations like this, it is better to use the //long// style.
<eucode>
  if sequence(var) then
     first = var[1]
  else
     first = var
  end if
</eucode>

===== Example 1:
<eucode>
msg = sprintf("%s: %s", {
    iif(ErrType = 'E', "Fatal error", "Warning"), 
    errortext 
})
</eucode>



!!CONTEXT:../include/std/convert.e
!!namespace:convert
%%output = std_convert

== Data Type Conversion

<<LEVELTOC level=2 depth=4>>



=== Routines


@[:convert:int_to_bytes|]
==== int_to_bytes
<eucode>
include std/convert.e
namespace convert
public function int_to_bytes(atom x, integer size = 4)
</eucode>

  converts an atom that represents an integer to a sequence of 4 bytes.

===== Parameters:
# ##x## : an atom, the value to convert.

===== Returns:
A **sequence**, of 4 bytes, lowest significant byte first.

===== Comments:
If the atom does not fit into a 32-bit integer, things may still work right:
* If there is a fractional part, the first element in the returned value
will carry it. If you poke the sequence to RAM, that fraction will be discarded anyway.
* If ##x## is simply too big, the first three bytes will still be correct, and the 4th
element will be  ##floor(x/power(2,24))##. If this is not a byte sized integer, some
truncation may occur, but usually no error.

The integer can be negative. Negative byte-values will be returned, but
after poking them into memory you will have the correct (two's complement)
representation for the 386+.

===== Example 1:
<eucode>
s = int_to_bytes(999)
-- s is {231, 3, 0, 0}
</eucode>

===== Example 2:

<eucode>
s = int_to_bytes(-999)
-- s is {-231, -4, -1, -1}
</eucode>

===== See Also:
[[:bytes_to_int]], [[:int_to_bits]], [[:atom_to_float64]], [[:poke4]]


@[:convert:bytes_to_int|]
==== bytes_to_int
<eucode>
include std/convert.e
namespace convert
public function bytes_to_int(sequence s)
</eucode>

  converts a sequence of at most 4 bytes into an atom.

===== Parameters:
# ##s## : the sequence to convert
===== Returns:
An **atom**, the value of the concatenated bytes of ##s##.

===== Comments:

This performs the reverse operation from [[:int_to_bytes]]

An atom is being returned, because the converted value may be bigger
than what can fit in an Euphoria integer.

===== Example 1:
<eucode>
atom int32

int32 = bytes_to_int({37,1,0,0})
-- int32 is 37 + 256*1 = 293
</eucode>

===== See Also:
[[:bits_to_int]], [[:float64_to_atom]], [[:int_to_bytes]], [[:peek]],
[[:peek4s]], [[:peek4u]], [[:poke4]]


@[:convert:int_to_bits|]
==== int_to_bits
<eucode>
include std/convert.e
namespace convert
public function int_to_bits(atom x, integer nbits = 32)
</eucode>

  extracts the lower bits from an integer.

===== Parameters:
# ##x## : the atom to convert
# ##nbits## : the number of bits requested. The default is 32.

===== Returns:
A **sequence**, of length ##nbits##, made of 1's and 0's.

===== Comments:
##x## should have no fractional part. If it does, then the first "bit"
will be an atom between 0 and 2.

The bits are returned lowest first.

For negative numbers the two's complement bit pattern is returned.

You can use operators like subscripting/slicing/and/or/xor/not on entire sequences
to manipulate sequences of bits. Shifting of bits and rotating of bits are
easy to perform.

===== Example 1:
<eucode>
s = int_to_bits(177, 8)
-- s is {1,0,0,0,1,1,0,1} -- "reverse" order
</eucode>

===== See Also:
[[:bits_to_int]], [[:int_to_bytes]], [[:Relational operators]],
[[:operations on sequences]]


@[:convert:bits_to_int|]
==== bits_to_int
<eucode>
include std/convert.e
namespace convert
public function bits_to_int(sequence bits)
</eucode>

  converts a sequence of bits to an atom that has no fractional part.

===== Parameters:
# ##bits## : the sequence to convert.

===== Returns:
A positive **atom**, whose machine representation was given by ##bits##.

===== Comments:
An element in ##bits## can be any atom. If nonzero, it counts for 1, else
for 0.

The first elements in ##bits## represent the bits with the least weight in
the returned value. Only the 52 last bits will matter, as the PC hardware
cannot hold an integer with more digits than this.

If you print s the bits will appear in "reverse" order, but it is
convenient to have increasing subscripts access bits of increasing
significance.

===== Example 1:
<eucode>
a = bits_to_int({1,1,1,0,1})
-- a is 23 (binary 10111)
</eucode>

===== See Also:
[[:bytes_to_int]], [[:int_to_bits]], [[:operations on sequences]]


@[:convert:atom_to_float64|]
==== atom_to_float64
<eucode>
include std/convert.e
namespace convert
public function atom_to_float64(atom a)
</eucode>

  converts an atom to a sequence of 8 bytes in IEEE 64-bit format.

===== Parameters:
# ##a## : the atom to convert:

===== Returns:
A **sequence**, of 8 bytes, which can be poked in memory to represent ##a##.

===== Comments:
All Euphoria atoms have values which can be represented as 64-bit IEEE
floating-point numbers, so you can convert any atom to 64-bit format
without losing any precision.

Integer values will also be converted to 64-bit floating-point format.

===== Example 1:
<eucode>
fn = open("numbers.dat", "wb")
puts(fn, atom_to_float64(157.82)) -- write 8 bytes to a file
</eucode>

===== See Also:
[[:float64_to_atom]], [[:int_to_bytes]], [[:atom_to_float32]]


@[:convert:atom_to_float80|]
==== atom_to_float80
<eucode>
include std/convert.e
namespace convert
public function atom_to_float80(atom a)
</eucode>

  


@[:convert:float80_to_atom|]
==== float80_to_atom
<eucode>
include std/convert.e
namespace convert
public function float80_to_atom(sequence bytes)
</eucode>

  


@[:convert:atom_to_float32|]
==== atom_to_float32
<eucode>
include std/convert.e
namespace convert
public function atom_to_float32(atom a)
</eucode>

  converts an atom to a sequence of 4 bytes in IEEE 32-bit format.

===== Parameters:
# ##a## : the atom to convert:

===== Returns:
A **sequence**, of 4 bytes, which can be poked in memory to represent ##a##.

===== Comments:

Euphoria atoms can have values which are 64-bit IEEE floating-point
numbers, so you may lose precision when you convert to 32-bits
(16 significant digits versus 7). The range of exponents is much larger
in 64-bit format (10 to the 308, versus 10 to the 38), so some atoms may
be too large or too small to represent in 32-bit format. In this case you
will get one of the special 32-bit values: ##inf## or ##-inf## (infinity or
-infinity). To avoid this, you can use [[:atom_to_float64]].

Integer values will also be converted to 32-bit floating-point format.

On modern computers, computations on 64 bit floats are no slower than
on 32 bit floats. Internally, the PC stores them in 80 bit registers
anyway. Euphoria does not support these so called long doubles. Not all C compilers do.

===== Example 1:
<eucode>
fn = open("numbers.dat", "wb")
puts(fn, atom_to_float32(157.82)) -- write 4 bytes to a file
</eucode>

===== See Also:
[[:float32_to_atom]], [[:int_to_bytes]], [[:atom_to_float64]]


@[:convert:float64_to_atom|]
==== float64_to_atom
<eucode>
include std/convert.e
namespace convert
public function float64_to_atom(sequence_8 ieee64)
</eucode>

  converts a sequence of 8 bytes in IEEE 64-bit format to an atom.

===== Parameters:
# ##ieee64## : the sequence to convert.

===== Returns:
An **atom**, the same value as the FPU would see by peeking
##ieee64## from RAM.

===== Comments:
Any 64-bit IEEE floating-point number can be converted to an atom.

===== Example 1:
<eucode>
f = repeat(0, 8)
fn = open("numbers.dat", "rb")  -- read binary
for i = 1 to 8 do
    f[i] = getc(fn)
end for
a = float64_to_atom(f)
</eucode>

===== See Also:
[[:float32_to_atom]], [[:bytes_to_int]], [[:atom_to_float64]]


@[:convert:float32_to_atom|]
==== float32_to_atom
<eucode>
include std/convert.e
namespace convert
public function float32_to_atom(sequence_4 ieee32)
</eucode>

  converts a sequence of 4 bytes in IEEE 32-bit format to an atom.

===== Parameters:
# ##ieee32## : the sequence to convert.

===== Returns:
An **atom**, the same value as the FPU would see by peeking
##ieee64## from RAM.

===== Comments:
Any 32-bit IEEE floating-point number can be converted to an atom.

===== Example 1:
<eucode>
f = repeat(0, 4)
fn = open("numbers.dat", "rb") -- read binary
f[1] = getc(fn)
f[2] = getc(fn)
f[3] = getc(fn)
f[4] = getc(fn)
a = float32_to_atom(f)
</eucode>

===== See Also:
[[:float64_to_atom]], [[:bytes_to_int]], [[:atom_to_float32]]


@[:convert:hex_text|]
==== hex_text
<eucode>
include std/convert.e
namespace convert
public function hex_text(sequence text)
</eucode>

  converts a text representation of a hexadecimal number to an atom.

===== Parameters:
# ##text## : the text to convert.

===== Returns:
An **atom**, the numeric equivalent to ##text##

===== Comments:
* The text can optionally begin with ##'#'## which is ignored.
* The text can have any number of underscores, all of which are ignored.
* The text can have one leading ##'-'##, indicating a negative number.
* The text can have any number of underscores, all of which are ignored.
* Any other characters in the text stops the parsing and returns the value thus far.

===== Example 1:
<eucode>
 atom h = hex_text("-#3_4FA.00E_1BD")
 -- h is now -13562.003444492816925
 atom h = hex_text("DEADBEEF")
 -- h is now 3735928559
</eucode>

===== See Also:
[[:value]]


@[:convert:set_decimal_mark|]
==== set_decimal_mark
<eucode>
include std/convert.e
namespace convert
public function set_decimal_mark(integer new_mark)
</eucode>

  gets, and possibly sets, the decimal mark that [[:to_number]] uses.

===== Parameters:
# ##new_mark## : An integer: Either a comma (,), a period (.) or any other integer.

===== Returns:
An **integer**, The current value, before ##new_mark## changes it.

===== Comments:
* When ##new_mark## is a //period// it will cause ##to_number## to interpret a dot ##(.)##
as the decimal point symbol. The pre-changed value is returned.
* When ##new_mark## is a //comma// it will cause ##to_number## to interpret a comma ##(,)##
as the decimal point symbol. The pre-changed value is returned.
* Any other value does not change the current setting. Instead it just returns the current value.
* The initial value of the decimal marker is a period.


@[:convert:to_number|]
==== to_number
<eucode>
include std/convert.e
namespace convert
public function to_number(sequence text_in, integer return_bad_pos = 0)
</eucode>

  converts the text into a number.

===== Parameters:
# ##text_in## : A string containing the text representation of a number.
# ##return_bad_pos## : An integer.
** If 0 (the default) then this will return
a number based on the supplied text and it will **not** return
any position in ##text_in## that caused an incomplete conversion.
** If ##return_bad_pos## is -1 then if the conversion of ##text_in## was
complete the resulting number is returned otherwise a single-element
sequence containing the position within ##text_in## where the conversion
stopped.
** If not 0 then this returns both the converted value up to the point of failure (if any) and the
position in ##text_in## that caused the failure. If that position is 0 then
there was no failure.

===== Returns:
* an **atom**, If ##return_bad_pos## is zero, the number represented by ##text_in##.
If ##text_in## contains invalid characters, zero is returned.\\
* a **sequence**, If ##return_bad_pos## is non-zero. If ##return_bad_pos## is -1
it returns a 1-element sequence containing the spot inside ##text_in## where
conversion stopped. Otherwise it returns a 2-element sequence
containing the number represented by ##text_in## and either 0 or the position in
##text_in## where conversion stopped.

===== Comments:
# You can supply **Hexadecimal** values if the value is preceded by
a '#' character, **Octal** values if the value is preceded by a '@' character,
and **Binary** values if the value is preceded by a '!' character. With
hexadecimal values, the case of the digits 'A' - 'F' is not important. Also,
any decimal marker embedded in the number is used with the correct base.
# Any underscore characters or thousands separators, that are embedded in the text
number are ignored. These can be used to help visual clarity for long numbers. The thousands
separator is a ',' when the decimal mark is '.' (the default), or '.' if the
decimal mark is ','. You inspect and set it using [[:set_decimal_mark]]().
# You can supply a single leading or trailing sign. Either a minus (-) or plus (+).
# You can supply one or more trailing adjacent percentage signs. The first one
causes the resulting value to be divided by 100, and each subsequent one divides
the result by a further 10. Thus ##3845%## gives a value of ##(3845 / 100) ==> 38.45##,
and ##3845%%## gives a value of ##(3845 / 1000) ==> 3.845##.
# You can have single currency symbol before the first digit or after the last
digit. A currency symbol is any character of the string: "$".
# You can have any number of whitespace characters before the first digit and
after the last digit.
# The currency, sign and base symbols can appear in any order. Thus ##"$ -21.10"## is
the same as ##" -$21.10 "##, which is also the same as ##"21.10$-"##, and so on.
# This function can optionally return information about invalid numbers. If ##return_bad_pos##
is not zero, a two-element sequence is returned. The first element is the converted
number value , and the second is the position in the text where conversion stopped.
If no errors were found then the second element is zero.
# When converting floating point text numbers to atoms, you need to be aware that
many numbers cannot be accurately converted to the exact value expected due to the
limitations of the 64-bit IEEEE Floating point format.

===== Example 1:
<eucode>
object val
val = to_number("12.34")      ---> 12.34 -- No errors and no error return needed.
val = to_number("12.34", 1)   ---> {12.34, 0} -- No errors.
val = to_number("12.34", -1)  ---> 12.34 -- No errors.
val = to_number("12.34a", 1)  ---> {12.34, 6} -- Error at position 6
val = to_number("12.34a", -1) ---> {6} -- Error at position 6
val = to_number("12.34a")     ---> 0 because its not a valid number

val = to_number("#f80c")        --> 63500
val = to_number("#f80c.7aa")    --> 63500.47900390625
val = to_number("@1703")        --> 963
val = to_number("!101101")      --> 45
val = to_number("12_583_891")   --> 12583891
val = to_number("12_583_891%")  --> 125838.91
val = to_number("12,583,891%%") --> 12583.891
</eucode>


@[:convert:to_integer|]
==== to_integer
<eucode>
include std/convert.e
namespace convert
public function to_integer(object data_in, integer def_value = 0)
</eucode>

  converts an object into a integer.

===== Parameters:
# ##data_in## : Any Euphoria object.
# ##def_value## : An integer. This is returned if ##data_in## cannot be converted
into an integer. If omitted, zero is returned.

===== Returns:
An **integer**, either the integer rendition of ##data_in## or ##def_value## if it has
no integer value.

===== Comments:
The returned value is guaranteed to be a valid Euphoria integer.

===== Example 1:
<eucode>
? to_integer(12)            --> 12
? to_integer(12.4)          --> 12
? to_integer("12")          --> 12
? to_integer("12.9")        --> 12

? to_integer("a12")         --> 0 (not a valid number)
? to_integer("a12",-1)      --> -1 (not a valid number)
? to_integer({"12"})        --> 0 (sub-sequence found)
? to_integer(#3FFFFFFF)     --> 1073741823
? to_integer(#3FFFFFFF + 1) --> 0 (too big for a Euphoria integer)
</eucode>


@[:convert:to_string|]
==== to_string
<eucode>
include std/convert.e
namespace convert
public function to_string(object data_in, integer string_quote = 0,
        integer embed_string_quote = '"')
</eucode>

  converts an object into a text string.

===== Parameters:
# ##data_in## : Any Euphoria object.
# ##string_quote## : An integer. If not zero (the default) this will be used to
enclose ##data_in##, if it is already a string.
# ##embed_string_quote## : An integer. This will be used to
enclose any strings embedded inside ##data_in##. The default is '"'

===== Returns:
A **sequence**. This is the string repesentation of ##data_in##.

===== Comments:
* The returned value is guaranteed to be a displayable text string.
* ##string_quote## is only used if ##data_in## is already a string. In this case,
all occurances of ##string_quote## already in ##data_in## are prefixed with
the '\' escape character, as are any preexisting escape characters. Then
##string_quote## is added to both ends of ##data_in##, resulting in a quoted
string.
* ##embed_string_quote## is only used if ##data_in## is a sequence that contains
strings. In this case, it is used as the enclosing quote for embedded strings.

===== Example 1:
<eucode>
include std/console.e
display(to_string(12))           --> 12
display(to_string("abc"))        --> abc
display(to_string("abc",'"'))    --> "abc"
display(to_string(`abc\"`,'"'))  --> "abc\\\""
display(to_string({12,"abc",{4.5, -99}}))    --> {12, "abc", {4.5, -99}}
display(to_string({12,"abc",{4.5, -99}},,0)) --> {12, abc, {4.5, -99}}
</eucode>



!!CONTEXT:../include/std/get.e
!!namespace:stdget
%%output = std_get

== Input Routines

<<LEVELTOC level=2 depth=4>>




=== Error Status Constants
These are returned from [[:get]] and [[:value]].


@[:stdget:GET_SUCCESS|]
==== GET_SUCCESS
<eucode>
include std/get.e
namespace stdget
public constant GET_SUCCESS
</eucode>





@[:stdget:GET_EOF|]
==== GET_EOF
<eucode>
include std/get.e
namespace stdget
public constant GET_EOF
</eucode>





@[:stdget:GET_FAIL|]
==== GET_FAIL
<eucode>
include std/get.e
namespace stdget
public constant GET_FAIL
</eucode>





@[:stdget:GET_NOTHING|]
==== GET_NOTHING
<eucode>
include std/get.e
namespace stdget
public constant GET_NOTHING
</eucode>





=== Answer Types


@[:stdget:GET_SHORT_ANSWER|]
==== GET_SHORT_ANSWER
<eucode>
include std/get.e
namespace stdget
public constant GET_SHORT_ANSWER
</eucode>





@[:stdget:GET_LONG_ANSWER|]
==== GET_LONG_ANSWER
<eucode>
include std/get.e
namespace stdget
public constant GET_LONG_ANSWER
</eucode>





=== Routines



@[:stdget:get|]
==== get
<eucode>
include std/get.e
namespace stdget
public function get(integer file, integer offset = 0, integer answer = GET_SHORT_ANSWER)
</eucode>

  reads from an open file a human-readable string of characters representing a Euphoria object.
Converts the string into the numeric value of that object.

===== Parameters:
# ##file## : an integer, the handle to an open file from which to read
# ##offset## : an integer, an offset to apply to file position before reading. Defaults to 0.
# ##answer## : an integer, either ##GET_SHORT_ANSWER## (the default) or ##GET_LONG_ANSWER##.

===== Returns:
A **sequence**, of length two (##GET_SHORT_ANSWER##) or four (##GET_LONG_ANSWER##) consisting of:

* an integer, the return status. This is any of:
** ##GET_SUCCESS## ~-- object was read successfully
** ##GET_EOF## ~--     end of file before object was read completely
** ##GET_FAIL## ~--    object is not syntactically correct
** ##GET_NOTHING## ~-- nothing was read, even a partial object string, before end of input
* an object, the value that was read. This is valid only if return status is ##GET_SUCCESS##.
* an integer, the number of characters read. On an error, this is the point at which the
error was detected.
* an integer, the amount of initial whitespace read before the first active character was found

===== Comments:
When ##answer## is not specified, or explicitly ##GET_SHORT_ANSWER##, only the first two
elements in the returned sequence are actually returned.

The ##GET_NOTHING## return status will not be returned if ##answer## is ##GET_SHORT_ANSWER##.

##get## can read arbitrarily complicated Euphoria objects. You
could have a long sequence of values in braces and separated by
commas and comments. For example: ##{23, {49, 57}, 0.5, -1, 99, 'A', "john"}##.
A single call to ##get## will read in this entire sequence,  return its value as a result, and
return complementary information.

If a nonzero offset is supplied, it is interpreted as an offset to the current file
position; the file will start ##seek## from there first.

##get## returns a two or four element sequence; similar to what ##[[:value]]## returns:

* a status code ( success, error, end of file, no value at all )
* the value just read (meaningful only when the status code is ##GET_SUCCESS##)
(optionally)
* the total number of characters read
* the amount of initial whitespace read.

Using the default value for answer, or setting it to ##GET_SHORT_ANSWER##, returns two elements.
Setting it to ##GET_LONG_ANSWER## causes four elements to be returned.

Each call to ##get## picks up where the previous call left off. For instance: a series of five
calls to ##get## would be needed to read in this sequence: ## `99 5.2 {1, 2, 3} "Hello" -1`##
On the sixth and any subsequent call to ##get## you would see a ##GET_EOF## status.

If you had something like ## {1, 2, xxx} ## in the input stream you would see a
##GET_FAIL## error status because ##xxx## is not a Euphoria
object.

After seeing ##-- something\nBut no value ## and the input stream stops right there, you
will receive a status code of ##GET_NOTHING##,
because nothing but whitespace or comments was read. If you had opted for a short answer,
you would get ##GET_EOF## instead.

Multiple "top-level" objects in the input stream must be
separated from each other with one or more "whitespace"
characters (blank, tab, \r, or \n). At the very least, a top
level number must be followed by a white space from the following object.
Whitespace is not necessary //within// a top-level object. Comments, terminated by either
'\n' or '\r', are allowed anywhere inside sequences, and ignored if at the top level.
A call to ##get## will read one entire top-level object, plus possibly one additional
(whitespace) character, after a top level number, even though the next object may have an
identifiable starting point.

The combination of ##[[:print]]## and ##get## can be used to save a
Euphoria object to disk and later read it back. This technique
could be used to implement a database as one or more large
Euphoria sequences stored in disk files. The sequences could be
read into memory, updated and then written back to disk after
each series of transactions is complete. Remember to write out
a whitespace character (using ##[[:puts]]##) after each call to ##[[:print]]##,
at least when a top level number was just printed.

The value returned is not meaningful unless you have a ##GET_SUCCESS## status.

===== Example 1:
<eucode>
-- If he types 77.5, get(0) would return:
{GET_SUCCESS, 77.5}

-- whereas gets(0) would return:
"77.5\n"
</eucode>

===== Example 2:
See ##.../euphoria/demo/mydata.ex##

===== See Also:
[[:value]]


@[:stdget:value|]
==== value
<eucode>
include std/get.e
namespace stdget
public function value(sequence st, integer start_point = 1, integer answer = GET_SHORT_ANSWER)
</eucode>

  reads, from a string, a human-readable string of characters representing a Euphoria object.
Converts the string into the numeric value of that object.

===== Parameters:
# ##st## : a sequence, from which to read text
# ##offset## : an integer, the position at which to start reading. Defaults to 1.
# ##answer## : an integer, either ##GET_SHORT_ANSWER## (the default) or ##GET_LONG_ANSWER##.

===== Returns:
A **sequence**, of length two (##GET_SHORT_ANSWER##) or four (##GET_LONG_ANSWER##) made of:

* an integer, the return status. This is any of
** ##GET_SUCCESS## ~-- object was read successfully
** ##GET_EOF## ~--     end of file before object was read completely
** ##GET_FAIL## ~--    object is not syntactically correct
** ##GET_NOTHING## ~-- nothing was read, even a partial object string, before end of input
* an object, the value that was read. This is valid only if return status is ##GET_SUCCESS##.
* an integer, the number of characters read. On an error, this is the point at which the
error was detected.
* an integer, the amount of initial whitespace read before the first active character was found

===== Comments:
When ##answer## is not specified, or explicitly ##GET_SHORT_ANSWER##, only the first two
elements in the returned sequence are actually returned.

This works the same as [[:get]] but it reads from a string that you supply, rather than
from a file or device.

After reading one valid representation of a Euphoria object ##value## will stop reading
and ignore any additional characters in the string. For example: ##"36"## and ##"36P"## will
both give you ##{GET_SUCCESS, 36}##.

The function returns ##{return_status, value}## if the answer type is not passed or set to
##GET_SHORT_ANSWER##. If set to ##GET_LONG_ANSWER##, the number of characters read and the
amount of leading whitespace are returned in 3rd and 4th position. The ##GET_NOTHING## return
status can occur only on a long answer.

===== Example 1:
<eucode>
s = value("12345"}
s is {GET_SUCCESS, 12345}
</eucode>

===== Example 2:
<eucode>
s = value("{0, 1, -99.9}")
-- s is {GET_SUCCESS, {0, 1, -99.9}}
</eucode>

===== Example 3:
<eucode>
s = value("+++")
-- s is {GET_FAIL, 0}
</eucode>

===== See Also:
[[:get]]


@[:stdget:defaulted_value|]
==== defaulted_value
<eucode>
include std/get.e
namespace stdget
public function defaulted_value(object st, object def, integer start_point = 1)
</eucode>

  calls the ##value## function and returns the resulting value on success or
the default default on failure.

===== Parameters:
# ##st## : object to retrieve value from.
# ##def## : the value returned if ##st## is an atom or ##value(st)## fails.
# ##start_point## : an integer, the position in ##st## at which to start
getting the value from. Defaults to 1

===== Returns:
* If ##st##, is an atom then ##def## is returned.
* If calling ##value(st)## is a success. then ##value()[2]##, otherwise it will return
the parameter ##def##.

===== Example 1:
<eucode>
object i = defaulted_value("10", 0)
-- i is 10

i = defaulted_value("abc", 39)
-- i is 39

i = defaulted_value(12, 42)
-- i is 42

i = defaulted_value("{1,2}", 42)
-- i is {1,2}
</eucode>

===== See Also:
[[:value]]




!!CONTEXT:../include/std/search.e
!!namespace:search
%%output = std_search

== Searching

<<LEVELTOC level=2 depth=4>>


=== Equality



@[:eu:compare|]
==== compare
<eucode>
<built-in> function compare(object compared, object reference)
</eucode>

compares two items returning less than, equal or greater than.

===== Parameters:
# ##compared## : the compared object
# ##reference## : the reference object

===== Returns:
An **integer**,
*  0 ~-- if objects are identical
*  1 ~-- if ##compared## is greater than ##reference##
* -1 ~-- if ##compared## is less than ##reference##

===== Comments:
Atoms are considered to be less than sequences. Sequences are compared alphabetically
starting with the first element until a difference is found or one of the sequences is exhausted. Atoms are compared as ordinary reals.

===== Example 1:
<eucode>
x = compare({1,2,{3,{4}},5}, {2-1,1+1,{3,{4}},6-1})
-- identical, x is 0
</eucode>

===== Example 2:
<eucode>
if compare("ABC", "ABCD") < 0 then   -- -1
    -- will be true: ABC is "less" because it is shorter
end if
</eucode>

===== Example 3:
<eucode>
x = compare('a', "a")
-- x will be -1 because 'a' is an atom
-- while "a" is a sequence
</eucode>

===== See Also:
[[:equal]], [[:relational operators]], [[:operations on sequences]], [[:sort]]


@[:eu:equal|]
==== equal
<eucode>
<built-in> function equal(object left, object right)
</eucode>

compares two Euphoria objects to see if they are the same.

===== Parameters:
# ##left## : one of the objects to test
# ##right## : the other object

===== Returns:
An **integer**, 1 if the two objects are identical, else 0.

===== Comments:
This is equivalent to the expression: ##compare(left, right) = 0##.

This routine, like most other built-in routines, is very fast. It does not have any
subroutine call overhead.

===== Example 1:
<eucode>
if equal(PI, 3.14) then
    puts(1, "give me a better value for PI!\n")
end if
</eucode>

===== Example 2:
<eucode>
if equal(name, "George") or equal(name, "GEORGE") then
   puts(1, "name is George\n")
end if
</eucode>

===== See Also:
[[:compare]]


=== Finding



@[:eu:find|]
==== find
<eucode>
<built-in> function find(object needle, sequence haystack, integer start)
</eucode>

finds the first occurrence of a "needle" as an element of a "haystack", starting from position "start".

===== Parameters:
# ##needle## : an object whose presence is being queried
# ##haystack## : a sequence, which is being looked up for ##needle##
# ##start## : an integer, the position at which to start searching. Defaults to 1.

===== Returns:
An **integer**, 0 if ##needle## is not on ##haystack##, else the smallest index of an
element of ##haystack## that equals ##needle##.

===== Example 1:
<eucode>
location = find(11, {5, 8, 11, 2, 3})
-- location is set to 3
</eucode>

===== Example 2:
<eucode>
names = {"fred", "rob", "george", "mary", ""}
location = find("mary", names)
-- location is set to 4
</eucode>

===== See Also:
[[:find]], [[:match]], [[:compare]]


@[:eu:find_from|]
==== find_from
<eucode>
<built-in> function find_from(object needle, object haystack, integer start)
</eucode>

===== Deprecated:
Deprecated since version 4.0.0

In Euphoria 4.0.0 we have the ability to default parameters to procedures and functions.
The built-in [[:find]] therefore now has a ##start## parameter that is defaulted to the
beginning of the sequence. Thus, [[:find]] can perform the identical functionality
provided by ##find_from##. In an undetermined future release of Euphoria, ##find_from##
will be removed.



@[:search:find_any|]
==== find_any
<eucode>
include std/search.e
namespace search
public function find_any(object needles, sequence haystack, integer start = 1)
</eucode>

  finds any element from a list inside a sequence. Returns the location of the first hit.

===== Parameters:
# ##needles## : a sequence, the list of items to look for
# ##haystack## : a sequence, in which "needles" are looked for
# ##start## : an integer, the starting point of the search. Defaults to 1.

===== Returns:
An **integer**, the smallest index in ##haystack## of an element of ##needles##, or 0 if no needle is found.

===== Comments:
This function may be applied to a string sequence or a complex
sequence.

===== Example 1:
<eucode>
location = find_any("aeiou", "John Smith", 3)
-- location is 8
</eucode>

===== Example 2:
<eucode>
location = find_any("aeiou", "John Doe")
-- location is 2
</eucode>

===== See Also:
[[:find]]


@[:search:match_any|]
==== match_any
<eucode>
include std/search.e
namespace search
public function match_any(sequence needles, sequence haystack, integer start = 1)
</eucode>

  determines if any element from ##needles## is in ##haystack##.

===== Parameters:
# ##needles## : a sequence, the list of items to look for
# ##haystack## : a sequence, in which "needles" are looked for
# ##start## : an integer, the starting point of the search. Defaults to 1.

===== Returns:
An **integer**, 0 if no matches, 1 if any matches.

===== Comments:
This function may be applied to a string sequence or a complex
sequence.
An empty needles sequence will always result in 0.

===== Example 1:
<eucode>
ok = match_any("aeiou", "John Smith")
-- okay is 1
ok = match_any("xyz", "John Smith" )
-- okay is 0
</eucode>

===== See Also:
[[:find_any]]


@[:search:find_each|]
==== find_each
<eucode>
include std/search.e
namespace search
public function find_each(sequence needles, sequence haystack, integer start = 1)
</eucode>

  finds all instances of any element from the needle sequence that occur in the
haystack sequence. Returns a list of indexes.

===== Parameters:
# ##needles## : a sequence, the list of items to look for
# ##haystack## : a sequence, in which "needles" are looked for
# ##start## : an integer, the starting point of the search. Defaults to 1.

===== Returns:
A **sequence**, the list of indexes into ##haystack## that point to an
element that is also in ##needles##.

===== Comments:
This function may be applied to a string sequence or a complex
sequence.

===== Example 1:
<eucode>
location = find_each("aeiou", "John Smith", 3)
-- location is {8}
</eucode>

===== Example 2:
<eucode>
location = find_each("aeiou", "John Doe")
-- location is {2,7,8}
</eucode>

===== See Also:
[[:find]], [[:find_any]]


@[:search:find_all|]
==== find_all
<eucode>
include std/search.e
namespace search
public function find_all(object needle, sequence haystack, integer start = 1)
</eucode>

  finds all occurrences of an object inside a sequence, starting at some specified point.

===== Parameters:
# ##needle## : an object, what to look for
# ##haystack## : a sequence to search in
# ##start## : an integer, the starting index position (defaults to 1)

===== Returns:
A **sequence**, the list of all indexes no less than ##start## of elements of ##haystack## that equal ##needle##. This sequence is empty if no match found.

===== Example 1:
<eucode>
s = find_all('A', "ABCABAB")
-- s is {1,4,6}
</eucode>

===== See Also:
[[:find]], [[:match]], [[:match_all]]


@[:search:find_all_but|]
==== find_all_but
<eucode>
include std/search.e
namespace search
public function find_all_but(object needle, sequence haystack, integer start = 1)
</eucode>

  finds all non-occurrences of an object inside a sequence, starting at some specified point.

===== Parameters:
# ##needle## : an object, what to look for
# ##haystack## : a sequence to search in
# ##start## : an integer, the starting index position (defaults to 1)

===== Returns:
A **sequence**, the list of all indexes no less than ##start## of elements
of ##haystack## that not equal to ##needle##. This sequence is empty if
##haystack## only consists of ##needle##.

===== Example 1:
<eucode>
s = find_all_but('A', "ABCABAB")
-- s is {2,3,5,7}
</eucode>

===== See Also:
[[:find_all]], [[:match]], [[:match_all]]


@[:search:NESTED_ANY|]
==== NESTED_ANY
<eucode>
include std/search.e
namespace search
public constant NESTED_ANY
</eucode>





@[:search:NESTED_ALL|]
==== NESTED_ALL
<eucode>
include std/search.e
namespace search
public constant NESTED_ALL
</eucode>





@[:search:NESTED_INDEX|]
==== NESTED_INDEX
<eucode>
include std/search.e
namespace search
public constant NESTED_INDEX
</eucode>





@[:search:NESTED_BACKWARD|]
==== NESTED_BACKWARD
<eucode>
include std/search.e
namespace search
public constant NESTED_BACKWARD
</eucode>





@[:search:find_nested|]
==== find_nested
<eucode>
include std/search.e
namespace search
public function find_nested(object needle, sequence haystack, integer flags = 0,
        integer rtn_id = types :NO_ROUTINE_ID)
</eucode>

  finds any object (among a list) in a sequence of arbitrary shape at arbitrary nesting.

===== Parameters:
# ##needle## : an object, either what to look up, or a list of items to look up
# ##haystack## : a sequence, where to look up
# ##flags## : options to the function, see Comments section.  Defaults to 0.
# ##routine## : an integer, the routine_id of an user supplied equal/find function. Defaults to  [[:types:NO_ROUTINE_ID]].

===== Returns:
A possibly empty **sequence**, of results, one for each hit.

===== Comments:
Each item in the returned sequence is either a sequence of indexes, or a pair {sequence of indexes, index in ##needle##}.

The following flags are available to fine tune the search~:
* ##NESTED_BACKWARD## ~--  if on ##flags##, search is performed backward. Default is forward.
* ##NESTED_ALL## ~-- if on ##flags##, all occurrences are looked for. Default is one hit only.
* ##NESTED_ANY## ~-- if present on ##flags##, ##needle## is a list of items to look for. Not the default.
* ##NESTED_INDEXES## ~-- if present on ##flags##, an individual result is a pair {position, index
in ##needle##}. Default is just return the position.

If ##s## is a single index list, or position, from the returned sequence, then ##fetch(haystack, s) = needle##.

If a routine id is supplied, the routine must behave like [[:equal]] if the ##NESTED_ANY##
flag is not supplied, and like [[:find]] if it is. The routine is being passed the current
##haystack## item and ##needle##. The returned integer is interpreted as if returned by
[[:equal]] or [[:find]].

If the ##NESTED_ANY## flag is specified, and ##needle## is an atom, then the flag is removed.

===== Example 1:
<eucode>
sequence s = find_nested(3, {5, {4, {3, {2}}}})
-- s is {2 ,2 ,1}
</eucode>

===== Example 2:
<eucode>
sequence s = find_nested({3, 2}, {1, 3, {2,3}}, 
                                   NESTED_ANY + NESTED_BACKWARD + NESTED_ALL)
-- s is {{3,2}, {3,1}, {2}}
</eucode>

===== Example 3:
<eucode>
sequence s = find_nested({3, 2}, {1, 3, {2,3}}, 
                                    NESTED_ANY + NESTED_INDEXES + NESTED_ALL)
-- s is {{{2}, 1}, {{3, 1}, 2}, {{3, 2}, 1}}
</eucode>

===== See Also:
[[:find]], [[:rfind]], [[:find_any]], [[:fetch]]


@[:search:rfind|]
==== rfind
<eucode>
include std/search.e
namespace search
public function rfind(object needle, sequence haystack, integer start = length(haystack))
</eucode>

  finds a needle in a haystack in reverse order.

===== Parameters:
# ##needle## : an object to search for
# ##haystack## : a sequence to search in
# ##start## : an integer, the starting index position (defaults to length(##haystack##))

===== Returns:
An **integer**, 0 if no instance of ##needle## can be found on ##haystack## before
index ##start##, or the highest such index otherwise.

===== Comments:

If ##start## is less than 1, it will be added once to length(##haystack##)
to designate a position counted backwards. Thus, if ##start## is -1, the
first element to be queried in ##haystack## will be ##haystack[$-1]##,
then ##haystack[$-2]## and so on.

===== Example 1:
<eucode>
location = rfind(11, {5, 8, 11, 2, 11, 3})
-- location is set to 5
</eucode>

===== Example 2:
<eucode>
names = {"fred", "rob", "rob", "george", "mary"}
location = rfind("rob", names)
-- location is set to 3
location = rfind("rob", names, -4)
-- location is set to 2
</eucode>

===== See Also:
[[:find]], [[:rmatch]]


@[:search:find_replace|]
==== find_replace
<eucode>
include std/search.e
namespace search
public function find_replace(object needle, sequence haystack, object replacement,
        integer max = 0)
</eucode>

  finds a ##needle## in the ##haystack##, and replaces all or upto ##max##
occurrences with ##replacement##.

===== Parameters:

# ##needle## : an object to search and perhaps replace
# ##haystack## : a sequence to be inspected
# ##replacement## : an object to substitute for any (first) instance of ##needle##
# ##max## : an integer, 0 to replace all occurrences

===== Returns:
A **sequence**, the modified ##haystack##.

===== Comments:
Replacements will not be made recursively on the part of ##haystack## that was already changed.

If ##max## is 0 or less, any occurrence of ##needle## in ##haystack## will be replaced by ##replacement##. Otherwise, only the first ##max## occurrences are.

===== Example 1:
<eucode>
s = find_replace('b', "The batty book was all but in Canada.", 'c', 0)
-- s is "The catty cook was all cut in Canada."
</eucode>

===== Example 2:
<eucode>
s = find_replace('/', "/euphoria/demo/unix", '\\', 2)
-- s is "\\euphoria\\demo/unix"
</eucode>

===== Example 3:
<eucode>
s = find_replace("theater", { "the", "theater", "theif" }, "theatre")
-- s is { "the", "theatre", "theif" }
</eucode>

===== See Also:
[[:find]], [[:replace]], [[:match_replace]]


@[:search:match_replace|]
==== match_replace
<eucode>
include std/search.e
namespace search
public function match_replace(object needle, sequence haystack, object replacement,
        integer max = 0)
</eucode>

  finds a "needle" in a "haystack", and replace any, or only the first few, occurrences with a replacement.

===== Parameters:

# ##needle## : an non-empty sequence or atom to search and perhaps replace
# ##haystack## : a sequence to be inspected
# ##replacement## : an object to substitute for any (first) instance of ##needle##
# ##max## : an integer, 0 to replace all occurrences

===== Returns:
A **sequence**, the modified ##haystack##.

===== Comments:
Replacements will not be made recursively on the part of ##haystack## that was already changed.

If ##max## is 0 or less, any occurrence of ##needle## in ##haystack## will be replaced by ##replacement##. Otherwise, only the first ##max## occurrences are.

If either ##needle## or ##replacement## are atoms they will be treated as if you had passed in a
length-1 sequence containing the said atom.

If ##needle## is an empty sequence, an error will be raised and your program will exit.

===== Example 1:
<eucode>
s = match_replace("the", "the cat ate the food under the table", "THE", 0)
-- s is "THE cat ate THE food under THE table"
</eucode>

===== Example 2:
<eucode>
s = match_replace("the", "the cat ate the food under the table", "THE", 2)
-- s is "THE cat ate THE food under the table"
</eucode>

===== Example 3:
<eucode>
s = match_replace('/', "/euphoria/demo/unix", '\\', 2)
-- s is "\\euphoria\\demo/unix"
</eucode>

===== Example 4:
<eucode>
s = match_replace('a', "abracadabra", 'X')
-- s is now "XbrXcXdXbrX"
s = match_replace("ra", "abracadabra", 'X')
-- s is now "abXcadabX"
s = match_replace("a", "abracadabra", "aa")
-- s is now "aabraacaadaabraa"
s = match_replace("a", "abracadabra", "")
-- s is now "brcdbr"
</eucode>

===== See Also:
[[:find]], [[:replace]], [[:regex:find_replace]], [[:find_replace]]


@[:search:binary_search|]
==== binary_search
<eucode>
include std/search.e
namespace search
public function binary_search(object needle, sequence haystack, integer start_point = 1,
        integer end_point = 0)
</eucode>

  finds a "needle" in an ordered "haystack". Start and end point can be given for the search.

===== Parameters:
# ##needle## : an object to look for
# ##haystack## : a sequence to search in
# ##start_point## : an integer, the index at which to start searching. Defaults to 1.
# ##end_point## : an integer, the end point of the search. Defaults to 0, ie search to end.

===== Returns:
An **integer**, either:
# a positive integer ##i##, which means ##haystack[i]## equals ##needle##.
# a negative integer, ##-i##, with ##i## between adjusted start and end
points. This means that ##needle## is not in the searched slice of
##haystack##, but would be at index ##i## if it were there.
# a negative integer ##-i## with ##i## out of the searched range. This
means than ##needle##might be either below the start point if ##i##
is below the start point, or above the end point if ##i## is.

===== Comments:
* If ##end_point## is not greater than zero, it is added to
##length(haystack)## once only. Then, the end point of the search is
adjusted to ##length(haystack)## if out of bounds.
* The start point is adjusted to 1 if below 1.
* The way this function returns is very similar to what [[:db_find_key]]
does. They use variants of the same algorithm. The latter is all the
more efficient as ##haystack## is long.
* ##haystack## is assumed to be in ascending order. Results are undefined
if it is not.
* If duplicate copies of ##needle## exist in the range searched on
##haystack##, any of the possible contiguous indexes may be returned.

===== See Also:
[[:find]], [[:db_find_key]]


=== Matching



@[:eu:match|]
==== match
<eucode>
<built-in> function match(sequence needle, sequence haystack, integer start)
</eucode>

tries to match a "needle" against some slice of a "haystack", starting at position "start".

===== Parameters:
# ##needle## : a sequence whose presence as a "substring" is being queried
# ##haystack## : a sequence, which is being looked up for ##needle## as a sub-sequence
# ##start## : an integer, the point from which matching is attempted. Defaults to 1.

===== Returns:
An **integer**, 0 if no slice of ##haystack## is ##needle##, else the smallest index at which such a slice starts.

===== Comments:
If ##needle## is an empty sequence, an error is raised and your program
will exit.

===== Example 1:
<eucode>
location = match("pho", "Euphoria")
-- location is set to 3
</eucode>

===== See Also:
[[:find]], [[:compare]], [[:wildcard:is_match]]


@[:eu:match_from|]
==== match_from
<eucode>
<built-in> function match_from(sequence needle, sequence haystack, integer start)
</eucode>

===== Deprecated:
Deprecated since version 4.0.0

In Euphoria 4.0.0 we have the ability to default parameters to procedures and functions.
The built-in [[:match]] therefore now has a ##start## parameter that is defaulted to the
beginning of the sequence. Thus, [[:match]] can perform the identical functionality
provided by ##match_from##. In an undetermined future release of Euphoria, ##match_from##
will be removed.

===== Comments:
If ##needle## is an empty sequence, an error is raised and your program
will exit.



@[:search:match_all|]
==== match_all
<eucode>
include std/search.e
namespace search
public function match_all(sequence needle, sequence haystack, integer start = 1)
</eucode>

  matches all items of haystack in needle.

===== Parameters:
# ##needle## : a non-empty sequence, what to look for
# ##haystack## : a sequence to search in
# ##start## : an integer, the starting index position (defaults to 1)

===== Returns:
A **sequence**, of integers, the list of all lower indexes, not less than ##start##, of all slices in ##haystack## that equal ##needle##. The list may be empty.

===== Comments:
If ##needle## is an empty sequence, an error will be raised and your program will exit.

===== Example 1:
<eucode>
s = match_all("the", "the dog chased the cat under the table.")
-- s is {1,16,30}
</eucode>

===== See Also:
[[:match]], [[:regex:find_all]] [[:find]], [[:find_all]]


@[:search:rmatch|]
==== rmatch
<eucode>
include std/search.e
namespace search
public function rmatch(sequence needle, sequence haystack, integer start = length(haystack))
</eucode>

  tries to match a needle against some slice of a haystack in reverse order.

===== Parameters:
# ##needle## : a sequence to search for
# ##haystack## : a sequence to search in
# ##start## : an integer, the starting index position (defaults to length(##haystack##))

===== Returns:
An **integer**, either 0 if no slice of ##haystack## starting before
##start## equals ##needle##, else the highest lower index of such a slice.

===== Comments:
If ##start## is less than 1, it will be added once to ##length(haystack)##
to designate a position counted backwards. Thus, if ##start## is -1, the
first element to be queried in ##haystack## will be ##haystack[$-1]##,
then ##haystack[$-2]## and so on.

If a ##needle## is an empty sequence this will return 0.

===== Example 1:
<eucode>
location = rmatch("the", "the dog ate the steak from the table.")
-- location is set to 28 (3rd 'the')
location = rmatch("the", "the dog ate the steak from the table.", -11)
-- location is set to 13 (2nd 'the')
</eucode>

===== See Also:
[[:rfind]], [[:match]]


@[:search:begins|]
==== begins
<eucode>
include std/search.e
namespace search
public function begins(object sub_text, sequence full_text)
</eucode>

  tests whether a sequence is the head of another one.

===== Parameters:
# ##sub_text## : an object to be looked for
# ##full_text## : a sequence, the head of which is being inspected.

===== Returns:
An **integer**, 1 if ##sub_text## begins ##full_text##, else 0.

===== Comments:
If ##sub_text## is an empty sequence, this returns 1 unless ##full_text##
is also an empty sequence.  When they are both empty sequences this returns
0.

===== Example 1:
<eucode>
s = begins("abc", "abcdef")
-- s is 1
s = begins("bcd", "abcdef")
-- s is 0
</eucode>

===== See Also:
[[:ends]], [[:head]]


@[:search:ends|]
==== ends
<eucode>
include std/search.e
namespace search
public function ends(object sub_text, sequence full_text)
</eucode>

  tests whether a sequence ends another one.

===== Parameters:
# ##sub_text## : an object to be looked for
# ##full_text## : a sequence, the tail of which is being inspected.

===== Returns:
An **integer**, 1 if ##sub_text## ends ##full_text##, else 0.

===== Comments:
If ##sub_text## is an empty sequence, this returns 1 unless ##full_text##
is also an empty sequence.  When they are both empty sequences this returns
0.

===== Example 1:
<eucode>
s = ends("def", "abcdef")
-- s is 1
s = begins("bcd", "abcdef")
-- s is 0
</eucode>

===== See Also:
[[:begins]], [[:tail]]


@[:search:is_in_range|]
==== is_in_range
<eucode>
include std/search.e
namespace search
public function is_in_range(object item, sequence range_limits, sequence boundries = "[]")
</eucode>

  tests to see if the ##item## is in a range of values supplied by ##range_limits##.

===== Parameters:
# ##item## : The object to test for.
# ##range_limits## : A sequence of two or more elements. The first is assumed
to be the smallest value and the last is assumed to be the highest value.
# ##boundries##: a sequence. This determines if the range limits are inclusive
or not. Must be one of ##"[]"## (the default), ##"[)"##, ##"(]"##, or
##"()"##.

===== Returns:
An **integer**, 0 if ##item## is not in the ##range_limits## otherwise it returns 1.

===== Comments:
* In ##boundries##, square brackets mean //inclusive// and round brackets
mean //exclusive//. Thus ##"[]"## includes both limits in the range, while
##"()"## excludes both limits. And, ##"[)"## includes the lower limit and excludes
the upper limits while ##"(]"## does the reverse.

===== Example 1:
<eucode>
if is_in_range(2, {2, 75}) then
    procA(user_data) -- Gets run (both limits included)
end if
if is_in_range(2, {2, 75}, "(]") then
    procA(user_data) -- Does not get run
end if
</eucode>


@[:search:is_in_list|]
==== is_in_list
<eucode>
include std/search.e
namespace search
public function is_in_list(object item, sequence list)
</eucode>

  tests to see if the ##item## is in a list of values supplied by ##list##.

===== Parameters:
# ##item## : The object to test for.
# ##list## : A sequence of elements that ##item## could be a member of.

===== Returns:
An **integer**,  0 if ##item## is not in the ##list##, otherwise
it returns 1.

===== Example 1:
<eucode>
if is_in_list(user_data, {100, 45, 2, 75, 121}) then
    procA(user_data)
end if
</eucode>


@[:search:lookup|]
==== lookup
<eucode>
include std/search.e
namespace search
public function lookup(object find_item, sequence source_list, sequence target_list,
        object def_value = 0)
</eucode>

  returns the corresponding element from the target list if
the supplied item is in the source list.

===== Parameters:
# ##find_item##: an object that might exist in ##source_list##.
# ##source_list##: a sequence that might contain ##pITem##.
# ##target_list##: a sequence from which the corresponding item will be returned.
# ##def_value##: an object (defaults to zero). This is returned when ##find_item##
is not in ##source_list## **and** ##target_list## is not longer than ##source_list##.

===== Returns:
An **object**
* If ##find_item## is found in ##source_list## then this is the corresponding element
from ##target_list##
* If ##find_item## is not in ##source_list## then if ##target_list## is longer than ##source_list##
then the last item in ##target_list## is returned otherwise ##def_value## is returned.

===== Example 1:
<eucode>
lookup('a', "cat", "dog") --> 'o'
lookup('d', "cat", "dogx") --> 'x'
lookup('d', "cat", "dog") --> 0
lookup('d', "cat", "dog", -1) --> -1
lookup("ant", {"ant","bear","cat"}, {"spider","seal","dog","unknown"}) 
            --> "spider"
lookup("dog", {"ant","bear","cat"}, {"spider","seal","dog","unknown"})     
            --> "unknown"
</eucode>



@[:search:vlookup|]
==== vlookup
<eucode>
include std/search.e
namespace search
public function vlookup(object find_item, sequence grid_data, integer source_col,
        integer target_col, object def_value = 0)
</eucode>

  returns the corresponding element from the target column
if the supplied item is in a source grid column.

===== Parameters:
# ##find_item##: an object that might exist in ##source_col##.
# ##grid_data##: a 2D grid sequence that might contain ##pITem##.
# ##source_col##: an integer. The column number to look for ##find_item##.
# ##target_col##: an integer. The column number from which the corresponding
item will be returned.
# ##def_value##: an object (defaults to zero). This is returned when ##find_item##
is not found in the ##source_col## column, or if found but the target column
does not exist.

===== Comments:
* If a row in the grid is actually a single atom, the row is ignored.
* If a row's length is less than the ##source_col##, the row is ignored.

===== Returns:
An **object**,
* If ##find_item## is found in the ##source_col## column then this is the corresponding element
from the ##target_col## column.

===== Example 1:
<eucode>
sequence grid
grid = {
       {"ant", "spider", "mortein"},
       {"bear", "seal", "gun"},
       {"cat", "dog", "ranger"},
       $
 }
vlookup("ant", grid, 1, 2, "?") --> "spider"
vlookup("ant", grid, 1, 3, "?") --> "mortein"
vlookup("seal", grid, 2, 3, "?") --> "gun"
vlookup("seal", grid, 2, 1, "?") --> "bear"
vlookup("mouse", grid, 2, 3, "?") --> "?"
</eucode>




!!CONTEXT:../include/std/sequence.e
!!namespace:stdseq
%%output = std_sequence

== Sequence Manipulation

<<LEVELTOC level=2 depth=4>>


=== Constants


@[:stdseq:ADD_PREPEND|]
==== ADD_PREPEND
<eucode>
include std/sequence.e
namespace stdseq
public enum ADD_PREPEND
</eucode>





@[:stdseq:ADD_APPEND|]
==== ADD_APPEND
<eucode>
include std/sequence.e
namespace stdseq
public enum ADD_APPEND
</eucode>





@[:stdseq:ADD_SORT_UP|]
==== ADD_SORT_UP
<eucode>
include std/sequence.e
namespace stdseq
public enum ADD_SORT_UP
</eucode>





@[:stdseq:ADD_SORT_DOWN|]
==== ADD_SORT_DOWN
<eucode>
include std/sequence.e
namespace stdseq
public enum ADD_SORT_DOWN
</eucode>





@[:stdseq:ROTATE_LEFT|]
==== ROTATE_LEFT
<eucode>
include std/sequence.e
namespace stdseq
public constant ROTATE_LEFT
</eucode>





@[:stdseq:ROTATE_RIGHT|]
==== ROTATE_RIGHT
<eucode>
include std/sequence.e
namespace stdseq
public constant ROTATE_RIGHT
</eucode>





=== Basic Routines



@[:stdseq:binop_ok|]
==== binop_ok
<eucode>
include std/sequence.e
namespace stdseq
public function binop_ok(object a, object b)
</eucode>

  checks whether two objects can perform a sequence operation together.

===== Parameters:
# ##a## : one of the objects to test for compatible shape
# ##b## : the other object

===== Returns:
An **integer**, 1 if a sequence operation is valid between ##a## and ##b##, else 0.

===== Example 1:
<eucode>
i = binop_ok({1,2,3},{4,5})
-- i is 0

i = binop_ok({1,2,3},4)
-- i is 1

i = binop_ok({1,2,3},{4,{5,6},7})
-- i is 1
</eucode>

===== See Also:
[[:series]]


@[:stdseq:fetch|]
==== fetch
<eucode>
include std/sequence.e
namespace stdseq
public function fetch(sequence source, sequence indexes)
</eucode>

  retrieves an element nested arbitrarily deep into a sequence.

===== Parameters:
# ##source## : the sequence from which to fetch
# ##indexes## : a sequence of integers, the path to follow to reach the
element to return.

===== Returns:
An **object**, which is ##source[indexes[1]][indexes[2]]...[indexes[$]]##

===== Errors:
If the path cannot be followed to its end, an error about reading a
nonexistent element, or subscripting an atom, will occur.

===== Comments:
The last element of ##indexes## may be a pair ##{lower,upper}##, in which case
a slice of the innermost referenced sequence is returned.

===== Example 1:
<eucode>
x = fetch({0,1,2,3,{"abc","def","ghi"},6},{5,2,3})
-- x is 'f', or 102.
</eucode>

===== See Also:
[[:store]], [[:Subscripting of Sequences]]


@[:stdseq:store|]
==== store
<eucode>
include std/sequence.e
namespace stdseq
public function store(sequence target, sequence indexes, object x)
</eucode>

  stores something at a location nested arbitrarily deep into a sequence.

===== Parameters:
# ##target## : the sequence in which to store something
# ##indexes## : a sequence of integers, the path to follow to reach the
place where to store
# ##x## : the object to store.

===== Returns:
A **sequence**, a **copy** of ##target## with the specified place
##indexes## modified by storing ##x## into it.

===== Errors:
If the path to storage location cannot be followed to its end, or an
index is not what one would expect or is not valid, an error about illegal
sequence operations will occur.

===== Comments:
If the last element of ##indexes## is a pair of integers, ##x## will be
stored as a slice three, the bounding indexes being given in the pair as ##{lower,upper}##.

In Euphoria, you can never modify an object by passing it to a routine.
You have to get a modified copy and then assign it back to the original.

===== Example 1:
<eucode>
s = store({0,1,2,3,{"abc","def","ghi"},6},{5,2,3},108)
-- s is {0,1,2,3,{"abc","del","ghi"},6}
</eucode>

===== See Also:
[[:fetch]], [[:Subscripting of Sequences]]


@[:stdseq:valid_index|]
==== valid_index
<eucode>
include std/sequence.e
namespace stdseq
public function valid_index(sequence st, object x)
</eucode>

  checks whether an index exists on a sequence.

===== Parameters:
# ##s## : the sequence for which to check
# ##x## : an object, the index to check.

===== Returns:
An **integer**, 1 if ##s[x]## makes sense, else 0.

===== Example 1:
<eucode>
i = valid_index({51,27,33,14},2)
-- i is 1
</eucode>

===== See Also:
[[:Subscripting of Sequences]]


@[:stdseq:rotate|]
==== rotate
<eucode>
include std/sequence.e
namespace stdseq
public function rotate(sequence source, integer shift, integer start = 1,
        integer stop = length(source))
</eucode>

  rotates a slice of a sequence.

===== Parameters:
# ##source## : sequence to be rotated
# ##shift## : direction and count to be shifted (##ROTATE_LEFT## or ##ROTATE_RIGHT##)
# ##start## : starting position for shift, defaults o 1
# ##stop## : stopping position for shift, defaults to ##length(source)##

===== Comments:

Use ##amount * direction## to specify the shift. direction is either ##ROTATE_LEFT##
or ##ROTATE_RIGHT##. This enables to shift multiple places in a single call.
For instance, use ##{{{ROTATE_LEFT * 5}}}## to rotate left, ##5##
positions.

A null shift does nothing and returns source unchanged.

===== Example 1:
<eucode>
s = rotate({1, 2, 3, 4, 5}, ROTATE_LEFT)
-- s is {2, 3, 4, 5, 1}
</eucode>

===== Example 2:
<eucode>
s = rotate({1, 2, 3, 4, 5}, ROTATE_RIGHT * 2)
-- s is {4, 5, 1, 2, 3}
</eucode>

===== Example 3:
<eucode>
s = rotate({11,13,15,17,19,23}, ROTATE_LEFT, 2, 5)
-- s is {11,15,17,19,13,23}
</eucode>

===== Example 4:
<eucode>
s = rotate({11,13,15,17,19,23}, ROTATE_RIGHT, 2, 5)
-- s is {11,19,13,15,17,23}
</eucode>

===== See Also:
[[:slice]], [[:head]], [[:tail]]


@[:stdseq:columnize|]
==== columnize
<eucode>
include std/sequence.e
namespace stdseq
public function columnize(sequence source, object cols = {}, object defval = 0)
</eucode>

  converts a set of sub sequences into a set of "columns."

===== Parameters:
# ##source## : sequence containing the sub-sequences
# ##cols## : either a specific column number or a set of column numbers.
Default is 0, which returns the maximum number of columns.
# ##defval## : an object. Used when a column value is not available. Default is 0

===== Comments:
Any atoms found in ##source## are treated as if they are a 1-element sequence.

===== Example 1:
<eucode>
s = columnize({{1, 2}, {3, 4}, {5, 6}})
-- s is { {1,3,5}, {2,4,6}}
</eucode>

===== Example 2:
<eucode>
s = columnize({{1, 2}, {3, 4}, {5, 6, 7}})
-- s is { {1,3,5}, {2,4,6}, {0,0,7} }
s = columnize({{1, 2}, {3, 4}, {5, 6, 7},,-999}) 
    --> Change the not-available value.
-- s is { {1,3,5}, {2,4,6}, {-999,-999,7} }
</eucode>

===== Example 3:
<eucode>
s = columnize({{1, 2}, {3, 4}, {5, 6, 7}}, 2)
-- s is { {2,4,6} } -- Column 2 only
</eucode>

===== Example 4:
<eucode>
s = columnize({{1, 2}, {3, 4}, {5, 6, 7}}, {2,1})
-- s is { {2,4,6}, {1,3,5} } -- Column 2 then column 1
</eucode>

===== Example 5:
<eucode>
s = columnize({"abc", "def", "ghi"})
-- s is {"adg", "beh", "cfi" }
</eucode>


@[:stdseq:apply|]
==== apply
<eucode>
include std/sequence.e
namespace stdseq
public function apply(sequence source, integer rid, object userdata = {})
</eucode>

  applies a function to every element of a sequence returning a new sequence of
the same size.

===== Parameters:
* ##source## : the sequence to map
* ##rid## : the [[:routine_id]] of function to use as converter
* ##userdata## : an object passed to each invocation of ##rid##. If omitted,
##{}## is used.

===== Returns:
A **sequence**, the length of ##source##. Each element there is the
corresponding element in ##source## mapped using the routine referred to by ##rid##.

===== Comments:
The supplied routine must take two arguments. The type of the first arguments must
be compatible with all the elements in ##source##. The second parameter is
an ##object## containing ##userdata##.

===== Example 1:
<eucode>
function greeter(object o, object d)
    return o[1] & ", " & o[2] & d
end function

s = apply({{"Hello", "John"}, {"Goodbye", "John"}},routine_id("greeter"),"!")
-- s is {"Hello, John!", "Goodbye, John!"}
</eucode>

===== See Also:
[[:filter]]


@[:stdseq:mapping|]
==== mapping
<eucode>
include std/sequence.e
namespace stdseq
public function mapping(object source_arg, sequence from_set, sequence to_set,
        integer one_level = 0)
</eucode>

  changes each item from ##source_arg## found in ##from_set## into the
corresponding item in ##to_set##

===== Parameters:
# ##source_arg## : Any Euphoria object to be transformed.
# ##from_set## : A sequence of objects representing the only items from
##source_arg## that are actually transformed.
# ##to_set## : A sequence of objects representing the transformed equivalents
of those found in ##from_set##.
# ##one_level## : An integer. ##0## (the default) means that mapping applies to
every atom in every level of sub-sequences. ##1## means that
mapping only applies to the items at the first level
in ##source_arg##.

===== Returns:
An **object**, The transformed version of ##source_arg##.

===== Comments:
* When ##one_level## is zero or omitted, for each item in ##source_arg##,
** if it is an atom then it may be transformed
** if it is a sequence, then the mapping is performed recursively on the
sequence.
** This option required ##from_set## to only contain atoms and contain no
sub-sequences.

* When ##one_level## is not zero, for each item in ##source_arg##,
** regardless of whether it is an atom or sequence, if it is found in ##from_set##
then it is mapped to the corresponding object in ##to_set##.
* Mapping occurs when an item in ##source_arg## is found in ##from_set##,
then it is replaced by the corresponding object in ##to_set##.

===== Example 1:
<eucode>
res = mapping("The Cat in the Hat", "aeiou", "AEIOU")
-- res is now "ThE CAt In thE HAt"
</eucode>


@[:eu:length|]
==== length
<eucode>
<built-in> function length(object target)
</eucode>

returns the length of an object.

===== Parameters:
# ##target## : the object being queried

===== Returns:
An **integer**, the number of elements involved with ##target##.

===== Comments:
* An atom only ever has a length of 1.
* The length of a sequence is the number of elements in the sequence.
* The length of each sequence is stored internally by the
interpreter for fast access. In some other languages this
operation requires a search through memory for an end marker.

===== Example 1:
<eucode>
length({{1,2}, {3,4}, {5,6}})   -- 3
length("")	 -- 0
length({})	 -- 0
length( 7 )   -- 1
length( 3.14 ) -- 1
</eucode>

===== See Also:
[[:append]], [[:prepend]], [[:& -> amp_concat]]


@[:stdseq:reverse|]
==== reverse
<eucode>
include std/sequence.e
namespace stdseq
public function reverse(object target, integer pFrom = 1, integer pTo = 0)
</eucode>

  reverses the order of elements in a sequence.

===== Parameters:
# ##target## : the sequence to reverse.
# ##pFrom## : an integer, the starting point. Defaults to 1.
# ##pTo## : an integer, the end point. Defaults to 0.

===== Returns:
A **sequence**, if ##target## is a sequence, the same length as ##target##
and the same elements, but those with index between ##pFrom## and ##pTo##
appear in reverse order.

===== Comments:
In the result sequence, some or all top-level elements appear in reverse order compared
to the original sequence. This does not reverse any sub-sequences found in the original
sequence.

The ##pTo## parameter can be negative, which indicates an offset from the last element.
Thus ##-1## means the second-last element and ##0## means the last element.

===== Example 1:
<eucode>
reverse({1,3,5,7})          -- {7,5,3,1}
reverse({1,3,5,7,9}, 2, -1) -- {1,7,5,3,9}
reverse({1,3,5,7,9}, 2)     -- {1,9,7,5,3}
reverse({{1,2,3}, {4,5,6}}) -- {{4,5,6}, {1,2,3}}
reverse({99})               -- {99}
reverse({})                 -- {}
reverse(42)                 -- 42
</eucode>


@[:stdseq:shuffle|]
==== shuffle
<eucode>
include std/sequence.e
namespace stdseq
public function shuffle(object seq)
</eucode>

  shuffles the elements of a sequence.

===== Parameters:
# ##seq##: the sequence to shuffle.

===== Returns:
A **sequence**

===== Comments:
The input sequence does not have to be in any specific order and can
contain duplicates. The output will be in an unpredictable order, which
might even be the same as the input order.

===== Example 1:
<eucode>
shuffle({1,2,3,3}) -- {3,1,3,2}
shuffle({1,2,3,3}) -- {2,3,1,3}
shuffle({1,2,3,3}) -- {1,2,3,3}
</eucode>


=== Building Sequences



@[:stdseq:series|]
==== series
<eucode>
include std/sequence.e
namespace stdseq
public function series(object start, object increment, integer count = 2, integer op = '+')
</eucode>

  returns a new sequence built as a series from a given object.

===== Parameters:
# ##start## : the initial value from which to start
# ##increment## : the value to recursively add to ##start## to get new elements
# ##count## :  an integer, the number of items in the returned sequence. The default is 2.
# ##operation## :  an integer, the type of operation used to build the series.
Can be either '+' for a linear series or '*' for a geometric series.
The default is '+'.

===== Returns:
An **object**, either 0 on failure or a sequence containing the series.


===== Comments:
* The first item in the returned series is always ##start##.
* A //linear// series is formed by **adding** ##increment## to ##start##.
* A //geometric// series is formed by **multiplying** ##increment## by ##start##.
* If ##count## is negative, or if ##start## **##op##** ##increment## is invalid,
then 0 is returned. Otherwise, a sequence, of length
##count+1##, staring with ##start## and whose adjacent elements differ
by ##increment##, is returned.

===== Example 1:
<eucode>
s = series( 1, 4, 5)
-- s is {1, 5, 9, 13, 17}
s = series( 1, 2, 6, '*')
-- s is {1, 2, 4, 8, 16, 32}
s = series({1,2,3}, 4, 2)
-- s is {{1,2,3}, {5,6,7}}
s = series({1,2,3}, {4,-1,10}, 2)
-- s is {{1,2,3}, {5,1,13}}
</eucode>

===== See Also:
[[:repeat_pattern]]


@[:stdseq:repeat_pattern|]
==== repeat_pattern
<eucode>
include std/sequence.e
namespace stdseq
public function repeat_pattern(object pattern, integer count)
</eucode>

  returns a periodic sequence, given a pattern and a count.

===== Parameters:
# ##pattern## : the sequence whose elements are to be repeated
# ##count## : an integer, the number of times the pattern is to be repeated.

===== Returns:
A **sequence**, empty on failure, and of length ##count*length(pattern)##
otherwise. The first elements of the returned sequence are those of
##pattern##. So are those that follow, on to the end.

===== Example 1:
<eucode>
s = repeat_pattern({1,2,5},3)
-- s is {1,2,5,1,2,5,1,2,5}
</eucode>

===== See Also:
[[:repeat]], [[:series]]


@[:eu:repeat|]
==== repeat
<eucode>
<built-in> function repeat(object item, atom count)
</eucode>

creates a sequence whose all elements are identical, with given length.

===== Parameters:
# ##item## : an object, to which all elements of the result will be equal
# ##count## : an atom, the requested length of the result sequence. This must
be a value from zero to ##0x3FFFFFFF##. Any floating point values
are first floored.

===== Returns:
A **sequence**, of length ##count## each element of which is ##item##.

===== Errors:
##count## cannot be less than zero and cannot be greater than ##1_073_741_823##.

===== Comments:
When you ##repeat## a sequence or an atom the
interpreter does not actually make multiple copies in memory.
Rather, a single copy is "pointed to" a number of times.

===== Example 1:
<eucode>
repeat(0, 10)	  -- {0,0,0,0,0,0,0,0,0,0}

repeat("JOHN", 4)  -- {"JOHN", "JOHN", "JOHN", "JOHN"}
-- The interpreter will create only one copy of "JOHN"
-- in memory and create a sequence containing four references to it.
</eucode>

===== See Also:
[[:repeat_pattern]], [[:series]]


=== Adding to Sequences



@[:eu:append|]
==== append
<eucode>
<built-in> function append(sequence target, object x)
</eucode>

adds an object as the last element of a sequence.

===== Parameters:
# ##source## : the sequence to add to
# ##x## : the object to add

===== Returns:
A **sequence**, whose first elements are those of ##target## and whose
last element is ##x##.

===== Comments:

The length of the resulting sequence will be ##length(target) + 1##, no
matter what ##x## is.

If ##x## is an atom this is equivalent to ##result = target & x##. If ##x##
is a sequence it is not equivalent.

The extra storage is allocated automatically and very efficiently with
Euphoria's dynamic storage allocation. The case where ##target## itself is
appended to (as in Example 1 below) is highly optimized.

===== Example 1:
<eucode>
  sequence x

  x = {}
  for i = 1 to 10 do
     x = append(x, i)
  end for
  -- x is now {1,2,3,4,5,6,7,8,9,10}
</eucode>

===== Example 2:
<eucode>
sequence x, y, z

x = {"fred", "barney"}
y = append(x, "wilma")
-- y is now {"fred", "barney", "wilma"}

z = append(append(y, "betty"), {"bam", "bam"})
-- z is now {"fred", "barney", "wilma", "betty", {"bam", "bam"}}
</eucode>

===== See Also:
[[:prepend]], [[:& -> amp_concat]]


@[:eu:prepend|]
==== prepend
<eucode>
<built-in> function prepend(sequence target, object x)
</eucode>

adds an object as the first element of a sequence.

===== Parameters:
# ##source## : the sequence to add to
# ##x## : the object to add

===== Returns:
A **sequence**, whose last elements are those of ##target## and whose
first element is ##x##.

===== Comments:
The length of the returned sequence will be ##length(target) + 1## always.

If ##x## is an atom this is the same as ##result = x & target##. If ##x## is
a sequence it is not the same.

The case where ##target## itself is prepended to is handled very efficiently.

===== Example 1:
<eucode>
prepend({1,2,3}, {0,0})	 -- {{0,0}, 1, 2, 3}
-- Compare with concatenation:
{0,0} & {1,2,3}			 -- {0, 0, 1, 2, 3}
</eucode>

===== Example 2:
<eucode>
s = {}
for i = 1 to 10 do
   s = prepend(s, i)
end for
-- s is {10,9,8,7,6,5,4,3,2,1}
</eucode>

===== See Also:
[[:append]], [[:& -> amp_concat]]


@[:eu:insert|]
==== insert
<eucode>
<built-in> function insert(sequence target, object what, integer index)
</eucode>

inserts an object into a sequence as a new element at a given location.

===== Parameters:
# ##target## : the sequence to insert into
# ##what## : the object to insert
# ##index## : an integer, the position in ##target## where ##what##
should appear

===== Returns:
A **sequence**, which is ##target## with one more element at ##index##,
which is ##what##.

===== Comments:
##target## can be a sequence of any shape, and ##what## any kind of object.

The length of the returned sequence is always ##length(target) + 1##.

Inserting a sequence into a string returns a sequence which is no longer a string.

===== Example 1:
<eucode>
s = insert("John Doe", " Middle", 5)
-- s is {'J','o','h','n'," Middle",' ','D','o','e'}
</eucode>

===== Example 2:
<eucode>
s = insert({10,30,40}, 20, 2)
-- s is {10,20,30,40}
</eucode>

===== See Also:
[[:remove]], [[:splice]], [[:append]], [[:prepend]]


@[:eu:splice|]
==== splice
<eucode>
<built-in> function splice(sequence target, object what, integer index)
</eucode>

inserts an object as a new slice in a sequence at a given position.

===== Parameters:
# ##target## : the sequence to insert into
# ##what## : the object to insert
# ##index## : an integer, the position in ##target## where ##what## should appear

===== Returns:
A **sequence**, which is ##target## with one or more elements, those of ##what##,
inserted at locations starting at ##index##.

===== Comments:
##target## can be a sequence of any shape, and ##what## any kind of object.

The length of this new sequence is the sum of the lengths of ##target## and ##what##.
##splice## is equivalent to
[[:insert]] when ##what## is an atom, but not when it is a sequence.

Splicing a string into a string results into a new string.

===== Example 1:
<eucode>
s = splice("John Doe", " Middle", 5)
-- s is "John Middle Doe"
</eucode>

===== Example 2:
<eucode>
s = splice({10,30,40}, 20, 2)
-- s is {10,20,30,40}
</eucode>

===== See Also:
[[:insert]], [[:remove]], [[:replace]], [[:& -> amp_concat]]


@[:stdseq:pad_head|]
==== pad_head
<eucode>
include std/sequence.e
namespace stdseq
public function pad_head(object target, integer size, object ch = ' ')
</eucode>

  pads the beginning of a sequence with an object so as to meet a minimum
length condition.

===== Parameters:
# ##target## : the sequence to pad.
# ##size## : an integer, the target minimum size for ##target##
# ##padding## : an object, usually the character to pad to (defaults to ' ').

===== Returns:
A **sequence**, either ##target## if it was long enough, or a sequence of
length ##size## whose last elements are those of ##target## and whose first
few head elements all equal ##padding##.

===== Comments:
##pad_head## will not remove characters. If ##length(target)## is greater
than ##size##, this function simply returns ##target##. See [[:head]]
if you wish to truncate long sequences.

===== Example 1:
<eucode>
s = pad_head("ABC", 6)
-- s is "   ABC"

s = pad_head("ABC", 6, '-')
-- s is "---ABC"
</eucode>

===== See Also:
[[:trim_head]], [[:pad_tail]], [[:head]]


@[:stdseq:pad_tail|]
==== pad_tail
<eucode>
include std/sequence.e
namespace stdseq
public function pad_tail(object target, integer size, object ch = ' ')
</eucode>

  pads the end of a sequence with an object so as to meet a minimum length condition.

===== Parameters:
# ##target## : the sequence to pad.
# ##size## : an integer, the target minimum size for ##target##
# ##padding## : an object, usually the character to pad to (defaults to ' ').

===== Returns:
A **sequence**, either ##target## if it was long enough, or a sequence
of length ##size## whose first elements are those of ##target## and whose
last few head elements all equal ##padding##.

===== Comments:
##pad_tail## will not remove characters. If ##length(target)## is greater
than ##size##, this function simply returns ##target##. See [[:tail]] if
you wish to truncate long sequences.

===== Comments:

##pad_tail## will not remove characters. If ##length(str)## is greater than params, this
function simply returns ##str##. See ##tail## if you wish to truncate long sequences.

===== Example 1:
<eucode>
s = pad_tail("ABC", 6)
-- s is "ABC   "

s = pad_tail("ABC", 6, '-')
-- s is "ABC---"
</eucode>

===== See Also:
[[:trim_tail]], [[:pad_head]], [[:tail]]


@[:stdseq:add_item|]
==== add_item
<eucode>
include std/sequence.e
namespace stdseq
public function add_item(object needle, sequence haystack, integer pOrder = 1)
</eucode>

  adds an item to the sequence if its not already there. If it already exists
in the list, the list is returned unchanged.

===== Parameters:
# ##needle## :   object to add.
# ##haystack## : sequence to add it to.
# ##order## :    an integer; determines how the ##needle## affects the ##haystack##.
It can be added to the front (prepended), to the back (appended),
or sorted after adding. The default is to prepend it.

===== Returns:
A **sequence**, which is ##haystack## with ##needle## added to it.

===== Comments:

An error occurs if an invalid ##order## argument is supplied.

The following enum is provided for specifying ##order##:
* ##ADD_PREPEND## ~--  prepend ##needle## to ##haystack##. This is the default option.
* ##ADD_APPEND## ~--  append ##needle## to ##haystack##.
* ##ADD_SORT_UP## ~-- sort ##haystack## in ascending order after inserting ##needle##
* ##ADD_SORT_DOWN## ~-- sort ##haystack## in descending order after inserting ##needle##

===== Example 1:
<eucode>
s = add_item( 1, {3,4,2}, ADD_PREPEND ) -- prepend
-- s is {1,3,4,2}
</eucode>

===== Example 2:
<eucode>
s = add_item( 1, {3,4,2}, ADD_APPEND ) -- append
-- s is {3,4,2,1}
</eucode>

===== Example 3:
<eucode>
s = add_item( 1, {3,4,2}, ADD_SORT_UP ) -- ascending
-- s is {1,2,3,4}
</eucode>

===== Example 4:
<eucode>
s = add_item( 1, {3,4,2}, ADD_SORT_DOWN ) -- descending
-- s is {4,3,2,1}
</eucode>

===== Example 5:
<eucode>
s = add_item( 1, {3,1,4,2} )
-- s is {3,1,4,2} -- Item was already in list so no change.
</eucode>


@[:stdseq:remove_item|]
==== remove_item
<eucode>
include std/sequence.e
namespace stdseq
public function remove_item(object needle, sequence haystack)
</eucode>

  removes an item from the sequence.

===== Parameters:
# ##needle## :   object to remove.
# ##haystack## : sequence to remove it from.

===== Returns:
A **sequence**, which is ##haystack## with ##needle## removed from it.

===== Comments:
If ##needle## is not in ##haystack## then ##haystack## is returned unchanged.

===== Example 1:
<eucode>
s = remove_item( 1, {3,4,2,1} ) --> {3,4,2}
s = remove_item( 5, {3,4,2,1} ) --> {3,4,2,1}
</eucode>


=== Extracting, Removing, Replacing



@[:eu:head|]
==== head
<eucode>
<built-in> function head(sequence source, atom size=1)
</eucode>

returns the first ##size## item or items of a sequence.

===== Parameters:
# ##source## : the sequence from which elements will be returned
# ##size## : an integer; how many elements, at most, will be returned.
Defaults to 1.

===== Returns:
A **sequence**, ##source## if its length is not greater than ##size##,
or the ##size## first elements of ##source## otherwise.

===== Example 1:
<eucode>
s2 = head("John Doe", 4)
-- s2 is John
</eucode>

===== Example 2:
<eucode>
s2 = head("John Doe", 50)
-- s2 is John Doe
</eucode>

===== Example 3:
<eucode>
s2 = head({1, 5.4, "John", 30}, 3)
-- s2 is {1, 5.4, "John"}
</eucode>

===== See Also:
[[:tail]], [[:mid]], [[:slice]]


@[:eu:tail|]
==== tail
<eucode>
<built-in> function tail(sequence source, atom size=length(source) - 1)
</eucode>

returns the last ##size## item or items of a sequence.

===== Parameters:
# ##source## : the sequence to get the tail of.
# ##size## : an integer, the number of items to return.
(defaults to length(source) - 1)

===== Returns:
A **sequence**, of length at most ##size##. If the length is less than
##size##, then ##source## was returned. Otherwise, the ##size## last elements
of ##source## were returned.

===== Comments:
##source## can be any type of sequence, including nested sequences.

===== Example 1:
<eucode>
s2 = tail("John Doe", 3)
-- s2 is "Doe"
</eucode>

===== Example 2:
<eucode>
s2 = tail("John Doe", 50)
-- s2 is "John Doe"
</eucode>

===== Example 3:
<eucode>
s2 = tail({1, 5.4, "John", 30}, 3)
-- s2 is {5.4, "John", 30}
</eucode>

===== See Also:
[[:head]], [[:mid]], [[:slice]]


@[:stdseq:mid|]
==== mid
<eucode>
include std/sequence.e
namespace stdseq
public function mid(sequence source, atom start, atom len)
</eucode>

  returns a slice of a sequence, given by a starting point and a length.

===== Parameters:
# ##source## : the sequence some elements of which will be returned
# ##start## : an integer, the lower index of the slice to return
# ##len## : an integer, the length of the slice to return

===== Returns:
A **sequence**, made of at most ##len## elements of ##source##. These
elements are at contiguous positions in ##source## starting at ##start##.

===== Errors:
If ##len## is less than ##-length(source)##, an error occurs.

===== Comments:
##len## may be negative, in which case it is added ##length(source)## once.

===== Example 1:
<eucode>
s2 = mid("John Middle Doe", 6, 6)
-- s2 is Middle
</eucode>

===== Example 2:
<eucode>
s2 = mid("John Middle Doe", 6, 50)
-- s2 is Middle Doe
</eucode>

===== Example 3:
<eucode>
s2 = mid({1, 5.4, "John", 30}, 2, 2)
-- s2 is {5.4, "John"}
</eucode>

===== Example 4:
<eucode>
s2 = mid({1, 5.4, "John", 30}, 2, -1)
-- s2 is {5.4, "John", 30}
</eucode>

===== See Also:
[[:head]], [[:tail]], [[:slice]]


@[:stdseq:slice|]
==== slice
<eucode>
include std/sequence.e
namespace stdseq
public function slice(sequence source, atom start = 1, atom stop = 0)
</eucode>

  returns a portion of the supplied sequence.

===== Parameters:
# ##source## : the sequence from which to get a portion
# ##start## : an integer, the starting point of the portion. Default is 1.
# ##stop## : an integer, the ending point of the portion. Default is length(source).

===== Returns:
A **sequence**.

===== Comments:
* If the supplied ##start## is less than 1 then it set to 1.
* If the supplied ##stop## is less than 1 then ##length(source)## is added to it.
In this way, 0 represents the end of ##source##, -1 represents one element
in from the end of ##source## and so on.
* If the supplied ##stop## is greater than ##length(source)## then it is set to the end.
* After these adjustments, and if ##source[start..stop]## makes sense, it is
returned, otherwise, ##{}## is returned.

===== Example 1:
<eucode>
s2 = slice("John Doe", 6, 8)--> "Doe"
s2 = slice("John Doe", 6, 50) --> "Doe"
s2 = slice({1, 5.4, "John", 30}, 2, 3) --> {5.4, "John"}
s2 = slice({1,2,3,4,5}, 2, -1) --> {2,3,4}
s2 = slice({1,2,3,4,5}, 2) --> {2,3,4,5}
s2 = slice({1,2,3,4,5}, , 4) --> {1,2,3,4}
</eucode>

===== See Also:
[[:head]], [[:mid]], [[:tail]]


@[:stdseq:vslice|]
==== vslice
<eucode>
include std/sequence.e
namespace stdseq
public function vslice(sequence source, atom colno, object error_control = 0)
</eucode>

  performs a vertical slice on a nested sequence.

===== Parameters:
# ##source## : the sequence to take a vertical slice from
# ##colno## : an atom, the column number to extract (rounded down)
# ##error_control## : an object which says what to do if some element
does not exist. Defaults to 0 (crash in such a circumstance).

===== Returns:
A **sequence**, usually of the same length as ##source##, made of all
the ##source[x][colno]##.

===== Errors:
If an element is not defined and ##error_control## is 0, an error occurs.
If ##colno## is less than 1, it cannot be any valid column, and an error occurs.

===== Comments:
If it is not possible to return the sequence of all ##source[x][colno]]##
for all available ##x##, the outcome is decided by ##error_control##:
* If 0 (the default), program is aborted.
* If a nonzero atom, the short vertical slice is returned.
* Otherwise, elements of ##error_control## will be taken to make for any
missing element. The elements are selected from the first to the last,
as needed and this cycles again from the first.

===== Example 1:
<eucode>
s = vslice({{5,1}, {5,2}, {5,3}}, 2)
-- s is {1,2,3}

s = vslice({{5,1}, {5,2}, {5,3}}, 1)
-- s is {5,5,5}
</eucode>

===== See Also:
[[:slice]], [[:project]]


@[:eu:remove|]
==== remove
<eucode>
<built-in> function remove(sequence target, atom start, atom stop=start)
</eucode>

removes an item, or a range of items from a sequence.

===== Parameters:
# ##target## : the sequence to remove from.
# ##start## : an atom, the (starting) index at which to remove
# ##stop## : an atom, the index at which to stop removing (defaults to ##start##)

===== Returns:
A **sequence**, obtained from ##target## by carving the ##start..stop## slice
out of it.

===== Comments:
A new sequence is created. ##target## can be a string or complex sequence.

===== Example 1:
<eucode>
s = remove("Johnn Doe", 4)
-- s is "John Doe"
</eucode>

===== Example 2:
<eucode>
s = remove({1,2,3,3,4}, 4)
-- s is {1,2,3,4}
</eucode>

===== Example 3:
<eucode>
s = remove("John Middle Doe", 6, 12)
-- s is "John Doe"
</eucode>

===== Example 4:
<eucode>
s = remove({1,2,3,3,4,4}, 4, 5)
-- s is {1,2,3,4}
</eucode>

===== See Also:
[[:replace]], [[:insert]], [[:splice]], [[:remove_all]]


@[:stdseq:patch|]
==== patch
<eucode>
include std/sequence.e
namespace stdseq
public function patch(sequence target, sequence source, integer start, object filler = ' ')
</eucode>

  changes a sequence slice, possibly with padding.

===== Parameters:
# ##target## : a sequence, a modified copy of which will be returned
# ##source## : a sequence, to be patched inside or outside ##target##
# ##start## : an integer, the position at which to patch
# ##filler## : an object, used for filling gaps. Defaults to ' '

===== Returns:
A **sequence**, which looks like ##target##, but a slice starting at ##start##
equals ##source##.

===== Comments:

In some cases, this call will result in the same result as [[:replace]].

If ##source## does not fit into ##target## because of the lengths and the
supplied ##start## value, gaps will be created, and ##filler## is used to
fill them in.

Notionally, ##target## has an infinite amount of ##filler## on both sides,
and ##start## counts position relative to where ##target## actually starts.
Then, notionally, a [[:replace]] operation is performed.

===== Example 1:
<eucode>
sequence source = "abc", target = "John Doe"
sequence s = patch(target, source, 11,'0')
-- s is now "John Doe00abc"
</eucode>

===== Example 2:
<eucode>
sequence source = "abc", target = "John Doe"
sequence s = patch(target, source, -1)
-- s is now "abcohn Doe"
Note that there was no gap to fill.
Since -1 = 1 - 2, the patching started 2 positions before the initial 'J'.
</eucode>

===== Example 3:
<eucode>
sequence source = "abc", target = "John Doe"
sequence s = patch(target, source, 6)
-- s is now "John Dabc"
</eucode>

===== See Also:
[[:mid]], [[:replace]]


@[:stdseq:remove_all|]
==== remove_all
<eucode>
include std/sequence.e
namespace stdseq
public function remove_all(object needle, sequence haystack)
</eucode>

  removes all occurrences of some object from a sequence.

===== Parameters:
# ##needle## : the object to remove.
# ##haystack## : the sequence to remove from.

===== Returns:
A **sequence**, of length at most ##length(haystack)##, and which has
the same elements, without any copy of ##needle## left

===== Comments:
This function weeds elements out, not sub-sequences.

===== Example 1:
<eucode>
s = remove_all( 1, {1,2,4,1,3,2,4,1,2,3} )
-- s is {2,4,3,2,4,2,3}
</eucode>

===== Example 2:
<eucode>
s = remove_all('x', "I'm toox secxksy for my shixrt.")
-- s is "I'm too secksy for my shirt."
</eucode>

===== See Also:
[[:remove]], [[:replace]]


@[:stdseq:retain_all|]
==== retain_all
<eucode>
include std/sequence.e
namespace stdseq
public function retain_all(object needles, sequence haystack)
</eucode>

  keeps all occurrences of a set of objects from a sequence and removes all others.

===== Parameters:
# ##needles## : the set of objects to retain.
# ##haystack## : the sequence to remove items not in ##needles##.

===== Returns:
A **sequence** containing only those objects from ##haystack## that are also in ##needles##.

===== Example 1:
<eucode>
s = retain_all( {1,3,5}, {1,2,4,1,3,2,4,1,2,3} ) --> {1,1,3,1,3}
s = retain_all("0123456789", "+34 (04) 555-44392") -> "340455544392"
</eucode>

===== See Also:
[[:remove]], [[:replace]], [[:remove_all]]


@[:stdseq:filter|]
==== filter
<eucode>
include std/sequence.e
namespace stdseq
public function filter(sequence source, object rid, object userdata = {},
        object rangetype = "")
</eucode>

  filters a sequence based on a user supplied comparator function.

===== Parameters:
* ##source## : sequence to filter
* ##rid## : Either a [[:routine_id]] of function to use as comparator or one
of the predefined comparitors.
* ##userdata## : an object passed to each invocation of ##rid##. If omitted,
##{}## is used.
* ##rangetype##: A sequence. Only used when ##rid## is "in" or "out". This is
used to let the function know how to interpret ##userdata##. When ##rangetype##
is an empty string (which is the default), then ##userdata## is treated as a set of zero or more
discrete items such that "in" will only return items from ##source## that are
in the set of item in ##userdata## and "out" returns those not in ##userdata##.
The other values for ##rangetype## mean that ##userdata## must be a set of
exactly two items, that represent the lower and upper limits of a range of
values.

===== Returns:
A **sequence**, made of the elements in ##source## which passed the
comparitor test.

===== Comments:
* The only items from ##source## that are returned are those that pass the test.
* When ##rid## is a routine_id, that user defined routine must be a function.
Each item in ##source##, along with the ##userdata## is passed to the function.
The function must return a non-zero atom if the item is to be included in the
result sequence, otherwise it should return zero to exclude it from the result.

* The predefined comparitors are~:

|= Comparitor |  |= Return Items in ##source## that are... |
| "<"  |   "lt" | less than ##userdata## |
| "<=" |  "le" |  less than or equal to ##userdata## |
| "=" or "==" |  "eq" |  equal to ##userdata## |
| "!=" |  "ne" |  not equal to ##userdata## |
| ">"  |  "gt" |  greater than ##userdata## |
| ">=" | "ge" | greater than or equal to ##userdata## |
| | "in" | in ##userdata## |
| | "out" | not in ##userdata## |

* Range Type Usage

|= Range Type  |= Range |= Meaning |
| "[]"         | Inclusive range. | Lower and upper are in the range. |
| "[)"         | Low Inclusive range. | Lower is in the range but upper is not. |
| "(]"         | High Inclusive range.| Lower is not in the range but upper is. |
| "()"         | Exclusive range. | Lower and upper are not in the range. |

===== Example 1:
<eucode>
function mask_nums(atom a, object t)
    if sequence(t) then
        return 0
    end if
    return and_bits(a, t) != 0
end function

function even_nums(atom a, atom t)
    return and_bits(a,1) = 0
end function

constant data = {5,8,20,19,3,2,10}
filter(data, routine_id("mask_nums"), 1) --> {5,19,3}
filter(data, routine_id("mask_nums"), 2) -->{19, 3, 2, 10}
filter(data, routine_id("even_nums")) -->{8, 20, 2, 10}

-- Using 'in' and 'out' with sets.
filter(data, "in", {3,4,5,6,7,8}) -->{5,8,3}
filter(data, "out", {3,4,5,6,7,8}) -->{20,19,2,10}

-- Using 'in' and 'out' with ranges.
filter(data, "in",  {3,8}, "[]") --> {5,8,3}
filter(data, "in",  {3,8}, "[)") --> {5,3}
filter(data, "in",  {3,8}, "(]") --> {5,8}
filter(data, "in",  {3,8}, "()") --> {5}
filter(data, "out", {3,8}, "[]") --> {20,19,2,10}
filter(data, "out", {3,8}, "[)") --> {8,20,19,2,10}
filter(data, "out", {3,8}, "(]") --> {20,19,3,2,10}
filter(data, "out", {3,8}, "()") --> {8,20,19,3,2,10}
</eucode>

===== Example 2:
<eucode>
function quiksort(sequence s)
	if length(s) < 2 then
		return s
	end if
	return quiksort( filter(s[2..$], "<=", s[1]) ) & s[1] & quiksort(filter(s[2..$], ">", s[1]))
end function
? quiksort( {5,4,7,2,4,9,1,0,4,32,7,54,2,5,8,445,67} )
--> {0,1,2,2,4,4,4,5,5,7,7,8,9,32,54,67,445}
</eucode>

===== See Also:
[[:apply]]


@[:stdseq:STDFLTR_ALPHA|]
==== STDFLTR_ALPHA
<eucode>
public constant STDFLTR_ALPHA
</eucode>

Predefined routine_id for use with [[:filter]].

===== Comments:
Used to filter out non-alphabetic characters from a string.

===== Example 1:
<eucode>
-- Collect only the alphabetic characters from 'text'
 result = filter(text, STDFLTR_ALPHA)
</eucode>





@[:eu:replace|]
==== replace
<eucode>
<built-in> function replace(sequence target, object replacement, integer start, integer stop=start)
</eucode>

replaces a slice in a sequence by an object.

===== Parameters:
# ##target## : the sequence in which replacement will be done.
# ##replacement## : an object, the item to replace with.
# ##start## : an integer, the starting index of the slice to replace.
# ##stop## : an integer, the stopping index of the slice to replace.

===== Returns:
A **sequence**, which is made of ##target## with the ##start..stop## slice
removed and replaced by ##replacement##, which is spliced in.

===== Comments:
* A new sequence is created. ##target## can be a string or complex sequence
of any shape.

* To replace by just one element, enclose ##replacement## in curly braces,
which will be removed at replace time.

===== Example 1:
<eucode>
s = replace("John Middle Doe", "Smith", 6, 11)
-- s is "John Smith Doe"

s = replace({45.3, "John", 5, {10, 20}}, 25, 2, 3)
-- s is {45.3, 25, {10, 20}}
</eucode>

===== See Also:
[[:splice]], [[:remove]], [[:remove_all]]


@[:stdseq:extract|]
==== extract
<eucode>
include std/sequence.e
namespace stdseq
public function extract(sequence source, sequence indexes)
</eucode>

  picks out from a sequence a set of elements according to the supplied set of indexes.

===== Parameters:
# ##source## : the sequence from which to extract elements
# ##indexes## : a sequence of atoms, the indexes of the elements to be fetched in ##source##.

===== Returns:
A **sequence**, of the same length as ##indexes##.

===== Example 1:
<eucode>
s = extract({11,13,15,17},{3,1,2,1,4})
-- s is {15,11,13,11,17}
</eucode>

===== See Also:
[[:slice]]


@[:stdseq:project|]
==== project
<eucode>
include std/sequence.e
namespace stdseq
public function project(sequence source, sequence coords)
</eucode>

  creates a list of sequences based on selected elements from sequences in the source.

===== Parameters:
# ##source## : a list of sequences.
# ##coords## : a list of index lists.

===== Returns:
A **sequence**, with the same length as ##source##. Each of its elements is a sequence,
the length of ##coords##. Each innermost sequence is made of the
elements from the corresponding source sub-sequence.

===== Comments:
For each sequence in ##source##, a set of sub-sequences is created; one for
each index list in ##coords##. An index list is just a sequence containing
indexes for items in a sequence.

===== Example 1:
<eucode>
s = project({ "ABCD",  "789"},  {{1,2}, {3,1}, {2}})
-- s is {{"AB","CA","B"},{"78","97","8"}}
</eucode>

===== See Also:
[[:vslice]], [[:extract]]


=== Changing the Shape of a Sequence



@[:stdseq:split|]
==== split
<eucode>
include std/sequence.e
namespace stdseq
public function split(sequence st, object delim = ' ', integer no_empty = 0,
        integer limit = 0)
</eucode>

  splits a sequence on separator delimiters into a number of sub-sequences.

===== Parameters:
# ##source## : the sequence to split.
# ##delim## : an object (default is ' '). The delimiter that separates items
in ##source##.
# ##no_empty## : an integer (default is 0). If not zero then all zero-length sub-sequences
are removed from the returned sequence. Use this when leading,
trailing and duplicated delimiters are not significant.
# ##limit## : an integer (default is 0). The maximum number of sub-sequences
to create. If zero, there is no limit.

===== Returns:
A **sequence**, of sub-sequences of ##source##. Delimiters are removed.

===== Comments:
This function may be applied to a string sequence or a complex sequence.

If ##limit## is ##> 0##, this is the maximum number of sub-sequences that will
created, otherwise there is no limit.

===== Example 1:
<eucode>
result = split("John Middle Doe")
-- result is {"John", "Middle", "Doe"}
</eucode>

===== Example 2:
<eucode>
result = split("John,Middle,Doe", ",",, 2) -- Only want 2 sub-sequences.
-- result is {"John", "Middle,Doe"}
</eucode>

===== Example 3:
<eucode>
result = split("John||Middle||Doe|", '|') -- Each '|' is significant by default
-- result is {"John","","Middle","","Doe",""}
result = split("John||Middle||Doe|", '|', 1) -- Adjacent '|' are just a single delim,
                                             -- and leading/trailing '|' ignored.
-- result is {"John","Middle","Doe"}
</eucode>

===== See Also:
[[:split_any]], [[:breakup]], [[:join]]


@[:stdseq:split_any|]
==== split_any
<eucode>
include std/sequence.e
namespace stdseq
public function split_any(sequence source, object delim = ", \t|", integer limit = 0,
        integer no_empty = 0)
</eucode>

  splits a sequence by any of the separators in the list of delimiters.

If ##limit## is ##> 0## then limit the number of tokens that will be split to limit.

===== Parameters:
# ##source## : the sequence to split.
# ##delim## : a list of delimiters to split by. The default set is comma, space, tab and bar.
# ##limit## : an integer (default is 0). The maximum number of sub-sequences
to create. If zero, there is no limit.
# ##no_empty## : an integer (default is 0). If not zero then all zero-length sub-sequences
removed from the returned sequence. Use this when leading,
trailing and duplicated delimiters are not significant.

===== Comments:
* This function may be applied to a string sequence or a complex sequence.
* It works like ##split##, but in this case ##delim## is a set of potential
delimiters rather than a single delimiter.
* If ##delim## is an empty set, the ##source## is returned in a sequence.

===== Example 1:
<eucode>
result = split_any("One,Two|Three Four") -- Default delims
-- result is {"One", "Two", "Three", "Four"}
result = split_any("192.168.1.103:8080", ".:") -- Using dot and colon
-- result is {"192","168","1","103","8080"}
result = split_any("One,Two|Three Four",, 2) -- limited to two splits
-- result is {"One", "Two", "Three Four"}
result = split_any(",One,,Two| Three|| Four,"  ) -- Allow Empty option
-- result is {"","One","","Two","","Three","","","Four",""}
result = split_any(",One,,Two| Three|| Four,",,,1) -- No Empty option
-- result is {"One", "Two", "Three", "Four"}
result = split_any(",One,,Two| Three|| Four,", "") -- Empty delimiters
-- result is {",One,,Two| Three|| Four,"}
</eucode>

===== See Also:
[[:split]], [[:breakup]], [[:join]]


@[:stdseq:join|]
==== join
<eucode>
include std/sequence.e
namespace stdseq
public function join(sequence items, object delim = " ")
</eucode>

  joins sequences together using a delimiter.

===== Parameters:
# ##items## : the sequence of items to join.
# ##delim## : an object, the delimiter to join by. Defaults to " ".

===== Comments:
This function may be applied to a string sequence or a complex sequence

===== Example 1:
<eucode>
result = join({"John", "Middle", "Doe"})
-- result is "John Middle Doe"
</eucode>

===== Example 2:
<eucode>
result = join({"John", "Middle", "Doe"}, ",")
-- result is "John,Middle,Doe"
</eucode>

===== See Also:
[[:split]], [[:split_any]], [[:breakup]]


@[:stdseq:BK_LEN|]
==== BK_LEN
<eucode>
include std/sequence.e
namespace stdseq
public enum BK_LEN
</eucode>

 Indicates that ##size## parameter is maximum length of sub-sequence. See [[:breakup]]



@[:stdseq:BK_PIECES|]
==== BK_PIECES
<eucode>
include std/sequence.e
namespace stdseq
public enum BK_PIECES
</eucode>

 Indicates that ##size## parameter is maximum number of sub-sequence. See [[:breakup]]



@[:stdseq:breakup|]
==== breakup
<eucode>
include std/sequence.e
namespace stdseq
public function breakup(sequence source, object size, integer style = BK_LEN)
</eucode>

  breaks up a sequence into multiple sequences of a given length.

===== Parameters:
# ##source## : the sequence to be broken up into sub-sequences.
# ##size## : an object, if an integer it is either the maximum length of
each resulting sub-sequence or the maximum number of
sub-sequences to break ##source## into. \\
If ##size## is a sequence, it is a list of element counts
for the sub-sequences it creates.
# ##style## : an integer, Either ##BK_LEN## if ##size## integer represents
the sub-sequences' maximum length, or ##BK_PIECES## if
the ##size## integer represents the maximum number of
sub-sequences (pieces) to break ##source## into.

===== Returns:
A **sequence**, of sequences.

===== Comments:
**When ##size## is an integer and ##style## is BK_LEN...**\\
The sub-sequences have length ##size##, except possibly the last one,
which may be shorter. For example if ##source## has 11 items and ##size## is
3, then the first three sub-sequences will get 3 items each and the remaining
2 items will go into the last sub-sequence. If ##size## is less than 1 or
greater than the length of the ##source##, the ##source## is returned as the
only sub-sequence.

**When ##size## is an integer and ##style## is BK_PIECES...**\\
There is exactly ##size## sub-sequences created. If the ##source## is not
evenly divisible into that many pieces, then the lefthand sub-sequences will
contain one more element than the right-hand sub-sequences. For example, if
source contains 10 items and we break it into 3 pieces, piece #1 gets 4 elements,
piece #2 gets 3 items and piece #3 gets 3 items - a total of 10. If source had
11 elements then the pieces will have 4,4, and 3 respectively.

**When ##size## is a sequence...**\\
The style parameter is ignored in this case. The source will be broken up
according to the counts contained in the size parameter. For example, if
##size## was {3,4,0,1} then piece #1 gets 3 items, #2 gets 4 items, #3 gets
0 items, and #4 gets 1 item. Note that if not all items from source are
placed into the sub-sequences defined by ##size##, and //extra// sub-sequence
is appended that contains the remaining items from ##source##.

In all cases, when concatenated these sub-sequences will be identical
to the original ##source##.


===== Example 1:
<eucode>
s = breakup("5545112133234454", 4)
-- s is {"5545", "1121", "3323", "4454"}
</eucode>

===== Example 2:
<eucode>
s = breakup("12345", 2)
-- s is {"12", "34", "5"}
</eucode>

===== Example 3:
<eucode>
s = breakup({1,2,3,4,5,6}, 3)
-- s is {{1,2,3}, {4,5,6}}
</eucode>

===== Example 4:
<eucode>
s = breakup("ABCDEF", 0)
-- s is {"ABCDEF"}
</eucode>

===== See Also:
[[:split]] [[:flatten]]


@[:stdseq:flatten|]
==== flatten
<eucode>
include std/sequence.e
namespace stdseq
public function flatten(sequence s, object delim = "")
</eucode>

  removes all nesting from a sequence.

===== Parameters:
# ##s## : the sequence to flatten out.
# ##delim## : An optional delimiter to place after each flattened sub-sequence (except
the last one).

===== Returns:
A **sequence**, of atoms, all the atoms in ##s## enumerated.

===== Comments:
* If you consider a sequence as a tree, then the enumeration is performed
by left-right reading of the tree. The elements are simply read left to
right, without any care for braces.
* Empty sub-sequences are stripped out entirely.

===== Example 1:
<eucode>
s = flatten({{18, 19}, 45, {18.4, 29.3}})
-- s is {18, 19, 45, 18.4, 29.3}
</eucode>

===== Example 2:
<eucode>
s = flatten({18,{ 19, {45}}, {18.4, {}, 29.3}})
-- s is {18, 19, 45, 18.4, 29.3}
</eucode>

===== Example 3:
<eucode>
Using the delimiter argument.
s = flatten({"abc", "def", "ghi"}, ", ")
-- s is "abc, def, ghi"
</eucode>


@[:stdseq:pivot|]
==== pivot
<eucode>
include std/sequence.e
namespace stdseq
public function pivot(object data_p, object pivot_p = 0)
</eucode>

  returns a sequence of three sub-sequences. The sub-sequences contain
all the elements less than the supplied pivot value, equal to the pivot,
and greater than the pivot.

===== Parameters:
# ##data_p## : Either an atom or a list. An atom is treated as if it is one-element sequence.
# ##pivot_p## : An object. Default is zero.

===== Returns:
A **sequence**, { {less than pivot}, {equal to pivot}, {greater than pivot} }

===== Comments:
##pivot## is used as a split up a sequence relative to a specific value.

===== Example 1:
<eucode>
pivot( {7, 2, 8.5, 6, 6, -4.8, 6, 6, 3.341, -8, "text"}, 6 )
-- Ans: {{2, -4.8, 3.341, -8}, {6, 6, 6, 6}, {7, 8.5, "text"}}
pivot( {4, 1, -4, 6, -1, -7, 9, 10} )
-- Ans: {{-4, -1, -7}, {}, {4, 1, 6, 9, 10}}
pivot( 5 )
-- Ans: {{}, {}, {5}}
</eucode>

===== Example 2:
<eucode>
function quiksort(sequence s)
    if length(s) < 2 then
        return s
    end if

    sequence k = pivot(s, s[rand(length(s))])
	
    return quiksort(k[1]) & k[2] & quiksort(k[3])
end function

sequence t2 = {5,4,7,2,4,9,1,0,4,32,7,54,2,5,8,445,67}
? quiksort(t2) --> {0,1,2,2,4,4,4,5,5,7,7,8,9,32,54,67,445}
</eucode>



@[:stdseq:build_list|]
==== build_list
<eucode>
include std/sequence.e
namespace stdseq
public function build_list(sequence source, object transformer, integer singleton = 1,
        object user_data = {})
</eucode>

  implements "List Comprehension" or building a list based on the contents of another list.

===== Parameters:
# ##source## : A sequence. The list of items to base the new list upon.
# ##transformer## : One or more routine_ids. These are [[:routine_id | routine ids]]
of functions that must receive three parameters (object x, sequence i, object u)
where 'x' is an item in the ##source## list, 'i' contains the position that 'x' is
found in the ##source## list and the length of ##source##, and 'u'
is the ##user_data## value. Each transformer
must return a two-element sequence. If the first element is zero, then ##build_list## continues
on with the next transformer function for the same 'x'. If the first element is not
zero, the second element is added to the new list being built (other elements
are ignored) and build_list skips the rest of the transformers and processes
the next element in ##source##.
# ##singleton## : An integer. If zero then the transformer functions return multiple
list elements. If not zero then the transformer functions return
a single item (which might be a sequence).
# ##user_data## : Any object. This is passed unchanged to each transformer function.

===== Returns:
A **sequence**, The new list of items.

===== Comments:
* If the transformer is -1, then the source item is just copied.

===== Example 1:
<eucode>
function remitem(object x, sequence i, object q)
	if (x < q) then
		return {0} -- no output
	else
		return {1,x} -- copy 'x'
	end if
end function

sequence s
-- Remove negative elements (x < 0)
s = build_list({-3, 0, 1.1, -2, 2, 3, -1.5}, routine_id("remitem"), , 0)
-- s is {0, 1.1, 2, 3}
</eucode>


@[:stdseq:transform|]
==== transform
<eucode>
include std/sequence.e
namespace stdseq
public function transform(sequence source_data, object transformer_rids)
</eucode>

  transforms the input sequence by using one or more user-supplied transformers.

===== Parameters:
# ##source_data## : A sequence to be transformed.
# ##transformer_rids## : An object. One or more routine_ids used to transform the input.

===== Returns:
The source **sequence**, that has been transformed.

===== Comments:
* This works by calling each transformer in order, passing to it the result
of the previous transformation. Of course, the first transformer gets the
original sequence as passed to this routine.
* Each transformer routine takes one or more parameters. The first is a source sequence
to be transformed and others are any user data that may have been supplied
to the ##transform## routine.
* Each transformer routine returns a transformed sequence.
* The ##transformer_rids## parameters is either a single routine_id or a sequence
of routine_ids. In this second case, the routine_id may actually be a
multi-element sequence containing the real routine_id and some user data to
pass to the transformer routine. If there is no user data then the transformer
is called with only one parameter.

===== Example 1:
<eucode>
res = transform(" hello    ", {
    { routine_id("trim"), " ", 0 },
    routine_id("upper")
})
--> "HELLO"
</eucode>


@[:stdseq:transmute|]
==== transmute
<eucode>
include std/sequence.e
namespace stdseq
public function transmute(sequence source_data, sequence current_items, sequence new_items,
        integer start = 1, integer limit = length(source_data))
</eucode>

  replaces all instances of any element from the ##current_items## sequence that occur in the
##source_data## sequence with the corresponding item from the ##new_items## sequence.

===== Parameters:
# ##source_data## : a sequence, the data that might contain elements from ##current_items##
# ##current_items## : a sequence, the set of items to look for in ##source_data##. Matching
data is replaced with the corresponding data from ##new_items##.
# ##new_items## : a sequence, the set of replacement data for any matches found.
# ##start## : an integer, the starting point of the search. Defaults to 1.
# ##limit## : an integer, the maximum number of replacements to be made.
Defaults to ##length(source_data)##.

===== Returns:
A **sequence**, an updated version of ##source_data##.

===== Comments:
By default, this routine operates on single elements from each of the arguments.
That is to say, it scans ##source_data## for elements that match any single element
in ##current_items## and when matched, replaces that with a single element from ##new_items##.

For example, you can find all occurrances of 'h', 's', and 't' in a string and replace
them with '1', '2', and '3' respectively. \\
##transmute(SomeString, "hts", "123")## \\
However, the routine can also be used to scan for sub-sequences and/or replace
matches with sequences rather than single elements. This is done by making the first
element in ##current_items## and/or ##new_items## an empty sequence.

For example, to find all occurrances of "sh","th", and "sch" you have the
##current_items## as ##{{}, "sh", "th", "sch"}##. Note that for the purposes
of determine the corresponding replacement data, the leading empty sequence
is not counted, so in this example "th" is the second item.

<eucode>
  res = transmute("the school shoes", {{}, "sh", "th", "sch"}, "123")
  -- res becomes "2e 3ool 1oes"
</eucode>
The similar syntax is used to indicates that replacements are sequences and
not single elements.

<eucode>
  res = transmute("the school shoes", {{}, "sh", "th", "sch"}, {{}, "SH", "TH", "SCH"})
  -- res becomes "THe SCHool SHoes"
</eucode>

Using this option also allows you to remove matching data.
<eucode>
  res = transmute("the school shoes", {{}, "sh", "th", "sch"}, {{}, "", "", ""})
  -- res becomes "e ool oes"
</eucode>

Another thing to note is that when using this syntax, you can still mix together
atoms and sequences.

<eucode>
  res = transmute("the school shoes", {{}, "sh", 't', "sch"}, {{}, 'x', "TH", "SCH"})
  -- res becomes "THhe SCHool xoes"
</eucode>

===== Example 1:
<eucode>
res = transmute("John Smith enjoys uncooked apples.", "aeiouy", "YUOIEA")
-- res is "JIhn SmOth UnjIAs EncIIkUd YpplUs."
</eucode>
===== See Also:
[[:find]], [[:match]], [[:replace]], [[:mapping]]


@[:stdseq:sim_index|]
==== sim_index
<eucode>
include std/sequence.e
namespace stdseq
public function sim_index(sequence A, sequence B)
</eucode>

  calculates the similarity between two sequences.

===== Parameters:
# ##A## : A sequence.
# ##B## : A sequence.

===== Returns:
An **atom**, the closer to zero, the more the two sequences are alike.

===== Comments:
The calculation is weighted to give mismatched elements towards the front
of the sequences larger scores. This means that sequences that differ near
the begining are considered more un-alike than mismatches towards the end of
the sequences. Also, unmatched elements from the first sequence are weighted more
than unmatched elements from the second sequence.

Two identical sequences return zero. A non-zero means that they are not the same
and larger values indicate a larger differences.

===== Example 1:
<eucode>
? sim_index("sit",      "sin")      --> 0.08784
? sim_index("sit",      "sat")      --> 0.32394
? sim_index("sit",      "skit")     --> 0.34324
? sim_index("sit",      "its")      --> 0.68293
? sim_index("sit",      "kit")      --> 0.86603

? sim_index("knitting", "knitting") --> 0.00000
? sim_index("kitting",  "kitten")   --> 0.09068
? sim_index("knitting", "knotting") --> 0.27717
? sim_index("knitting", "kitten")   --> 0.35332
? sim_index("abacus","zoological")  --> 0.76304
</eucode>


@[:stdseq:SEQ_NOALT|]
==== SEQ_NOALT
<eucode>
include std/sequence.e
namespace stdseq
public constant SEQ_NOALT
</eucode>

  Indicates that [[:remove_subseq]] must not replace removed sub-sequences
with an alternative value.


@[:stdseq:remove_subseq|]
==== remove_subseq
<eucode>
include std/sequence.e
namespace stdseq
public function remove_subseq(sequence source_list, object alt_value = SEQ_NOALT)
</eucode>

  removes all sub-sequences from the supplied sequence, optionally
replacing them with a supplied alternative value. One common use
is to remove all strings from a mixed set of numbers and strings.

===== Parameters:
# ##source_list## : A sequence from which sub-sequences are removed.
# ##alt_value## : An object. The default is ##SEQ_NOALT##, which causes sub-sequences
to be physically removed, otherwise any other value will be
used to replace the sub-sequence.

===== Returns:
A **sequence**, which contains only the atoms from ##source_list## and optionally
the ##alt_value## where sub-sequences used to be.

===== Example 1:
<eucode>
sequence s = remove_subseq({4,6,"Apple",0.1, {1,2,3}, 4})
-- 's' is now {4, 6, 0.1, 4} -- length now 4
s = remove_subseq({4,6,"Apple",0.1, {1,2,3}, 4}, -1)
-- 's' is now {4, 6, -1, 0.1, -1, 4} -- length unchanged.
</eucode>



@[:stdseq:RD_INPLACE|]
==== RD_INPLACE
<eucode>
include std/sequence.e
namespace stdseq
public enum RD_INPLACE
</eucode>

Remove items while preserving the original order of the unique items.

===== See Also:
[[:remove_dups]]





@[:stdseq:RD_PRESORTED|]
==== RD_PRESORTED
<eucode>
include std/sequence.e
namespace stdseq
public enum RD_PRESORTED
</eucode>

Assume that the elements in ##source_data## are already sorted. If they
are not already sorted, this option merely removed adjacent duplicate elements.

===== See Also:
[[:remove_dups]]





@[:stdseq:RD_SORT|]
==== RD_SORT
<eucode>
include std/sequence.e
namespace stdseq
public enum RD_SORT
</eucode>

Will return the unique elements in ascending sorted order.

===== See Also:
[[:remove_dups]]





@[:stdseq:remove_dups|]
==== remove_dups
<eucode>
include std/sequence.e
namespace stdseq
public function remove_dups(sequence source_data, integer proc_option = RD_PRESORTED)
</eucode>

  removes duplicate elements.

===== Parameters:
# ##source_data## : A sequence that may contain duplicated elements
# ##proc_option## : One of ##RD_INPLACE##, ##RD_PRESORTED##, or ##RD_SORT##.
** ##RD_INPLACE## removes items while preserving the original order of the unique items.
** ##RD_PRESORTED## assumes that the elements in ##source_data## are already sorted. If they
are not already sorted, this option merely removed adjacent duplicate elements.
** ##RD_SORT## will return the unique elements in ascending sorted order.

===== Returns:
A **sequence**, that contains only the unique elements from ##source_data##.

===== Example 1:
<eucode>
sequence s = { 4,7,9,7,2,5,5,9,0,4,4,5,6,5}
? remove_dups(s, RD_INPLACE) --> {4,7,9,2,5,0,6}
? remove_dups(s, RD_SORT) --> {0,2,4,5,6,7,9}
? remove_dups(s, RD_PRESORTED) --> {4,7,9,7,2,5,9,0,4,5,6,5}
? remove_dups(sort(s), RD_PRESORTED) --> {0,2,4,5,6,7,9}
</eucode>



@[:stdseq:COMBINE_UNSORTED|]
==== COMBINE_UNSORTED
<eucode>
include std/sequence.e
namespace stdseq
public enum COMBINE_UNSORTED
</eucode>





@[:stdseq:COMBINE_SORTED|]
==== COMBINE_SORTED
<eucode>
include std/sequence.e
namespace stdseq
public enum COMBINE_SORTED
</eucode>





@[:stdseq:combine|]
==== combine
<eucode>
include std/sequence.e
namespace stdseq
public function combine(sequence source_data, integer proc_option = COMBINE_SORTED)
</eucode>

  combines all the sub-sequences into a single, optionally sorted, list.

===== Parameters:
# ##source_data## : A sequence that contains sub-sequences to be combined.
# ##proc_option## : An integer; ##COMBINE_UNSORTED## to return a non-sorted list and
##COMBINE_SORTED## (the default) to return a sorted list.

===== Returns:
A **sequence**, that contains all the elements from all the first-level of
sub-sequences from ##source_data##.

===== Comments:
The elements in the sub-sequences do not have to be pre-sorted.

Only one level of sub-sequence is combined.

===== Example 1:
<eucode>
sequence s = { {4,7,9}, {7,2,5,9}, {0,4}, {5}, {6,5}}
combine(s, COMBINE_SORTED)   --> {0,2,4,4,5,5,5,6,7,7,9,9}
combine(s, COMBINE_UNSORTED) --> {4,7,9,7,2,5,9,0,4,5,6,5}
</eucode>

===== Example 2:
<eucode>
sequence s = { {"cat", "dog"}, {"fish", "whale"}, {"wolf"}, {"snail", "worm"}}
combine(s)                   --> {"cat","dog","fish","snail","whale","wolf","worm"}
combine(s, COMBINE_UNSORTED) --> {"cat","dog","fish","whale","wolf","snail","worm"}
</eucode>

===== Example 3:
<eucode>
sequence s = { "cat", "dog","fish", "whale", "wolf", "snail", "worm"}
combine(s)                   --> "aaacdeffghhiilllmnooorsstwww"
combine(s, COMBINE_UNSORTED) --> "catdogfishwhalewolfsnailworm"
</eucode>



@[:stdseq:minsize|]
==== minsize
<eucode>
include std/sequence.e
namespace stdseq
public function minsize(object source_data,
        integer min_size = floor(length(source_data)* 1.5),
        object new_data = 0)
</eucode>

  ensures that the supplied sequence is at least the supplied minimum length.

===== Parameters:
# ##source_data## : An object that might need extending.
# ##min_size##: An integer. The minimum length that ##source_data## must be.
The default is to increase the length of ##source_data# by 50%.
# ##new_data##: An object. This used to when ##source_data## needs to be extended,
in which case it is appended as many times as required to make the length
equal to ##min_size##. The default is 0.

===== Returns:
A **sequence**. The padded sequence, unchanged if its size was not less
than ##min_size## on input.

===== Comments:
Pads ##source_data## to the right until its length reaches ##min_size##
using ##new_data## as filler.

===== Example 1:
<eucode>
sequence s
s = minsize({4,3,6,2,7,1,2}, 10, -1) --> {4,3,6,2,7,1,2,-1,-1,-1}
s = minsize({4,3,6,2,7,1,2},  5, -1) --> {4,3,6,2,7,1,2}
</eucode>




!!CONTEXT:../include/std/serialize.e
!!namespace:serialize
%%output = std_serialize

== Serialization of Euphoria Objects

<<LEVELTOC level=2 depth=4>>


=== Routines


@[:serialize:deserialize|]
==== deserialize
<eucode>
include std/serialize.e
namespace serialize
public function deserialize(object sdata, integer pos = 1)
</eucode>

  converts a serialized object in to a standard Euphoria object.

===== Parameters:
# ##sdata## : either a sequence containing one or more concatenated serialized objects or
an open file handle. If this is a file handle, the current position in the
file is assumed to be at a serialized object in the file.
# ##pos## : optional index into ##sdata##. If omitted 1 is assumed. The index must
point to the start of a serialized object.

===== Returns:
The return **value**, depends on the input type.
* If ##sdata## is a file handle then
this function returns a Euphoria object that had been stored in the file, and
moves the current file to the first byte after the stored object.
* If ##sdata## is a sequence then this returns a two-element sequence.
The //first// element is the Euphoria object that corresponds to the serialized
object that begins at index ##pos##, and the //second// element is the index
position in the input parameter just after the serialized object.


===== Comments:
A serialized object is one that has been returned from the [[:serialize]] function.

===== Example 1:
<eucode>
 sequence objcache
 objcache = serialize(FirstName) &
            serialize(LastName) &
            serialize(PhoneNumber) &
            serialize(Address)

 sequence res
 integer pos = 1
 res = deserialize( objcache , pos)
 FirstName = res[1] pos = res[2]
 res = deserialize( objcache , pos)
 LastName = res[1] pos = res[2]
 res = deserialize( objcache , pos)
 PhoneNumber = res[1] pos = res[2]
 res = deserialize( objcache , pos)
 Address = res[1] pos = res[2]
</eucode>

===== Example 2:
<eucode>
 sequence objcache
 objcache = serialize({FirstName,
                      LastName,
                      PhoneNumber,
                      Address})

 sequence res
 res = deserialize( objcache )
 FirstName = res[1][1]
 LastName = res[1][2]
 PhoneNumber = res[1][3]
 Address = res[1][4]
</eucode>

===== Example 3:
<eucode>
 integer fh
 fh = open("cust.dat", "wb")
 puts(fh, serialize(FirstName))
 puts(fh, serialize(LastName))
 puts(fh, serialize(PhoneNumber))
 puts(fh, serialize(Address))
 close(fh)

 fh = open("cust.dat", "rb")
 FirstName = deserialize(fh)
 LastName = deserialize(fh)
 PhoneNumber = deserialize(fh)
 Address = deserialize(fh)
 close(fh)
</eucode>

===== Example 4:
<eucode>
 integer fh
 fh = open("cust.dat", "wb")
 puts(fh, serialize({FirstName,
                     LastName,
                     PhoneNumber,
                     Address}))
 close(fh)

 sequence res
 fh = open("cust.dat", "rb")
 res = deserialize(fh)
 close(fh)
 FirstName = res[1]
 LastName = res[2]
 PhoneNumber = res[3]
 Address = res[4]
</eucode>



@[:serialize:serialize|]
==== serialize
<eucode>
include std/serialize.e
namespace serialize
public function serialize(object x)
</eucode>

  converts a standard Euphoria object in to a serialized version of it.

===== Parameters:
# ##euobj## : any Euphoria object.

===== Returns:
A **sequence**, this is the serialized version of the input object.

===== Comments:
A serialized object is one that has been converted to a set of byte values. This
can then by written directly out to a file for storage.

You can use the [[:deserialize]] function to convert it back into a standard
Euphoria object.

===== Example 1:
<eucode>
 integer fh
 fh = open("cust.dat", "wb")
 puts(fh, serialize(FirstName))
 puts(fh, serialize(LastName))
 puts(fh, serialize(PhoneNumber))
 puts(fh, serialize(Address))
 close(fh)

 fh = open("cust.dat", "rb")
 FirstName = deserialize(fh)
 LastName = deserialize(fh)
 PhoneNumber = deserialize(fh)
 Address = deserialize(fh)
 close(fh)
</eucode>

===== Example 2:
<eucode>
 integer fh
 fh = open("cust.dat", "wb")
 puts(fh, serialize({FirstName,
                     LastName,
                     PhoneNumber,
                     Address}))
 close(fh)

 sequence res
 fh = open("cust.dat", "rb")
 res = deserialize(fh)
 close(fh)
 FirstName = res[1]
 LastName = res[2]
 PhoneNumber = res[3]
 Address = res[4]
</eucode>



@[:serialize:dump|]
==== dump
<eucode>
include std/serialize.e
namespace serialize
public function dump(sequence data, sequence filename)
</eucode>

  saves a Euphoria object to disk in a binary format.

===== Parameters:
# ##data## : any Euphoria object.
# ##filename## : the name of the file to save it to.

===== Returns:
An **integer**, 0 if the function fails, otherwise the number of bytes in the
created file.

===== Comments:
If the named file does not exist it is created, otherwise it is overwritten.

You can use the [[:load]] function to recover the data from the file.

===== Example 1:
<eucode>
include std/serialize.e
integer size = dump(myData, theFileName) 
if size = 0 then
    puts(1, "Failed to save data to file\n")
else
    printf(1, "Saved file is %d bytes long\n", size)
end if
</eucode>



@[:serialize:load|]
==== load
<eucode>
include std/serialize.e
namespace serialize
public function load(sequence filename)
</eucode>

  restores a Euphoria object that has been saved to disk by [[:dump]].

===== Parameters:
# ##filename## : the name of the file to restore it from.

===== Returns:
A **sequence**, the first element is the result code. If the result code is 0
then it means that the function failed, otherwise the restored data is in the
second element.

===== Comments:
This is used to load back data from a file created by the [[:dump]]
function.

===== Example 1:
<eucode>
include std/serialize.e
sequence mydata = load(theFileName) 
if mydata[1] = 0 then
    puts(1, "Failed to load data from file\n")
else
    mydata = mydata[2] -- Restored data is in second element.
end if
</eucode>




!!CONTEXT:../include/std/sort.e
!!namespace:stdsort
%%output = std_sort

== Sorting

<<LEVELTOC level=2 depth=4>>



=== Constants



@[:stdsort:ASCENDING|]
==== ASCENDING
<eucode>
include std/sort.e
namespace stdsort
public constant ASCENDING
</eucode>

Ascending sort order, always the default.

When a sequence is sorted in ##ASCENDING## order, its first element
is the smallest as per the sort order and its last element is the
largest




@[:stdsort:NORMAL_ORDER|]
==== NORMAL_ORDER
<eucode>
include std/sort.e
namespace stdsort
public constant NORMAL_ORDER
</eucode>

 The normal sort order used by the custom comparison routine.



@[:stdsort:DESCENDING|]
==== DESCENDING
<eucode>
include std/sort.e
namespace stdsort
public constant DESCENDING
</eucode>

Descending sort order, which is the reverse of ##ASCENDING##.




@[:stdsort:REVERSE_ORDER|]
==== REVERSE_ORDER
<eucode>
include std/sort.e
namespace stdsort
public constant REVERSE_ORDER
</eucode>

 Reverses the sense of the order returned by a custom comparison routine.



=== Routines



@[:stdsort:sort|]
==== sort
<eucode>
include std/sort.e
namespace stdsort
public function sort(sequence x, integer order = ASCENDING)
</eucode>

  sorts the elements of a sequence into ascending order.

===== Parameters:
# ##x## : The sequence to be sorted.
# ##order## : the sort order. Default is ##ASCENDING##.

===== Returns:
A **sequence**, a copy of the original sequence in ascending order

===== Comments:

The elements can be atoms or sequences.

The standard ##compare##
routine is used to compare elements. This means that "##y## is greater than ##x##" is defined by ##compare(y, x)=1##.

This function uses the "Shell" sort algorithm. This sort is not "stable" which means elements that are considered equal might
change position relative to each other.

===== Example 1:
<eucode>
constant student_ages = {18,21,16,23,17,16,20,20,19}
sequence sorted_ages
sorted_ages = sort( student_ages )
-- result is {16,16,17,18,19,20,20,21,23}
</eucode>

===== See Also:
[[:compare]], [[:custom_sort]]


@[:stdsort:custom_sort|]
==== custom_sort
<eucode>
include std/sort.e
namespace stdsort
public function custom_sort(integer custom_compare, sequence x, object data = {},
        integer order = NORMAL_ORDER)
</eucode>

  sorts the elements of a sequence according to a user-defined order.

===== Parameters:
# ##custom_compare## : an integer, the routine-id of the user defined routine that compares two items which appear in the sequence to sort.
# ##x## : the sequence of items to be sorted.
# ##data## : an object, either ##{}## (no custom data, the default), an atom or a non-empty sequence.
# ##order## : an integer, either ##NORMAL_ORDER## (the default) or ##REVERSE_ORDER##.

===== Returns:
A **sequence**, a copy of the original sequence in sorted order

===== Errors:
If the user defined routine does not return according to the specifications in the
//Comments// section below, an error will occur.

===== Comments:
* If some user data is being provided, that data must be either an atom or
a sequence with at least one element. **NOTE** only the first element is passed
to the user defined comparison routine, any other elements are just ignored.
The user data is not used or inspected it in any way other than passing it
to the user defined routine.

* The user defined routine must return an integer //comparison result//
** a **negative** value if object A must appear before object B
** a **positive** value if object B must appear before object A
** 0 if the order does not matter
>
**NOTE:** The meaning of the value returned by the user-defined routine is reversed
when ##order = REVERSE_ORDER##.
The default is ##order = NORMAL_ORDER##, which sorts in order returned by the
custom comparison routine.
<

* When no user data is provided, the user defined routine must accept two
objects (A, B) and return just the //comparison result//.

* When some user data is provided, the user defined routine must take three
objects (A, B , data). It must return either...
** an integer, which is a //comparison result//
** a two-element sequence, in which the first element is a //comparison result//
and the second element is the updated user data that is to be used for the next call
to the user defined routine.

* The elements of ##x## can be atoms or sequences. Each time that the
sort needs to compare two items in the sequence, it calls
the user-defined function to determine the order.

* This function uses the "Shell" sort algorithm. This sort is not "stable"
which means the elements that are considered equal might change position relative to
each other.

===== Example 1:
<eucode>
constant students = {{"Anne",18},   {"Bob",21},
                     {"Chris",16},  {"Diane",23},
                     {"Eddy",17},   {"Freya",16},
                     {"George",20}, {"Heidi",20},
                     {"Ian",19}}
sequence sorted_byage
function byage(object a, object b)
 ----- If the ages are the same, compare the names otherwise just compare ages.
    if equal(a[2], b[2]) then
        return compare(upper(a[1]), upper(b[1]))
    end if
    return compare(a[2], b[2])
end function

sorted_byage = custom_sort( routine_id("byage"), students )
-- result is {{"Chris",16}, {"Freya",16},
--            {"Eddy",17},  {"Anne",18},
--            {"Ian",19},   {"George",20},
--            {"Heidi",20}, {"Bob",21},
--            {"Diane",23}}

sorted_byage = custom_sort( routine_id("byage"), students,, REVERSE_ORDER )
-- result is {{"Diane",23}, {"Bob",21},
--            {"Heidi",20}, {"George",20},
--            {"Ian",19},   {"Anne",18},
--            {"Eddy",17},  {"Freya",16},
--            {"Chris",16}}
--
</eucode>

===== Example 2:
<eucode>
constant students = {{"Anne","Baxter",18}, {"Bob","Palmer",21},
                     {"Chris","du Pont",16},{"Diane","Fry",23},
                     {"Eddy","Ammon",17},{"Freya","Brash",16},
                     {"George","Gungle",20},{"Heidi","Smith",20},
                     {"Ian","Sidebottom",19}}
sequence sorted
function colsort(object a, object b, sequence cols)
    integer sign
    for i = 1 to length(cols) do
        if cols[i] < 0 then
            sign = -1
            cols[i] = -cols[i]
        else
            sign = 1
        end if
        if not equal(a[cols[i]], b[cols[i]]) then
            return sign * compare(upper(a[cols[i]]), upper(b[cols[i]]))
        end if
    end for

    return 0
end function

-- Order is age:descending, Surname, Given Name
sequence column_order = {-3,2,1}
sorted = custom_sort( routine_id("colsort"), students, {column_order} )
-- result is
{
    {"Diane","Fry",23},
    {"Bob","Palmer",21},
    {"George","Gungle",20},
    {"Heidi","Smith",20},
    {"Ian","Sidebottom",19},
    {"Anne", "Baxter", 18 },
    {"Eddy","Ammon",17},
    {"Freya","Brash",16},
    {"Chris","du Pont",16}
}

sorted = custom_sort( routine_id("colsort"), students, {column_order}, REVERSE_ORDER )
-- result is
{
    {"Chris","du Pont",16},
    {"Freya","Brash",16},
    {"Eddy","Ammon",17},
    {"Anne", "Baxter", 18 },
    {"Ian","Sidebottom",19},
    {"Heidi","Smith",20},
    {"George","Gungle",20},
    {"Bob","Palmer",21},
    {"Diane","Fry",23}
}
</eucode>
===== See Also:
[[:compare]], [[:sort]]


@[:stdsort:sort_columns|]
==== sort_columns
<eucode>
include std/sort.e
namespace stdsort
public function sort_columns(sequence x, sequence column_list)
</eucode>

  sorts the rows in a sequence according to a user-defined
column order.

===== Parameters:
# ##x## : a sequence, holding the sequences to be sorted.
# ##column_list## : a list of columns indexes ##x## is to be sorted by.

===== Returns:
A **sequence**, a copy of the original sequence in sorted order.

===== Comments:

##x## must be a sequence of sequences.

A non-existent column is treated as coming before an existing column. This
allows sorting of records that are shorter than the columns in the
column list.

By default
columns are sorted in ascending order. To sort in descending
order make the column number negative.

This function uses the "Shell" sort algorithm.
This sort is not "stable" which means elements that are considered equal might
change position relative to each other.

===== Example 1:
<eucode>
sequence dirlist
dirlist = dir("c:\\temp")
sequence sorted
-- Order is Size:descending, Name
sorted = sort_columns( dirlist, {-D_SIZE, D_NAME} )
</eucode>

===== See Also:
[[:compare]], [[:sort]]


@[:stdsort:merge|]
==== merge
<eucode>
include std/sort.e
namespace stdsort
public function merge(sequence a, sequence b, integer compfunc = - 1, object userdata = "")
</eucode>

  merges two pre-sorted sequences into a single sequence.

===== Parameters:
# ##a## : a sequence, holding pre-sorted data.
# ##b## : a sequence, holding pre-sorted data.
# ##compfunc## : an integer, either -1 or the routine id of a user-defined
comparision function.

===== Returns:
A **sequence**, consisting of ##a## and ##b## merged together.

===== Comments:
* If ##a## or ##b## is not already sorted, the resulting sequence might not
be sorted either.
* The input sequences do not have to be the same size.
* The user-defined comparision function must accept two objects and return an
integer. It returns -1 if the first object must appear before the second one,
and 1 if the first object must after before the second one, and 0 if the order
doesn't matter.

===== Example 1:
<eucode>
sequence X,Y
X = sort( {5,3,7,1,9,0} ) --> {0,1,3,5,7,9}
Y = sort( {6,8,10,2} ) --> {2,6,8,10}
? merge(X,Y) --> {0,1,2,3,5,6,7,8,9,10}
</eucode>

===== See Also:
[[:compare]], [[:sort]]


@[:stdsort:insertion_sort|]
==== insertion_sort
<eucode>
include std/sort.e
namespace stdsort
public function insertion_sort(sequence s, object e = "", integer compfunc = - 1,
        object userdata = "")
</eucode>

  sorts a sequence and optionally another object together.

===== Parameters:
# ##s## : a sequence, holding data to be sorted.
# ##e## : an object. If this is an atom, it is sorted in with ##s##. If this
is a non-empty sequence then ##s## and ##e## are both sorted independantly using
this ##insertion_sort## function and then the results are merged and returned.
# ##compfunc## : an integer, either -1 or the routine id of a user-defined
comparision function.

===== Returns:
A **sequence**, consisting of ##s## and ##e## sorted together.

===== Comments:
* This routine is usually a lot faster than the standard sort when ##s## and ##e##
are (mostly) sorted before calling the function. For example, you can use
this routine to quickly add to a sorted list.
* The input sequences do not have to be the same size.
* The user-defined comparision function must accept two objects and return an
integer. It returns -1 if the first object must appear before the second one,
and 1 if the first object must after before the second one, and 0 if the order
does not matter.

===== Example 1:
<eucode>
sequence X = {}
while true do
   newdata = get_data()
   if compare(-1, newdata) then
      exit
   end if
   X = insertion_sort(X, newdata)
   process(new_data)
end while
</eucode>

===== See Also:
[[:compare]], [[:sort]], [[:merge]]



!!CONTEXT:../include/std/locale.e
!!namespace:locale
%%output = std_locale

==  Locale Routines

<<LEVELTOC level=2 depth=4>>


=== Message Translation Functions



@[:locale:set_lang_path|]
==== set_lang_path
<eucode>
include std/locale.e
namespace locale
public procedure set_lang_path(object pp)
</eucode>

  sets the language path.

===== Parameters:
# ##pp## : an object, either an actual path or an atom.

===== Comments:
When the language path is not set, and it is unset by default, [[:set]] does not load any language file.

===== See Also:
[[:set]]


@[:locale:get_lang_path|]
==== get_lang_path
<eucode>
include std/locale.e
namespace locale
public function get_lang_path()
</eucode>

  gets the language path.

===== Returns:
An **object**, the current language path.

===== See Also:
[[:get_lang_path]]


@[:locale:lang_load|]
==== lang_load
<eucode>
include std/locale.e
namespace locale
public function lang_load(sequence filename)
</eucode>

  loads a language file.

===== Parameters:
# ##filename## : a sequence, the name of the file to load. If no file
extension is supplied, then ##".lng"## is used.

===== Returns:
A language **map**, if successful. This is to be used when calling [[:translate]].

If the load fails it returns a zero.

===== Comments:
The language file must be made of lines which are either comments, empty lines
or translations. Note that leading whitespace is ignored on all lines except
continuation lines.

* //Comments// are lines that begin with a ##~### character and extend to the end of the line.
* //Empty Lines// are ignored.
* //Translations// have two forms.

{{{
keyword translation_text
}}}
In which the 'keyword' is a word that must not have any spaces in it.
{{{
keyphrase = translation_text
}}}
In which the 'keyphrase' is anything up to the first ##'='## symbol.

It is possible to have the translation text span multiple lines. You do this by
having ##'&'## as the last character of the line. These are placed by newline characters
when loading.

===== Example 1:
{{{
# Example translation file
#


hello Hola
world Mundo
greeting %s, %s!

help text = &
This is an example of some &
translation text that spans &
multiple lines.

# End of example PO #2
}}}

===== See Also:
[[:translate]]


@[:locale:set_def_lang|]
==== set_def_lang
<eucode>
include std/locale.e
namespace locale
public procedure set_def_lang(object langmap)
</eucode>

  sets the default language (translation) map.

===== Parameters:
# ##langmap## : A value returned by [[:lang_load]], or zero to remove any default map.

===== Example 1:
<eucode>
  set_def_lang( lang_load("appmsgs") )
</eucode>


@[:locale:get_def_lang|]
==== get_def_lang
<eucode>
include std/locale.e
namespace locale
public function get_def_lang()
</eucode>

  gets the default language (translation) map.

===== Parameters:
none.

===== Returns:
An **object**, a language map, or zero if there is no default language map yet.

===== Example 1:
<eucode>
  object langmap = get_def_lang()
</eucode>


@[:locale:translate|]
==== translate
<eucode>
include std/locale.e
namespace locale
public function translate(sequence word, object langmap = 0, object defval = "",
        integer mode = 0)
</eucode>

  translates a word, using the current language file.

===== Parameters:
# ##word## : a sequence, the word to translate.
# ##langmap## : Either a value returned by [[:lang_load]] or zero to use the default language map
# ##defval## : a object. The value to return if the word cannot be translated.
Default is "". If ##defval## is ##PINF## then the ##word## is returned
if it can not be translated.
# ##mode## : an integer. If zero (the default) it uses ##word## as the keyword and returns
the translation text. If not zero it uses ##word##
as the translation and returns the keyword.

===== Returns:
A **sequence**, the value associated with ##word##, or ##defval## if there
is no association.

===== Example 1:
<eucode>
sequence newword
newword = translate(msgtext)
if length(msgtext) = 0 then
   error_message(msgtext)
else
   error_message(newword)
end if
</eucode>

===== Example 2:
<eucode>
error_message(translate(msgtext, , PINF))
</eucode>

===== See Also:
[[:set]], [[:lang_load]]


@[:locale:trsprintf|]
==== trsprintf
<eucode>
include std/locale.e
namespace locale
public function trsprintf(sequence fmt, sequence data, object langmap = 0)
</eucode>

  returns a formatted string with automatic translation performed on the parameters.

===== Parameters:
# ##fmt## : A sequence. Contains the formatting string. See [[:printf]] for details.
# ##data## : A sequence. Contains the data that goes into the formatted result. see [[:printf]] for details.
# ##langmap## : An object. Either 0 (the default) to use the default language maps, or
the result returned from [[:lang_load]] to specify a particular
language map.

===== Returns:
A **sequence**, the formatted result.

===== Comments:
This works very much like the [[:sprintf]] function. The difference is that the ##fmt## sequence
and sequences contained in the ##data## parameter are [[:translate | translated ]] before
passing them to [[:sprintf]]. If an item has no translation, it remains unchanged.

Further more, after the translation pass, if the result text begins with {{{"__"}}},
the {{{"__"}}} is removed.
This function can be used when you do not want an item to be translated.

===== Example 1:
<eucode>
-- Assuming a language has been loaded and
--   "greeting" translates as '%s %s, %s'
--   "hello"  translates as "G'day"
--   "how are you today" translates as "How's the family?"
sequence UserName = "Bob"
sequence result = trsprintf( "greeting", {"hello", "__" & UserName, "how are you today"})
   --> "G'day Bob, How's the family?"
</eucode>



=== Time and Number Translation


@[:locale:set|]
==== set
<eucode>
include std/locale.e
namespace locale
public function set(sequence new_locale)
</eucode>

  sets the computer locale, and possibly loads an appropriate translation file.

===== Parameters:
# ##new_locale## : a sequence representing a new locale.

===== Returns:
An **integer**, either 0 on failure or 1 on success.

===== Comments:
Locale strings have the following format: ##xx_YY## or ##xx_YY.xyz## .
The ##xx## part refers to a culture, or main language or script. For instance, ##"en"## refers to
English, ##"de"## refers to German, and so on. For some languages, a script may be specified,
like ##"mn_Cyrl_MN"## (Mongolian in cyrillic transcription).

The ##YY## part refers to a subculture, or variant, of the main language. For instance, ##"fr_FR"##
refers to metropolitan France, while ##"fr_BE"## refers to the variant spoken in Wallonie, the
French speaking region of Belgium.

The optional ##.xyz## part specifies an encoding, like ##.utf8## or ##.1252## . This is required in some cases.


@[:locale:get|]
==== get
<eucode>
include std/locale.e
namespace locale
public function get()
</eucode>

  gets the current locale string.

===== Returns:
A **sequence**, a locale string.

===== See Also:
[[:set]]


@[:locale:money|]
==== money
<eucode>
include std/locale.e
namespace locale
public function money(object amount)
</eucode>

  converts an amount of currency into a string representing that amount.

===== Parameters:
# ##amount## : an atom, the value to write out.

===== Returns:
A **sequence**, a string that writes out ##amount## of current currency.

===== Example 1:
<eucode>
-- Assuming an en_US locale
money(1020.5) -- returns"$1,020.50"
</eucode>

===== See Also:
[[:set]], [[:number]]



@[:locale:number|]
==== number
<eucode>
include std/locale.e
namespace locale
public function number(object num)
</eucode>

  converts a number into a string representing that number.

===== Parameters:
# ##num## : an atom, the value to write out.

===== Returns:
A **sequence**, a string that writes out ##num##.

===== Example 1:
<eucode>
-- Assuming an en_US locale
number(1020.5) -- returns "1,020.50"
</eucode>

===== See Also:
[[:set]], [[:money]]


@[:locale:datetime|]
==== datetime
<eucode>
include std/locale.e
namespace locale
public function datetime(sequence fmt, datetime :datetime dtm)
</eucode>

  formats a date according to current locale.

===== Parameters:
# ##fmt## : A format string, as described in datetime:[[:format]]
# ##dtm## : the datetime to write out.

===== Returns:
A **sequence**, representing the formatted date.

===== Example 1:
<eucode>
include std/datetime.e

datetime("Today is a %A", datetime:now())
</eucode>

===== See Also:
[[:datetime:format]]



@[:locale:get_text|]
==== get_text
<eucode>
include std/locale.e
namespace locale
public function get_text(integer MsgNum, sequence LocalQuals = {}, sequence DBBase = "teksto")
</eucode>

  gets the text associated with the message number in the requested locale.

===== Parameters:
# ##MsgNum## : An integer. The message number whose text you are trying to get.
# ##LocalQuals## : A sequence. Zero or more locale codes. Default is ##{}##.
# ##DBBase##: A sequence. The base name for the database files containing the
locale text strings. The default is ##"teksto"##.

===== Returns:
A string **sequence**, the text associated with the message number and locale.\\
The **integer** zero, if associated text can not be found for any reason.

===== Comments:
* This first scans the database or databases linked to the locale codes supplied.
* The database name for each locale takes the format of ##"<DBBase>_<Locale>.edb"##
so if the default ##DBBase## is used, and the locales supplied are ##{"enus", "enau"}##
the databases scanned are ##"teksto_enus.edb"## and ##"teksto_enau.edb"##.
The database table name searched is ##"1"## with the key being the message number,
and the text is the record data.
* If the message is not found in these databases (or the databases do not exist)
a database called ##"<DBBase>.edb"## is searched. Again the table name is ##"1"## but
it first looks for keys with the format ##{<locale>,msgnum}## and failing that it
looks for keys in the format ##{"", msgnum}##, and if that fails it looks for a
key of just the ##msgnum##.




!!CONTEXT:../include/std/localeconv.e
!!namespace:localconv
%%output = std_localeconv

==  Locale Names

<<LEVELTOC level=2 depth=4>>


=== Constants
//Windows// locale names~:

| af-ZA|  sq-AL|  gsw-FR|  am-ET|  ar-DZ|  ar-BH|  ar-EG|  ar-IQ|
| ar-JO|  ar-KW|  ar-LB|  ar-LY|  ar-MA|  ar-OM|  ar-QA|  ar-SA|
| ar-SY|  ar-TN|  ar-AE|  ar-YE|  hy-AM|  as-IN|  az-Cyrl-AZ|  az-Latn-AZ|
| ba-RU|  eu-ES|  be-BY|  bn-IN|  bs-Cyrl-BA|  bs-Latn-BA|  br-FR|  bg-BG|
| ca-ES|  zh-HK|  zh-MO|  zh-CN|  zh-SG|  zh-TW|  co-FR|  hr-BA|
| hr-HR|  cs-CZ|  da-DK|  prs-AF|  dv-MV|  nl-BE|  nl-NL|  en-AU|
| en-BZ|  en-CA|  en-029|  en-IN|  en-IE|  en-JM|  en-MY|  en-NZ|
| en-PH|  en-SG|  en-ZA|  en-TT|  en-GB|  en-US|  en-ZW|  et-EE|
| fo-FO|  fil-PH|  fi-FI|  fr-BE|  fr-CA|  fr-FR|  fr-LU|  fr-MC|
| fr-CH|  fy-NL|  gl-ES|  ka-GE|  de-AT|  de-DE|  de-LI|  de-LU|
| de-CH|  el-GR|  kl-GL|  gu-IN|  ha-Latn-NG|  he-IL| hi-IN|  hu-HU|
| is-IS|  ig-NG|  id-ID|  iu-Latn-CA| iu-Cans-CA| ga-IE|  it-IT|  it-CH|
| ja-JP|  kn-IN|  kk-KZ|  kh-KH|  qut-GT| rw-RW|  kok-IN|  ko-KR|
| ky-KG|  lo-LA|  lv-LV|  lt-LT|  dsb-DE| lb-LU|  mk-MK|  ms-BN|
| ms-MY|  ml-IN|  mt-MT|  mi-NZ|  arn-CL| mr-IN|  moh-CA|  mn-Cyrl-MN|
| mn-Mong-CN| ne-IN| ne-NP|  nb-NO|  nn-NO|  oc-FR|  or-IN|  ps-AF|
| fa-IR|  pl-PL|  pt-BR|  pt-PT|  pa-IN|  quz-BO|  quz-EC|  quz-PE|
| ro-RO|  rm-CH|  ru-RU|  smn-FI|  smj-NO|  smj-SE|  se-FI|  se-NO|
| se-SE|  sms-FI|  sma-NO|  sma-SE|  sa-IN|  sr-Cyrl-BA|  sr-Latn-BA|  sr-Cyrl-CS|
| sr-Latn-CS| ns-ZA| tn-ZA|  si-LK|  sk-SK|  sl-SI|  es-AR|  es-BO|
| es-CL|  es-CO| es-CR|  es-DO|  es-EC|  es-SV|  es-GT|  es-HN|
| es-MX|  es-NI|  es-PA|  es-PY|  es-PE|  es-PR|  es-ES|  es-ES_tradnl|
| es-US|  es-UY|  es-VE|  sw-KE|  sv-FI|  sv-SE|  syr-SY|  tg-Cyrl-TJ|
| tmz-Latn-DZ| ta-IN| tt-RU|  te-IN|  th-TH|  bo-BT|  bo-CN|  tr-TR|
| tk-TM|  ug-CN|  uk-UA|  wen-DE|  tr-IN|  ur-PK|  uz-Cyrl-UZ|  uz-Latn-UZ|
| vi-VN|  cy-GB|  wo-SN|  xh-ZA|  sah-RU|  ii-CN|  yo-NG|  zu-ZA|


@[:localconv:w32_names|]
==== w32_names
<eucode>
include std/localeconv.e
namespace localconv
public constant w32_names
</eucode>





@[:localconv:w32_name_canonical|]
==== w32_name_canonical
<eucode>
include std/localeconv.e
namespace localconv
public constant w32_name_canonical
</eucode>

  Canonical locale names for //Windows//:

| Afrikaans_South Africa|  Afrikaans_South Africa| Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Afrikaans_South Africa|  Afrikaans_South Africa|  Afrikaans_South Africa|
| Basque_Spain|  Basque_Spain|  Belarusian_Belarus|
| Belarusian_Belarus|  Belarusian_Belarus|  Belarusian_Belarus|
| Belarusian_Belarus|  Belarusian_Belarus|  Catalan_Spain|
| Catalan_Spain|  Catalan_Spain|  Catalan_Spain|
| Catalan_Spain|  Catalan_Spain|  Catalan_Spain|
| Catalan_Spain| Catalan_Spain|  Catalan_Spain|
| Danish_Denmark| Danish_Denmark|  Danish_Denmark|
| Danish_Denmark|  Danish_Denmark|  English_Australia|
| English_United States|  English_United States|  English_United States|
| English_United States|  English_United States|  English_United States|
| English_United States|  English_United States|  English_United States|
| English_United States|  English_United States|  English_United States|
| English_United States|  English_United States|  English_United States|
| English_United States|  English_United States|  English_United States|
| Finnish_Finland|  French_France|  French_France|
| French_France|  French_France|  French_France|
| French_France|  French_France|  French_France|
| French_France|  French_France|  French_France|
| French_France|  French_France|  French_France|
| French_France|  French_France|  French_France|
| French_France|  French_France|  French_France|
| Hungarian_Hungary|  Hungarian_Hungary|  Hungarian_Hungary|
| Hungarian_Hungary|  Hungarian_Hungary|  Hungarian_Hungary|
| Hungarian_Hungary|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Italian_Italy|  Italian_Italy|
| Italian_Italy|  Romanian_Romania|  Romanian_Romania|
| Russian_Russia|  Russian_Russia|  Russian_Russia|
| Russian_Russia|  Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia|
| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia|
| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia|
| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia|
| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia| Serbian (Cyrillic)_Serbia|
| Serbian (Cyrillic)_Serbia| Slovak_Slovakia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Estonian_Estonia|
| Estonian_Estonia|  Estonian_Estonia|  Swedish_Sweden|
| Swedish_Sweden|  Swedish_Sweden|  Swedish_Sweden|
| Swedish_Sweden|  Swedish_Sweden|  Swedish_Sweden|
| Swedish_Sweden|  Swedish_Sweden|  Swedish_Sweden|
| Swedish_Sweden|  Swedish_Sweden|  Swedish_Sweden|
| Swedish_Sweden|  Swedish_Sweden|  Ukrainian_Ukraine|
| Ukrainian_Ukraine|  Ukrainian_Ukraine|  Ukrainian_Ukraine|
| Ukrainian_Ukraine|  Ukrainian_Ukraine|  Ukrainian_Ukraine|
| Ukrainian_Ukraine|  Ukrainian_Ukraine|  Ukrainian_Ukraine|
| Ukrainian_Ukraine|  Ukrainian_Ukraine|  Ukrainian_Ukraine|
| Ukrainian_Ukraine|                            |                     |


@[:localconv:posix_names|]
==== posix_names
<eucode>
include std/localeconv.e
namespace localconv
public constant posix_names
</eucode>

  POSIX locale names~:

| af_ZA|  sq_AL|  gsw_FR|   am_ET|  ar_DZ      | ar_BH      | ar_EG      | ar_IQ|
| ar_JO|  ar_KW|  ar_LB| ar_LY|  ar_MA|  ar_OM|  ar_QA|  ar_SA|
| ar_SY|  ar_TN|  ar_AE| ar_YE|  hy_AM|  as_IN|  az_Cyrl_AZ|  az_Latn_AZ|
| ba_RU|  eu_ES|  be_BY|  bn_IN|  bs_Cyrl_BA|  bs_Latn_BA|  br_FR|  bg_BG|
| ca_ES|  zh_HK|  zh_MO|  zh_CN|  zh_SG|  zh_TW|  co_FR|  hr_BA|
| hr_HR|  cs_CZ|  da_DK|  prs_AF|  dv_MV|  nl_BE|  nl_NL|  en_AU|
| en_BZ|  en_CA|  en_029|  en_IN|  en_IE|  en_JM|  en_MY|  en_NZ|
| en_PH|  en_SG|  en_ZA|  en_TT|  en_GB|  en_US|  en_ZW|  et_EE|
| fo_FO|  fil_PH|  fi_FI|  fr_BE|  fr_CA|  fr_FR|  fr_LU|  fr_MC|
| fr_CH|  fy_NL|  gl_ES|  ka_GE|  de_AT|  de_DE|  de_LI|  de_LU|
| de_CH|  el_GR|  kl_GL|  gu_IN|  ha_Latn_NG|  he_IL|  hi_IN|  hu_HU|
| is_IS|  ig_NG|  id_ID|  iu_Latn_CA| iu_Cans_CA|  ga_IE|  it_IT|  it_CH|
| ja_JP|  kn_IN|  kk_KZ|  kh_KH|  qut_GT|  rw_RW|  kok_IN|  ko_KR|
| ky_KG|  lo_LA|  lv_LV|  lt_LT|  dsb_DE|  lb_LU|  mk_MK|  ms_BN|
| ms_MY|  ml_IN|  mt_MT|  mi_NZ|  arn_CL|  mr_IN|  moh_CA|  mn_Cyrl_MN|
| mn_Mong_CN| ne_IN| ne_NP|  nb_NO|  nn_NO|  oc_FR|  or_IN|  ps_AF|
| fa_IR|  pl_PL|  pt_BR|  pt_PT|  pa_IN|  quz_BO|  quz_EC|  quz_PE|
| ro_RO|  rm_CH|  ru_RU|  smn_FI|  smj_NO|  smj_SE|  se_FI|  se_NO|
| se_SE|  sms_FI|  sma_NO|  sma_SE|  sa_IN|  sr_Cyrl_BA|  sr_Latn_BA|  sr_Cyrl_CS|
| sr_Latn_CS| ns_ZA| tn_ZA|  si_LK|  sk_SK|  sl_SI|  es_AR|  es_BO|
| es_CL|  es_CO|  es_CR|  es_DO|  es_EC|  es_SV|  es_GT|  es_HN|
| es_MX|  es_NI|  es_PA|  es_PY|  es_PE|  es_PR|  es_ES|  es_ES_tradnl|
| es_US|  es_UY|  es_VE|  sw_KE|  sv_FI|  sv_SE|  syr_SY|  tg_Cyrl_TJ|
| tmz_Latn_DZ| ta_IN| tt_RU|  te_IN|  th_TH|  bo_BT|  bo_CN|  tr_TR|
| tk_TM|  ug_CN|  uk_UA|  wen_DE|  tr_IN|  ur_PK|  uz_Cyrl_UZ|  uz_Latn_UZ|
| vi_VN|  cy_GB|  wo_SN|  xh_ZA|  sah_RU|  ii_CN|  yo_NG      | zu_ZA|


@[:localconv:locale_canonical|]
==== locale_canonical
<eucode>
include std/localeconv.e
namespace localconv
public constant locale_canonical
</eucode>





@[:localconv:platform_locale|]
==== platform_locale
<eucode>
include std/localeconv.e
namespace localconv
public constant platform_locale
</eucode>







=== Locale Name Translation



@[:localconv:canonical|]
==== canonical
<eucode>
include std/localeconv.e
namespace localconv
public function canonical(sequence new_locale)
</eucode>

  Get canonical name for a locale.

===== Parameters:
# ##new_locale## : a sequence, the string for the locale.
===== Returns:
A **sequence**, either the translated locale on success or ##new_locale## on failure.

===== See Also:
[[:get]], [[:set]], [[:decanonical]]


@[:localconv:decanonical|]
==== decanonical
<eucode>
include std/localeconv.e
namespace localconv
public function decanonical(sequence new_locale)
</eucode>

  gets the translation of a locale string for current platform.

===== Parameters:
# ##new_locale##: a sequence, the string for the locale.

===== Returns:
A **sequence**, either the translated locale on success or ##new_locale## on failure.

===== See Also:
[[:get]], [[:set]], [[:canonical]]


@[:localconv:canon2win|]
==== canon2win
<eucode>
include std/localeconv.e
namespace localconv
public function canon2win(sequence new_locale)
</eucode>

  gets the translation of a canoncial locale string for the //Windows// platform.

===== Parameters:
# ##new_locale##: a sequence, the string for the locale.

===== Returns:
A **sequence**, either the Windows native locale name on success or "C" on failure.

===== See Also:
[[:get]], [[:set]], [[:canonical]], [[:decanonical]]



!!CONTEXT:../include/std/regex.e
!!namespace:regex
%%output = std_regex

== Regular Expressions

<<LEVELTOC level=2 depth=4>>

=== Introduction

Regular expressions in Euphoria are based on the PCRE (Perl Compatible Regular Expressions)
library created by Philip Hazel.

This document will detail the Euphoria interface to Regular Expressions, not really
regular expression syntax. It is a very complex subject that many books have been
written on. Here are a few good resources online that can help while learning
regular expressions.

* [[EUForum Article -> http://openeuphoria.org/wiki/euwiki.cgi?EuGuide%20Regular%20Expressions ]]
* [[Perl Regular Expressions Man Page -> http://perldoc.perl.org/perlre.html]]
* [[Regular Expression Library -> http://regexlib.com/]] (user supplied regular
expressions for just about any task).
* [[WikiPedia Regular Expression Article -> http://en.wikipedia.org/wiki/Regular_expression]]
* [[Man page of PCRE in HTML -> http://www.slabihoud.de/software/archives/pcrecompat.html]]

=== General Use

Many functions take an optional ##options## argument. This argument can be either
a single option constant (see [[:Option Constants]]), multiple option constants or'ed
together into a single atom or a sequence of options, in which the function will take
care of ensuring the are or'ed together correctly.  Options are like their C equivalents
with the 'PCRE_' prefix stripped off.  Name spaces disambiguate symbols so we do not
need this prefix.

All strings passed into this library must be either 8-bit per character strings or
UTF which uses multiple bytes to encode UNICODE characters. You can
use UTF8 encoded UNICODE strings when you pass the UTF8 option.


=== Option Constants

==== Compile Time and Match Time

When a regular expression object is created via ##new## we call also say it gets "compiled."
The options you may use for this are called "compile time" option constants.  Once
the regular expression is created you can use the other functions that take this regular
expression and a string.  These routines' options are called "match time" option constants.
To not set any options at all, do not supply the options argument or supply [[:DEFAULT]].

===== Compile Time Option Constants

The only options that may set at "compile time" (that is to pass to ##new##)
are [[:ANCHORED]], [[:AUTO_CALLOUT]], [[:BSR_ANYCRLF]], [[:BSR_UNICODE]], [[:CASELESS]],
[[:DEFAULT]], [[:DOLLAR_ENDONLY]], [[:DOTALL]], [[:DUPNAMES]], [[:EXTENDED]], [[:EXTRA]],
[[:FIRSTLINE]], [[:MULTILINE]], [[:NEWLINE_CR]], [[:NEWLINE_LF]], [[:NEWLINE_CRLF]],
[[:NEWLINE_ANY]], [[:NEWLINE_ANYCRLF]],  [[:NO_AUTO_CAPTURE]], [[:NO_UTF8_CHECK]],
[[:UNGREEDY]], and [[:UTF8]].


===== Match Time Option Constants

Options that may be set at "match time" are: [[:ANCHORED]], [[:NEWLINE_CR]], [[:NEWLINE_LF]],
[[:NEWLINE_CRLF]], [[:NEWLINE_ANY]] [[:NEWLINE_ANYCRLF]] [[:NOTBOL]], [[:NOTEOL]],
[[:NOTEMPTY]], [[:NO_UTF8_CHECK]].

Routines that take match time option constants: ##match##,
##split##, or ##replace## a regular expression against some string.




@[:regex:ANCHORED|]
==== ANCHORED
<eucode>
public constant ANCHORED
</eucode>

Forces matches to be only from the first place it is asked to
try to make a search.
In C, this is called PCRE_ANCHORED.
This is passed to all routines including [[:new]].


@[:regex:AUTO_CALLOUT|]
==== AUTO_CALLOUT
<eucode>
public constant AUTO_CALLOUT
</eucode>

In C, this is called PCRE_AUTO_CALLOUT.
To get the functionality of this flag in Euphoria, you can use:
[[:find_replace_callback]] without passing this option.
This is passed to [[:new]].


@[:regex:BSR_ANYCRLF|]
==== BSR_ANYCRLF
<eucode
public constant BSR_ANYCRLF
</eucode>

With this option only ASCII new line sequences are recognized as newlines.  Other UNICODE
newline sequences (encoded as UTF8) are not recognized as an end of line marker.
This is passed to all routines including [[:new]].


@[:regex:BSR_UNICODE|]
==== BSR_UNICODE
<eucode>
public constant BSR_UNICODE
</eucode>

With this option any UNICODE new line sequence is recognized as a newline.
The UNICODE will have to be encoded as UTF8, however.
This is passed to all routines including [[:new]].


@[:regex:CASELESS|]
==== CASELESS
<eucode>
public constant CASELESS
</eucode>

This will make your regular expression matches case insensitive.  With this
flag for example, ##[a-z]## is the same as ##[A-Za-z]##.
This is passed to [[:new]].


@[:regex:DEFAULT|]
==== DEFAULT
<eucode>
public constant DEFAULT
</eucode>

This is a value used for not setting any flags at all.  This can be passed to
all routines including [[:new]]


@[:regex:DFA_SHORTEST|]
==== DFA_SHORTEST
<eucode>
public constant DFA_SHORTEST
</eucode>

This is NOT used by any standard library routine.


@[:regex:DFA_RESTART|]
==== DFA_RESTART
<eucode>
public constant DFA_RESTART
</eucode>

This is NOT used by any standard library routine.


@[:regex:DOLLAR_ENDONLY|]
==== DOLLAR_ENDONLY
<eucode>
public constant DOLLAR_ENDONLY
</eucode>

If this bit is set, a dollar sign metacharacter in the pattern matches only
at the end of the subject string. Without this option,  a  dollar sign  also
matches  immediately before a newline at the end of the string (but not
before any other newlines). Thus you must include the newline character
in the pattern before the dollar sign if you want to match a line that contanis
a newline character.
The ##DOLLAR_ENDONLY## option  is  ignored if  ##MULTILINE##  is  set.
There is no way to set this option within a pattern.
This is passed to [[:new]].


@[:regex:DOTALL|]
==== DOTALL
<eucode>
public constant DOTALL
</eucode>

With this option the '.' character also matches a newline sequence.
This is passed to [[:new]].


@[:regex:DUPNAMES|]
==== DUPNAMES
<eucode>
public constant DUPNAMES
</eucode>

Allow duplicate names for named subpatterns.
Since there is no way to access named subpatterns this flag has no effect.
This is passed to [[:new]].


@[:regex:EXTENDED|]
==== EXTENDED
<eucode>
public constant EXTENDED
</eucode>

Whitespace and characters beginning with a hash mark to the end of the line
in the pattern will be ignored when searching except when the whitespace or hash
is escaped or in a character class.
This is passed to [[:new]].


@[:regex:EXTRA|]
==== EXTRA
<eucode>
public constant EXTRA
</eucode>

When an alphanumeric follows a backslash ( ##\## ) has no special meaning an
error is generated.
This is passed to [[:new]].


@[:regex:FIRSTLINE|]
==== FIRSTLINE
<eucode>
public constant FIRSTLINE
</eucode>

If ##PCRE_FIRSTLINE## is set, the match must happen before or at the first
newline in the subject (though it may continue over the newline).
This is passed to [[:new]].


@[:regex:MULTILINE|]
==== MULTILINE
<eucode>
public constant MULTILINE
</eucode>

When  ##MULTILINE##  is set the "start of line" and "end of line"
constructs match immediately following or immediately  before  internal
newlines  in  the  subject string, respectively, as well as at the very
start and end.  This is passed to [[:new]].


@[:regex:NEWLINE_CR|]
==== NEWLINE_CR
<eucode>
public constant NEWLINE_CR
</eucode>

Sets CR as the ##NEWLINE## sequence.
The ##NEWLINE## sequence will match ##$##
when ##MULTILINE## is set.
This is passed to all routines including [[:new]].


@[:regex:NEWLINE_LF|]
==== NEWLINE_LF
<eucode>
public constant NEWLINE_LF
</eucode>

Sets LF as the ##NEWLINE## sequence.
The ##NEWLINE## sequence will match ##$##
when ##MULTILINE## is set.
This is passed to all routines including [[:new]].


@[:regex:NEWLINE_CRLF|]
==== NEWLINE_CRLF
<eucode>
public constant NEWLINE_CRLF
</eucode>

Sets ##CRLF## as the ##NEWLINE## sequence
The ##NEWLINE## sequence will match ##$##
when ##MULTILINE## is set.
This is passed to all routines including [[:new]].


@[:regex:NEWLINE_ANY|]
==== NEWLINE_ANY
<eucode>
public constant NEWLINE_ANY
</eucode>

Sets ##ANY## newline sequence as the ##NEWLINE## sequence including
those from UNICODE when UTF8 is also set.  The string will have
to be encoded as UTF8, however.
The ##NEWLINE## sequence will match ##$##
when ##MULTILINE## is set.
This is passed to all routines including [[:new]].


@[:regex:NEWLINE_ANYCRLF|]
==== NEWLINE_ANYCRLF
<eucode>
public constant NEWLINE_ANYCRLF
</eucode>

Sets ##ANY## newline sequence from ASCII.
The ##NEWLINE## sequence will match ##$##
when ##MULTILINE## is set.
This is passed to all routines including [[:new]].


@[:regex:NOTBOL|]
==== NOTBOL
<eucode>
public constant NOTBOL
</eucode>

This indicates that beginning of the passed string does NOTBOL ( **NOT** start
at the **B**eginning **O**f a **L**ine) so a carrot symbol (##^##) in the
original pattern will //not match// the beginning of the string.
This is used by routines other than [[:new]].


@[:regex:NOTEOL|]
==== NOTEOL
<eucode>
public constant NOTEOL
</eucode>

This indicates that end of the passed string does NOTEOL ( **NOT** end
at the **E**nd **O**f a **L**ine) so a dollar sign (##$##) in the
original pattern will //not match// the end of the string.
This is used by routines other than [[:new]].


@[:regex:NO_AUTO_CAPTURE|]
==== NO_AUTO_CAPTURE
<eucode>
public constant NO_AUTO_CAPTURE
</eucode>

Disables capturing subpatterns except when the subpatterns are
named.
This is passed to [[:new]].


@[:regex:NO_UTF8_CHECK|]
==== NO_UTF8_CHECK
<eucode>
public constant NO_UTF8_CHECK
</eucode>

Turn off checking for the validity of your UTF string.  Use this
with caution.  An invalid utf8 string with this option could //crash//
your program.  Only use this if you know the string is a valid utf8 string.
!!See [[:unicode:validate]].
This is passed to all routines including [[:new]].


@[:regex:NOTEMPTY|]
==== NOTEMPTY
<eucode>
public constant NOTEMPTY
</eucode>

Here matches of empty strings will not be allowed.  In C, this is ##PCRE_NOTEMPTY##.
The pattern: ##`A*a*`## will match ##"AAAA"##, ##"aaaa"##, and ##"Aaaa"## but not ##""##.
This is used by routines other than [[:new]].


@[:regex:PARTIAL|]
==== PARTIAL
<eucode>
public constant PARTIAL
</eucode>

This option has no effect on whether a match will occur or not.
However, it does affect the error code generated by [[:find]] in the event of a failure~:
If for some pattern ##re##, and two strings ##s1## and ##s2##,
##find( re, s1 & s2 )## would return a match
but both ##find( re, s1 )## and ##find( re, s2 )## would not,
then ##find( re, s1, 1, PCRE_PARTIAL )##
will return ##ERROR_PARTIAL## rather than ##ERROR_NOMATCH##.
We say ##s1## has a //partial match// of ##re##.

Note that ##find( re, s2, 1, PCRE_PARTIAL )## will ##ERROR_NOMATCH##.
In C, this constant is called ##PCRE_PARTIAL##.


@[:regex:STRING_OFFSETS|]
==== STRING_OFFSETS
<eucode>
public constant STRING_OFFSETS
</eucode>

This is used by [[:matches]] and [[:all_matches]].


@[:regex:UNGREEDY|]
==== UNGREEDY
<eucode>
public constant UNGREEDY
</eucode>

This is passed to [[:new]].
This modifier sets the pattern such that quantifiers are
not greedy by default, but become greedy if followed by a question mark.


@[:regex:UTF8|]
==== UTF8
<eucode>
public constant UTF8
</eucode>

Makes strings passed in to be interpreted as a UTF8 encoded string.
This is passed to [[:new]].




























































=== Error Constants

Error constants differ from their C equivalents as they do not have ##PCRE_## prepended to each name.



@[:regex:ERROR_NOMATCH|]
==== ERROR_NOMATCH
<eucode>
include std/regex.e
namespace regex
public constant ERROR_NOMATCH
</eucode>

 There was no match found.



@[:regex:ERROR_NULL|]
==== ERROR_NULL
<eucode>
include std/regex.e
namespace regex
public constant ERROR_NULL
</eucode>

 There was an internal error in the EUPHORIA wrapper (std/regex.e in the standard include directory or be_regex.c in the EUPHORIA source).



@[:regex:ERROR_BADOPTION|]
==== ERROR_BADOPTION
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADOPTION
</eucode>

 There was an internal error in the EUPHORIA wrapper (std/regex.e in the standard include directory or be_regex.c in the EUPHORIA source).



@[:regex:ERROR_BADMAGIC|]
==== ERROR_BADMAGIC
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADMAGIC
</eucode>

 The pattern passed is not a value returned from [[:new]].



@[:regex:ERROR_UNKNOWN_OPCODE|]
==== ERROR_UNKNOWN_OPCODE
<eucode>
include std/regex.e
namespace regex
public constant ERROR_UNKNOWN_OPCODE
</eucode>

 An internal error either in the pcre library EUPHORIA uses or its wrapper occured.



@[:regex:ERROR_UNKNOWN_NODE|]
==== ERROR_UNKNOWN_NODE
<eucode>
include std/regex.e
namespace regex
public constant ERROR_UNKNOWN_NODE
</eucode>

 An internal error either in the pcre library EUPHORIA uses or its wrapper occured.



@[:regex:ERROR_NOMEMORY|]
==== ERROR_NOMEMORY
<eucode>
include std/regex.e
namespace regex
public constant ERROR_NOMEMORY
</eucode>

 Out of memory.



@[:regex:ERROR_NOSUBSTRING|]
==== ERROR_NOSUBSTRING
<eucode>
include std/regex.e
namespace regex
public constant ERROR_NOSUBSTRING
</eucode>

 The wrapper or the PCRE backend did not preallocate enough capturing groups for this pattern.



@[:regex:ERROR_MATCHLIMIT|]
==== ERROR_MATCHLIMIT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_MATCHLIMIT
</eucode>

 Too many matches encountered.



@[:regex:ERROR_CALLOUT|]
==== ERROR_CALLOUT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_CALLOUT
</eucode>

 Not applicable to our implementation.



@[:regex:ERROR_BADUTF8|]
==== ERROR_BADUTF8
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADUTF8
</eucode>

 The subject or pattern is not valid UTF8 but it was specified as such with [[:UTF8]].



@[:regex:ERROR_BADUTF8_OFFSET|]
==== ERROR_BADUTF8_OFFSET
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADUTF8_OFFSET
</eucode>

 The offset specified does not start on a UTF8 character boundary but it was specified as UTF8 with [[:UTF8]].



@[:regex:ERROR_PARTIAL|]
==== ERROR_PARTIAL
<eucode>
include std/regex.e
namespace regex
public constant ERROR_PARTIAL
</eucode>

 Pattern didn't match, but there is a //partial match//.  See [[:PARTIAL]].



@[:regex:ERROR_BADPARTIAL|]
==== ERROR_BADPARTIAL
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADPARTIAL
</eucode>

 PCRE backend doesn't support partial matching for this pattern.



@[:regex:ERROR_INTERNAL|]
==== ERROR_INTERNAL
<eucode>
include std/regex.e
namespace regex
public constant ERROR_INTERNAL
</eucode>





@[:regex:ERROR_BADCOUNT|]
==== ERROR_BADCOUNT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADCOUNT
</eucode>

 size parameter to find is less than minus 1.



@[:regex:ERROR_DFA_UITEM|]
==== ERROR_DFA_UITEM
<eucode>
include std/regex.e
namespace regex
public constant ERROR_DFA_UITEM
</eucode>

 Not applicable to our implementation: The PCRE wrapper doesn't use DFA routines



@[:regex:ERROR_DFA_UCOND|]
==== ERROR_DFA_UCOND
<eucode>
include std/regex.e
namespace regex
public constant ERROR_DFA_UCOND
</eucode>

 Not applicable to our implementation: The PCRE wrapper doesn't use DFA routines



@[:regex:ERROR_DFA_UMLIMIT|]
==== ERROR_DFA_UMLIMIT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_DFA_UMLIMIT
</eucode>

 Not applicable to our implementation: The PCRE wrapper doesn't use DFA routines



@[:regex:ERROR_DFA_WSSIZE|]
==== ERROR_DFA_WSSIZE
<eucode>
include std/regex.e
namespace regex
public constant ERROR_DFA_WSSIZE
</eucode>

 Not applicable to our implementation: The PCRE wrapper doesn't use DFA routines



@[:regex:ERROR_DFA_RECURSE|]
==== ERROR_DFA_RECURSE
<eucode>
include std/regex.e
namespace regex
public constant ERROR_DFA_RECURSE
</eucode>

 Not applicable to our implementation: The PCRE wrapper doesn't use DFA routines



@[:regex:ERROR_RECURSIONLIMIT|]
==== ERROR_RECURSIONLIMIT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_RECURSIONLIMIT
</eucode>

 Too much recursion used for match.



@[:regex:ERROR_NULLWSLIMIT|]
==== ERROR_NULLWSLIMIT
<eucode>
include std/regex.e
namespace regex
public constant ERROR_NULLWSLIMIT
</eucode>

 This error isn't in the source code.



@[:regex:ERROR_BADNEWLINE|]
==== ERROR_BADNEWLINE
<eucode>
include std/regex.e
namespace regex
public constant ERROR_BADNEWLINE
</eucode>

 Both BSR_UNICODE and BSR_ANY options were specified.  These options are contradictory.



@[:regex:error_names|]
==== error_names
<eucode>
include std/regex.e
namespace regex
public constant error_names
</eucode>





=== Create and Destroy


@[:regex:regex|]
==== regex
<eucode>
include std/regex.e
namespace regex
public type regex(object o)
</eucode>

  Regular expression type


@[:regex:option_spec|]
==== option_spec
<eucode>
include std/regex.e
namespace regex
public type option_spec(object o)
</eucode>

  Regular expression option specification type

Although the functions do not use this type (they return an error instead),
you can use this to check if your routine is receiving something sane.


@[:regex:option_spec_to_string|]
==== option_spec_to_string
<eucode>
include std/regex.e
namespace regex
public function option_spec_to_string(option_spec o)
</eucode>

  converts an option spec to a string.

This can be useful for debugging what options were passed in.
Without it you have to convert a number to hex and lookup the
constants in the source code.


@[:regex:error_to_string|]
==== error_to_string
<eucode>
include std/regex.e
namespace regex
public function error_to_string(integer i)
</eucode>

  converts an regex error to a string.

This can be useful for debugging and even something rough to give to
the user incase of a regex failure.  It is preferable to
a number.

===== See Also:
[[:error_message]]


@[:regex:new|]
==== new
<eucode>
include std/regex.e
namespace regex
public function new(string pattern, option_spec options = DEFAULT)
</eucode>

  returns an allocated regular expression.

===== Parameters:
# ##pattern## : a sequence representing a human readable regular expression
# ##options## : defaults to [[:DEFAULT]]. See [[:Compile Time Option Constants]].

===== Returns:
A **regex**, which other regular expression routines can work on or an atom to indicate an
error. If an error, you can call [[:error_message]] to get a detailed error message.

===== Comments:
This is the only routine that accepts a human readable regular expression. The string is
compiled and a [[:regex]] is returned. Analyzing and compiling a regular expression is a
costly operation and should not be done more than necessary. For instance, if your application
looks for an email address among text frequently, you should create the regular expression
as a constant accessible to your source code and any files that may use it, thus, the regular
expression is analyzed and compiled only once per run of your application.

<eucode>
-- Bad Example
include std/regex.e as re

while sequence(line) do
    re:regex proper_name = re:new("[A-Z][a-z]+ [A-Z][a-z]+")
    if re:find(proper_name, line) then
        -- code
    end if
end while
</eucode>

<eucode>
-- Good Example
include std/regex.e as re
constant re_proper_name = re:new("[A-Z][a-z]+ [A-Z][a-z]+")
while sequence(line) do
    if re:find(re_proper_name, line) then
        -- code
    end if
end while
</eucode>

===== Example 1:
<eucode>
include std/regex.e as re
re:regex number = re:new("[0-9]+")
</eucode>

===== Note:
For simple matches, the built-in Euphoria
routine [[:eu:match]] and the library routine [[:wildcard:is_match]]
are often times easier to use and
a little faster. Regular expressions are faster for complex searching/matching.

===== See Also:
[[:error_message]], [[:find]], [[:find_all]]


@[:regex:error_message|]
==== error_message
<eucode>
include std/regex.e
namespace regex
public function error_message(object re)
</eucode>

  returns a text based error message.

===== Parameters:
# ##re##: Regular expression to get the error message from

===== Returns:
An atom (0) when no error message exists, otherwise a sequence describing the error.

===== Comments:
If ##[[:new]]## returns an atom, this function will return a text error message
as to the reason.

===== Example 1:
<eucode>
include std/regex.e
object r = regex:new("[A-Z[a-z]*")
if atom(r) then
  printf(1, "Regex failed to compile: %s\n", { regex:error_message(r) })
end if
</eucode>



=== Utility Routines



@[:regex:escape|]
==== escape
<eucode>
include std/regex.e
namespace regex
public function escape(string s)
</eucode>

  escapes special regular expression characters that may be entered into a search
string from user input.

===== Parameters:
# ##s##: string sequence to escape

===== Returns:
An escaped ##sequence## representing ##s##.

===== Note:
Special regex characters are~:
{{{
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
}}}

===== Example 1:
<eucode>
include std/regex.e as re
sequence search_s = re:escape("Payroll is $***15.00")
-- search_s = "Payroll is \\$\\*\\*\\*15\\.00"
</eucode>



@[:regex:get_ovector_size|]
==== get_ovector_size
<eucode>
include std/regex.e
namespace regex
public function get_ovector_size(regex ex, integer maxsize = 0)
</eucode>

  returns the number of capturing subpatterns (the ovector size) for a regex.

===== Parameters:
# ##ex## : a regex
# ##maxsize## : optional maximum number of named groups to get data from

===== Returns:
An **integer**



=== Match


@[:regex:find|]
==== find
<eucode>
include std/regex.e
namespace regex
public function find(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT,
        integer size = get_ovector_size(re, 30))
</eucode>

  returns the first match of ##re## in ##haystack##. You can optionally start at the position
##from##.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : defaults to [[:DEFAULT]]. See [[:Match Time Option Constants]].
The only options that
may be set when calling find are [[:ANCHORED]], [[:NEWLINE_CR]], [[:NEWLINE_LF]],
[[:NEWLINE_CRLF]], [[:NEWLINE_ANY]] [[:NEWLINE_ANYCRLF]] [[:NOTBOL]], [[:NOTEOL]],
[[:NOTEMPTY]], and [[:NO_UTF8_CHECK]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.
# ##size## : internal (how large an array the C backend should allocate). Defaults to 90, in
rare cases this number may need to be increased in order to accomodate complex regex
expressions.

===== Returns:
An **object**, which is either an atom of 0, meaning nothing matched or a sequence of
index pairs.  These index pairs may be fewer than the number of groups specified.  These
index pairs may be the invalid index pair ##{0,0}##.

The first pair is the starting and ending indeces of the sub-string that matches the
expression.  This pair may be followed by indeces of the groups.  The groups are
subexpressions in the regular expression surrounded by parenthesis ().

Now, it is possible to get a match without having all of the groups match.
This can happen when there is a quantifier after a group.  For example: ##'([01])*'## or ##'([01])?'##.
In this case, the returned sequence of pairs will be missing the last group indeces for
which there is no match.
However, if the missing group is followed by a group that *does* match, ##{0,0}## will be
used as a place holder.
You can ensure your groups match when your expression matches by keeping quantifiers
inside your groups~:
For example use: ##'([01]?)'## instead of ##'([01])?'##



===== Example 1:
<eucode>
include std/regex.e as re
r = re:new("([A-Za-z]+) ([0-9]+)") -- John 20 or Jane 45
object result = re:find(r, "John 20")

-- The return value will be:
-- {
--    { 1, 7 }, -- Total match
--    { 1, 4 }, -- First grouping "John" ([A-Za-z]+)
--    { 6, 7 }  -- Second grouping "20" ([0-9]+)
-- }
</eucode>



@[:regex:find_all|]
==== find_all
<eucode>
include std/regex.e
namespace regex
public function find_all(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT,
        integer size = get_ovector_size(re, 30))
</eucode>

  returns all matches of ##re## in ##haystack## optionally starting at the sequence position
##from##.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : defaults to [[:DEFAULT]]. See [[:Match Time Option Constants]].

===== Returns:
A **sequence** of **sequences** that were returned by [[:find]] and in the case of
no matches this returns an empty **sequence**.

===== Comments:
Please see [[:find]] for a detailed description of each member of the return
sequence.

===== Example 1:
<eucode>
include std/regex.e as re
constant re_number = re:new("[0-9]+")
object matches = re:find_all(re_number, "10 20 30")

-- matches is:
-- {
--     {{1, 2}},
--     {{4, 5}},
--     {{7, 8}}
-- }
</eucode>



@[:regex:has_match|]
==== has_match
<eucode>
include std/regex.e
namespace regex
public function has_match(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT)
</eucode>

  determines if ##re## matches any portion of ##haystack##.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : defaults to [[:DEFAULT]]. See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
An **atom**, 1 if ##re## matches any portion of ##haystack## or 0 if not.



@[:regex:is_match|]
==== is_match
<eucode>
include std/regex.e
namespace regex
public function is_match(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT)
</eucode>

  determines if the entire ##haystack## matches ##re##.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : defaults to [[:DEFAULT]].  See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
An **atom**,  1 if ##re## matches the entire ##haystack## or 0 if not.



@[:regex:matches|]
==== matches
<eucode>
include std/regex.e
namespace regex
public function matches(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT)
</eucode>

  gets the matched text only.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : defaults to [[:DEFAULT]]. See [[:Match Time Option Constants]].
##options## can be any match time option or STRING_OFFSETS or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
Returns a **sequence** of strings, the first being the entire match and subsequent
items being each of the captured groups or **ERROR_NOMATCH** of there is no match.
The size of the sequence is the number
of groups in the expression plus one (for the entire match).

If ##options## contains the bit [[:STRING_OFFSETS]], then the result is different.
For each item, a sequence is returned containing the matched text, the starting
index in ##haystack## and the ending index in ##haystack##.

===== Example 1:
<eucode>
include std/regex.e as re
constant re_name = re:new("([A-Z][a-z]+) ([A-Z][a-z]+)")

object matches = re:matches(re_name, "John Doe and Jane Doe")
-- matches is:
-- {
--   "John Doe", -- full match data
--   "John",     -- first group
--   "Doe"       -- second group
-- }

matches = re:matches(re_name, "John Doe and Jane Doe", 1, re:STRING_OFFSETS)
-- matches is:
-- {
--   { "John Doe", 1, 8 }, -- full match data
--   { "John",     1, 4 }, -- first group
--   { "Doe",      6, 8 }  -- second group
-- }
</eucode>

===== See Also:
[[:all_matches]]



@[:regex:all_matches|]
==== all_matches
<eucode>
include std/regex.e
namespace regex
public function all_matches(regex re, string haystack, integer from = 1,
        option_spec options = DEFAULT)
</eucode>

  gets the text of all matches.

===== Parameters:
# ##re## : a regex for a subject to be matched against
# ##haystack## : a string in which to searched
# ##from## : an integer setting the starting position to begin searching from. Defaults to 1
# ##options## : options, defaults to [[:DEFAULT]].  See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
Returns **ERROR_NOMATCH** if there are no matches, or a **sequence** of **sequences** of
**strings** if there is at least one match. In each member sequence of the returned sequence,
the first string is the entire match and subsequent items being each of the
captured groups.  The size of the sequence is
the number of groups in the expression plus one (for the entire match).  In other words,
each member of the return value will be of the same structure of that is returned by
[[:matches]].

If ##options## contains the bit [[:STRING_OFFSETS]], then the result is different.
In each member sequence, instead of each member being a string each member is itself a sequence
containing the matched text, the starting index in ##haystack## and the ending
index in ##haystack##.

===== Example 1:
<eucode>
include std/regex.e as re
constant re_name = re:new("([A-Z][a-z]+) ([A-Z][a-z]+)")

object matches = re:all_matches(re_name, "John Doe and Jane Doe")
-- matches is:
-- {
--   {             -- first match
--     "John Doe", -- full match data
--     "John",     -- first group
--     "Doe"       -- second group
--   },
--   {             -- second match
--     "Jane Doe", -- full match data
--     "Jane",     -- first group
--     "Doe"       -- second group
--   }
-- }

matches = re:all_matches(re_name, "John Doe and Jane Doe", , re:STRING_OFFSETS)
-- matches is:
-- {
--   {                         -- first match
--     { "John Doe",  1,  8 }, -- full match data
--     { "John",      1,  4 }, -- first group
--     { "Doe",       6,  8 }  -- second group
--   },
--   {                         -- second match
--     { "Jane Doe", 14, 21 }, -- full match data
--     { "Jane",     14, 17 }, -- first group
--     { "Doe",      19, 21 }  -- second group
--   }
-- }
</eucode>

===== See Also:
[[:matches]]


=== Splitting


@[:regex:split|]
==== split
<eucode>
include std/regex.e
namespace regex
public function split(regex re, string text, integer from = 1, option_spec options = DEFAULT)
</eucode>

  splits a string based on a regex as a delimiter.

===== Parameters:
# ##re## : a regex which will be used for matching
# ##text## : a string on which search and replace will apply
# ##from## : optional start position
# ##options## : options, defaults to [[:DEFAULT]]. See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
A **sequence** of string values split at the delimiter and if no delimiters were matched
this **sequence** will be a one member sequence equal to ##{text}##.

===== Example 1:
<eucode>
include std/regex.e as re
regex comma_space_re = re:new(`,\s`)
sequence data = re:split(comma_space_re, 
                         "euphoria programming, source code, reference data")
-- data is
-- {
--   "euphoria programming",
--   "source code",
--   "reference data"
-- }
</eucode>



@[:regex:split_limit|]
==== split_limit
<eucode>
include std/regex.e
namespace regex
public function split_limit(regex re, string text, integer limit = 0, integer from = 1,
        option_spec options = DEFAULT)
</eucode>



=== Replacement



@[:regex:find_replace|]
==== find_replace
<eucode>
include std/regex.e
namespace regex
public function find_replace(regex ex, string text, sequence replacement, integer from = 1,
        option_spec options = DEFAULT)
</eucode>

  replaces all matches of a regex with the replacement text.

===== Parameters:
# ##re## : a regex which will be used for matching
# ##text## : a string on which search and replace will apply
# ##replacement## : a string, used to replace each of the full matches
# ##from## : optional start position
# ##options## : options, defaults to [[:DEFAULT]].  See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
A **sequence**, the modified ##text##.  If there is no match with ##re## the
return value will be the same as ##text## when it was passed in.

===== Comments:
Special replacement operators~:

* **##\##**  ~-- Causes the next character to lose its special meaning.
* **##\n##** ~ -- Inserts a ##0x0A## (LF) character.
* **##\r##** ~-- Inserts a ##0x0D## (CR) character.
* **##\t##** ~-- Inserts a ##0x09## (TAB) character.
* **##\1##** to **##\9##** ~-- Recalls stored substrings from registers (\1, \2, \3, to \9).
* **##\0##** ~-- Recalls entire matched pattern.
* **##\u##** ~-- Convert next character to uppercase
* **##\l##** ~-- Convert next character to lowercase
* **##\U##** ~-- Convert to uppercase till ##\E## or ##\e##
* **##\L##** ~-- Convert to lowercase till ##\E## or ##\e##
* **##\E##** or **##\e##** ~-- Terminate a ##{{{\\}}}U## or ##\L## conversion

===== Example 1:
<eucode>
include std/regex.e
regex r = new(`([A-Za-z]+)\.([A-Za-z]+)`)
sequence details = find_replace(r, "hello.txt", 
                                        `Filename: \U\1\e Extension: \U\2\e`)
-- details = "Filename: HELLO Extension: TXT"
</eucode>



@[:regex:find_replace_limit|]
==== find_replace_limit
<eucode>
include std/regex.e
namespace regex
public function find_replace_limit(regex ex, string text, sequence replacement,
        integer limit, integer from = 1, option_spec options = DEFAULT)
</eucode>

  replaces up to ##limit## matches of ##ex## in ##text## except when ##limit## is 0.  When
##limit## is 0, this routine replaces all of the matches.

===== Parameters:
# ##re## : a regex which will be used for matching
# ##text## : a string on which search and replace will apply
# ##replacement## : a string, used to replace each of the full matches
# ##limit## : the number of matches to process
# ##from## : optional start position
# ##options## : options, defaults to [[:DEFAULT]].  See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Comments:
This function is identical to [[:find_replace]] except it allows you to limit the number of
replacements to perform. Please see the documentation for [[:find_replace]] for all the
details.

===== Returns:
A **sequence**, the modified ##text##.

===== See Also:
[[:find_replace]]



@[:regex:find_replace_callback|]
==== find_replace_callback
<eucode>
include std/regex.e
namespace regex
public function find_replace_callback(regex ex, string text, integer rid, integer limit = 0,
        integer from = 1, option_spec options = DEFAULT)
</eucode>

  finds and then replaces text that is processed by a call back function.

===== Parameters:
# ##re## : a regex which will be used for matching
# ##text## : a string on which search and replace will apply
# ##rid## : routine id to execute for each match
# ##limit## : the number of matches to process
# ##from## : optional start position
# ##options## : options, defaults to [[:DEFAULT]].  See [[:Match Time Option Constants]].
##options## can be any match time option or a
sequence of valid options or it can be a value that comes from using or_bits on
any two valid option values.

===== Returns:
A **sequence**, the modified ##text##.

===== Comments:
When ##limit## is positive,
this routine replaces up to ##limit## matches of ##ex## in ##text## with the
result of the user
defined callback, ##rid##, and when ##limit## is 0, replaces
all matches of ##ex## in ##text## with the result of this user defined callback, ##rid##.

The callback should take one sequence.  The first member of this sequence will be a
a string
representing the entire match and the subsequent members, if they exist,
will be a strings
for the captured groups within the regular expression.

The function rid.  Must take one sequence parameter.  The function needs to accept a sequence
of strings and return a string.  For each match, the function will be passed a sequence of
strings.  The first string is the entire match the subsequent strings are for the capturing groups.
If a match succeeds with groups that don't exist, that place will contain a 0. If the sub-group
does exist, the palce will contain the matching group string.
for that group.


===== Example 1:
<eucode>
include std/text.e 
function my_convert(sequence params)
    switch params[1] do
        case "1" then
            return "one "
        case "2" then
            return "two "
        case else
            return "unknown "
    end switch
end function

regex r = re:new(`\d`)
sequence result = re:find_replace_callback(r, "125",routine_id("my_convert"))
-- result = "one two unknown "


integer missing_data_flag = 0
regex r2 = re:new(`[A-Z][a-z]+ ([A-Z][a-z]+)?`)
function my_toupper( sequence params)
      -- here params[2] may be 0.
      return upper( params[1] )
end function

result = find_replace_callback(r2, "John Doe", routine_id("my_toupper"))
-- params[2] is "Doe"
-- result = "JOHN DOE"
printf(1, "result=%s\n", {result} )
result = find_replace_callback(r2, "Mary", routine_id("my_toupper"))
-- result = "MARY"
</eucode>




!!CONTEXT:../include/std/text.e
!!namespace:text
%%output = std_text

== Text Manipulation

<<LEVELTOC level=2 depth=4>>



=== Routines


@[:eu:sprintf|]
==== sprintf
<eucode>
<built-in> function sprintf(sequence format, object values)
</eucode>

returns the representation of any Euphoria object as a string of characters with formatting.

===== Parameters:
# ##format## : a sequence, the text to print. This text may contain format specifiers.
# ##values## : usually, a sequence of values. It should have as many elements as format specifiers in ##format##, as these values will be substituted to the specifiers.

===== Returns:
A **sequence**, of printable characters, representing ##format## with the values in ##values## spliced in.

===== Comments:
This is exactly the same as [[:printf]] except that the output is returned as a sequence
of characters, rather than being sent to a file or device.

##printf(fn, st, x)## is equivalent to ##puts(fn, sprintf(st, x))##.

Some typical uses of ##sprintf## are~:

# Converting numbers to strings.
# Creating strings to pass to ##system##.
# Creating formatted error messages that can be passed to a common error message handler.

===== Example 1:
<eucode>
s = sprintf("%08d", 12345)
-- s is "00012345"
</eucode>

===== See Also:
[[:printf]], [[:sprint]], [[:format]]


@[:text:sprint|]
==== sprint
<eucode>
include std/text.e
namespace text
public function sprint(object x)
</eucode>

  returns the representation of any Euphoria object as a string of characters.

===== Parameters:
# ##x## : Any Euphoria object.

===== Returns:
A **sequence**, a string representation of ##x##.

===== Comments:

This is exactly the same as ##print(fn, x)##, except that the output is returned as a sequence of characters, rather
than being sent to a file or device. ##x## can be any Euphoria object.

The atoms contained within ##x## will be displayed to a maximum of ten significant digits,
just as with [[:print]].

===== Example 1:
<eucode>
s = sprint(12345)
-- s is "12345"
</eucode>

===== Example 2:
<eucode>
s = sprint({10,20,30}+5)
-- s is "{15,25,35}"
</eucode>

===== See Also:
[[:sprintf]], [[:printf]]


@[:text:trim_head|]
==== trim_head
<eucode>
include std/text.e
namespace text
public function trim_head(sequence source, object what = " \t\r\n", integer ret_index = 0)
</eucode>

  trims all items in the supplied set from the leftmost (start or head) of a sequence.

===== Parameters:
# ##source## : the sequence to trim.
# ##what## : the set of item to trim from ##source## (defaults to ##" \t\r\n"##).
# ##ret_index## : If zero (the default) returns the trimmed sequence, otherwise
it returns the index of the leftmost item **not** in ##what##.

===== Returns:
A **sequence**, if ##ret_index## is zero, which is the trimmed version of ##source##\\
A **integer**, if ##ret_index## is not zero, which is index of the leftmost
element in ##source## that is not in ##what##.

===== Example 1:
<eucode>
object s
s = trim_head("\r\nSentence read from a file\r\n", "\r\n")
-- s is "Sentence read from a file\r\n"
s = trim_head("\r\nSentence read from a file\r\n", "\r\n", TRUE)
-- s is 3
</eucode>


===== See Also:
[[:trim_tail]], [[:trim]], [[:pad_head]]


@[:text:trim_tail|]
==== trim_tail
<eucode>
include std/text.e
namespace text
public function trim_tail(sequence source, object what = " \t\r\n", integer ret_index = 0)
</eucode>

  trims all items in the supplied set from the rightmost (end or tail) of a sequence.

===== Parameters:
# ##source## : the sequence to trim.
# ##what## : the set of item to trim from ##source## (defaults to ##" \t\r\n"##).
# ##ret_index## : If zero (the default) returns the trimmed sequence, otherwise
it returns the index of the rightmost item **not** in ##what##.

===== Returns:
A **sequence**, if ##ret_index## is zero, which is the trimmed version of ##source##\\
A **integer**, if ##ret_index## is not zero, which is index of the rightmost
element in ##source## that is not in ##what##.

===== Example 1:
<eucode>
object s
s = trim_tail("\r\nSentence read from a file\r\n", "\r\n")
-- s is "\r\nSentence read from a file"
s = trim_tail("\r\nSentence read from a file\r\n", "\r\n", TRUE)
-- s is 27
</eucode>

===== See Also:
[[:trim_head]], [[:trim]], [[:pad_tail]]


@[:text:trim|]
==== trim
<eucode>
include std/text.e
namespace text
public function trim(sequence source, object what = " \t\r\n", integer ret_index = 0)
</eucode>

  trims all items in the supplied set from both the left end (head/start) and right end (tail/end)
of a sequence.

===== Parameters:
# ##source## : the sequence to trim.
# ##what## : the set of item to trim from ##source## (defaults to ##" \t\r\n"##).
# ##ret_index## : If zero (the default) returns the trimmed sequence, otherwise
it returns a 2-element sequence containing the index of the
leftmost item and rightmost item **not** in ##what##.

===== Returns:
A **sequence**, if ##ret_index## is zero, which is the trimmed version of ##source##\\
A **2-element sequence**, if ##ret_index## is not zero, in the form ##{left_index, right_index}## .

===== Example 1:
<eucode>
object s
s = trim("\r\nSentence read from a file\r\n", "\r\n")
-- s is "Sentence read from a file"
s = trim("\r\nSentence read from a file\r\n", "\r\n", TRUE)
-- s is {3,27}
s = trim(" This is a sentence.\n")  -- Default is to trim off all " \t\r\n"
-- s is "This is a sentence."
</eucode>

===== See Also:
[[:trim_head]], [[:trim_tail]]


@[:text:set_encoding_properties|]
==== set_encoding_properties
<eucode>
include std/text.e
namespace text
public procedure set_encoding_properties(sequence en = "", sequence lc = "", sequence uc = "")
</eucode>

  sets the table of lowercase and uppercase characters that is used by
[[:lower]] and [[:upper]]

===== Parameters:
# ##en## : The name of the encoding represented by these character sets
# ##lc## : The set of lowercase characters
# ##uc## : The set of upper case characters


===== Comments:
* ##lc## and ##uc## must be the same length.
* If no parameters are given, the default ASCII table is set.

===== Example 1:
<eucode>
set_encoding_properties( "Elvish", "aeiouy", "AEIOUY")
</eucode>

===== Example 1:
<eucode>
set_encoding_properties( "1251") -- Loads a predefined code page.
</eucode>

===== See Also:
[[:lower]], [[:upper]], [[:get_encoding_properties]]


@[:text:get_encoding_properties|]
==== get_encoding_properties
<eucode>
include std/text.e
namespace text
public function get_encoding_properties()
</eucode>

  gets the table of lowercase and uppercase characters that is used by
[[:lower]] and [[:upper]].

===== Parameters:
none

===== Returns:
A **sequence**, containing three items.\\
##{Encoding_Name, LowerCase_Set, UpperCase_Set}##

===== Example 1:
<eucode>
encode_sets = get_encoding_properties()
</eucode>

===== See Also:
[[:lower]], [[:upper]], [[:set_encoding_properties]]



@[:text:lower|]
==== lower
<eucode>
include std/text.e
namespace text
public function lower(object x)
</eucode>

  converts an atom or sequence to lower case.

===== Parameters:
# ##x## : Any Euphoria object.

===== Returns:
A **sequence**, the lowercase version of ##x##

===== Comments:
* For //Windows// systems, this uses the current code page for conversion
* For //Unix// this only works on ASCII characters. It alters characters in
the ##'a'..'z'## range. If you need to do case conversion with other encodings
use the [[:set_encoding_properties]] first.
* ##x## may be a sequence of any shape, all atoms of which will be acted upon.

**WARNING**, When using ASCII encoding, this can also affect floating point
numbers in the range ##65## to ##90##.

===== Example 1:
<eucode>
s = lower("Euphoria")
-- s is "euphoria"

a = lower('B')
-- a is 'b'

s = lower({"Euphoria", "Programming"})
-- s is {"euphoria", "programming"}
</eucode>

===== See Also:
[[:upper]], [[:proper]], [[:set_encoding_properties]], [[:get_encoding_properties]]


@[:text:upper|]
==== upper
<eucode>
include std/text.e
namespace text
public function upper(object x)
</eucode>

  converts an atom or sequence to upper case.

===== Parameters:
# ##x## : Any Euphoria object.

===== Returns:
A **sequence**, the uppercase version of ##x##

===== Comments:
* For //Windows// systems, this uses the current code page for conversion
* For //Unix// this only works on ASCII characters. It alters characters in
the ##'a'..'z'## range. If you need to do case conversion with other encodings
use the [[:set_encoding_properties]] first.
* ##x## may be a sequence of any shape, all atoms of which will be acted upon.

**WARNING**, When using ASCII encoding, this can also affects floating point
numbers in the range ##97## to ##122##.

===== Example 1:
<eucode>
s = upper("Euphoria")
-- s is "EUPHORIA"

a = upper('b')
-- a is 'B'

s = upper({"Euphoria", "Programming"})
-- s is {"EUPHORIA", "PROGRAMMING"}
</eucode>

===== See Also:
[[:lower]], [[:proper]], [[:set_encoding_properties]], [[:get_encoding_properties]]


@[:text:proper|]
==== proper
<eucode>
include std/text.e
namespace text
public function proper(sequence x)
</eucode>

  converts a text sequence to capitalized words.

===== Parameters:
# ##x## : A text sequence.

===== Returns:
A **sequence**, the Capitalized Version of ##x##

===== Comments:
A text sequence is one in which all elements are either characters or
text sequences. This means that if a non-character is found in the input,
it is not converted. However this rule only applies to elements on the
same level, meaning that sub-sequences could be converted if they are
actually text sequences.

===== Example 1:
<eucode>
s = proper("euphoria programming language")
-- s is "Euphoria Programming Language"
s = proper("EUPHORIA PROGRAMMING LANGUAGE")
-- s is "Euphoria Programming Language"
s = proper({"EUPHORIA PROGRAMMING", "language", "rapid dEPLOYMENT", "sOfTwArE"})
-- s is {"Euphoria Programming", "Language", "Rapid Deployment", "Software"}
s = proper({'a', 'b', 'c'})
-- s is {'A', 'b', c'} -- "Abc"
s = proper({'a', 'b', 'c', 3.1472})
-- s is {'a', 'b', c', 3.1472} -- Unchanged because it contains a non-character.
s = proper({"abc", 3.1472})
-- s is {"Abc", 3.1472} -- The embedded text sequence is converted.
</eucode>

===== See Also:
[[:lower]] [[:upper]]


@[:text:keyvalues|]
==== keyvalues
<eucode>
include std/text.e
namespace text
public function keyvalues(sequence source, object pair_delim = ";,", object kv_delim = ":=",
        object quotes = "\"'`", object whitespace = " \t\n\r", integer haskeys = 1)
</eucode>

  converts a string containing Key/Value pairs into a set of
sequences, one per K/V pair.

===== Parameters:
# ##source## : a text sequence, containing the representation of the key/values.
# ##pair_delim## : an object containing a list of elements that delimit one
key/value pair from the next. The defaults are semi-colon (;)
and comma (,).
# ##kv_delim## : an object containing a list of elements that delimit the
key from its value. The defaults are colon (:) and equal (=).
# ##quotes## : an object containing a list of elements that can be used to
enclose either keys or values that contain delimiters or
whitespace. The defaults are double-quote ("), single-quote (')
and back-quote (`)
# ##whitespace## : an object containing a list of elements that are regarded
as whitespace characters. The defaults are space, tab, new-line,
and carriage-return.
# ##haskeys## : an integer containing true or false. The default is true. When
##true##, the ##kv_delim## values are used to separate keys from values, but
when ##false## it is assumed that each 'pair' is actually just a value.

===== Returns:
A **sequence**, of pairs. Each pair is in the form ##{key, value}##.

===== Comments:

String representations of atoms are not converted, either in the key or value part, but returned as any regular string instead.

If ##haskeys## is ##true##, but a substring only holds what appears to be a value, the key
is synthesized as ##p[n]##, where ##n## is the number of the pair. See Example 2.

By default, pairs can be delimited by either a comma or semi-colon ",;" and
a key is delimited from its value by either an equal or a colon "=:".
Whitespace between pairs, and between delimiters is ignored.

If you need to have one of the delimiters in the value data, enclose it in
quotation marks. You can use any of single, double and back quotes, which
also means you can quote quotation marks themselves. See Example 3.

It is possible that the value data itself is a nested set of pairs. To do
this enclose the value in parentheses. Nested sets can nested to any level.
See Example 4.

If a sub-list has only data values and not keys, enclose it in either braces
or square brackets. See Example 5.
If you need to have a bracket as the first character in a data value, prefix
it with a tilde. Actually a leading tilde will always just be stripped off
regardless of what it prefixes. See Example 6.

===== Example 1:
<eucode>
s= keyvalues("foo=bar, qwe=1234, asdf='contains space, comma, and equal(=)'")
-- s is 
-- {
--   {"foo", "bar"}, 
--   {"qwe", "1234"}, 
--   {"asdf", "contains space, comma, and equal(=)"}
--  }
</eucode>

===== Example 2:
<eucode>
s = keyvalues("abc fgh=ijk def")
-- s is { {"p[1]", "abc"}, {"fgh", "ijk"}, {"p[3]", "def"} }
</eucode>

===== Example 3:
<eucode>
s = keyvalues("abc=`'quoted'`")
-- s is { {"abc", "'quoted'"} }
</eucode>

===== Example 4:
<eucode>
s = keyvalues("colors=(a=black, b=blue, c=red)")
-- s is { {"colors", {{"a", "black"}, {"b", "blue"},{"c", "red"}}  } }
s = keyvalues("colors=(black=[0,0,0], blue=[0,0,FF], red=[FF,0,0])")
-- s is 
-- { {"colors", 
--   {{"black",{"0", "0", "0"}}, 
--   {"blue",{"0", "0", "FF"}},
--   {"red", {"FF","0","0"}}}} }
</eucode>

===== Example 5:
<eucode>
s = keyvalues("colors=[black, blue, red]")
-- s is { {"colors", { "black", "blue", "red"}  } }
</eucode>

===== Example 6:
<eucode>
s = keyvalues("colors=~[black, blue, red]")
-- s is { {"colors", "[black, blue, red]"}  } }
-- The following is another way to do the same.
s = keyvalues("colors=`[black, blue, red]`")
-- s is { {"colors", "[black, blue, red]"}  } }
</eucode>


@[:text:escape|]
==== escape
<eucode>
include std/text.e
namespace text
public function escape(sequence s, sequence what = "\"")
</eucode>

  escapes special characters in a string.

===== Parameters:
# ##s##: string to escape
# ##what##: sequence of characters to escape
defaults to escaping a double quote.

===== Returns:
An escaped ##sequence## representing ##s##.

===== Example 1:
<eucode>
sequence s = escape("John \"Mc\" Doe")
puts(1, s)
-- output is: John \"Mc\" Doe
</eucode>

===== See Also:
[[:quote]]



@[:text:quote|]
==== quote
<eucode>
include std/text.e
namespace text
public function quote(sequence text_in, object quote_pair = {"\"", "\""}, integer esc = - 1,
        t_text sp = "")
</eucode>

  returns a quoted version of the first argument.

===== Parameters:
# ##text_in## : The string or set of strings to quote.
# ##quote_pair## : A sequence of two strings. The first string is the opening
quote to use, and the second string is the closing quote to use.
The default is {"\"", "\""} which means that the output will be
enclosed by double-quotation marks.
# ##esc## : A single escape character. If this is not negative (the default),
then this is used to 'escape' any embedded quote characters and
'esc' characters already in the ##text_in## string.
# ##sp##  : A list of zero or more special characters. The ##text_in## is only
quoted if it contains any of the special characters. The default
is "" which means that the ##text_in## is always quoted.

===== Returns:
A **sequence**, the quoted version of ##text_in##.

===== Example 1:
<eucode>
-- Using the defaults. Output enclosed in double-quotes, no escapes and no specials.
s = quote("The small man")
-- 's' now contains '"the small man"' including the double-quote characters.
</eucode>

===== Example 2:
<eucode>
s = quote("The small man", {"(", ")"} )
-- 's' now contains '(the small man)'
</eucode>

===== Example 3:
<eucode>
s = quote("The (small) man", {"(", ")"}, '~' )
-- 's' now contains '(The ~(small~) man)'
</eucode>

===== Example 4:
<eucode>
s = quote("The (small) man", {"(", ")"}, '~', "#" )
-- 's' now contains "the (small) man"
-- because the input did not contain a '#' character.
</eucode>

===== Example 5:
<eucode>
s = quote("The #1 (small) man", {"(", ")"}, '~', "#" )
-- 's' now contains '(the #1 ~(small~) man)'
-- because the input did contain a '#' character.
</eucode>

===== Example 6:
<eucode>
-- input is a set of strings...
s = quote({"a b c", "def", "g hi"},)
-- 's' now contains three quoted strings: '"a b c"', '"def"', and '"g hi"'
</eucode>

===== See Also:
[[:escape]]



@[:text:dequote|]
==== dequote
<eucode>
include std/text.e
namespace text
public function dequote(sequence text_in, object quote_pairs = {{"\"", "\""}},
        integer esc = - 1)
</eucode>

  removes 'quotation' text from the argument.

===== Parameters:
# ##text_in## : The string or set of strings to de-quote.
# ##quote_pairs## : A set of one or more sub-sequences of two strings,
or an atom representing a single character to be used as
both the open and close quotes.
The first string in each sub-sequence is the opening
quote to look for, and the second string is the closing quote.
The default is {{{"\"", "\""}}} which means that the output is
'quoted' if it is enclosed by double-quotation marks.
# ##esc## : A single escape character. If this is not negative (the default),
then this is used to 'escape' any embedded occurrences of the
quote characters. In which case the 'escape' character is also
removed.

===== Returns:
A **sequence**, the original text but with 'quote' strings stripped of quotes.

===== Example 1:
<eucode>
-- Using the defaults.
s = dequote("\"The small man\"")
-- 's' now contains "The small man"
</eucode>

===== Example 2:
<eucode>
-- Using the defaults.
s = dequote("(The small ?(?) man)", {{"(",")"}}, '?')
-- 's' now contains "The small () man"
</eucode>



@[:text:format|]
==== format
<eucode>
include std/text.e
namespace text
public function format(sequence format_pattern, object arg_list = {})
</eucode>

  formats a set of arguments in to a string based on a supplied pattern.

===== Parameters:
# ##format_pattern## : A sequence: the pattern string that contains zero or more tokens.
# ##arg_list## : An object: Zero or more arguments used in token replacement.

===== Returns:
A string **sequence**, the original ##format_pattern## but with tokens replaced by
corresponding arguments.

===== Comments:
The ##format_pattern## string contains text and argument tokens. The resulting string
is the same as the format string except that each token is replaced by an
item from the argument list.

A token has the form **##[<Q>]##**, where ##<Q>## is are optional qualifier codes.

The qualifier. ##<Q>## is a set of zero or more codes that modify the default
way that the argument is used to replace the token. The default replacement
way is to convert the argument to its shortest string representation and
use that to replace the token. This may be modified by the following codes,
which can occur in any order.

|= Qualifier |= Usage                                              |
|  N         | ('N' is an integer) The index of the argument to use|
| {id}       | Uses the argument that begins with "id=" where "id" \\
is an identifier name.                              |
| %envvar%   | Uses the Environment Symbol 'envar' as an argument  |
|  w         | For string arguments, if capitalizes the first\\
letter in each word                                 |
|  u         | For string arguments, it converts it to upper case. |
|  l         | For string arguments, it converts it to lower case. |
|  <         | For numeric arguments, it left justifies it.        |
|  >         | For string arguments, it right justifies it.        |
|  c         | Centers the argument.                               |
|  z         | For numbers, it zero fills the left side.           |
|  :S        | ('S' is an integer) The maximum size of the\\
resulting field. Also, if 'S' begins with '0' the\\
field will be zero-filled if the argument is an integer|
|  .N        | ('N' is an integer) The number of digits after\\
the  decimal point                                 |
|  +         | For positive numbers, show a leading plus sign      |
|  (         | For negative numbers, enclose them in parentheses   |
|  b         | For numbers, causes zero to be all blanks           |
|  s         | If the resulting field would otherwise be zero\\
length, this ensures that at least one space occurs\\
between this token's field                          |
|  t         | After token replacement, the resulting string up to this point is trimmed. |
|  X         | Outputs integer arguments using hexadecimal digits. |
|  B         | Outputs integer arguments using binary digits.      |
|  ?         | The corresponding argument is a set of two strings. This\\
uses the first string if the previous token's argument is\\
not the value 1 or a zero-length string, otherwise it\\
uses the second string.                             |
|  [         | Does not use any argument. Outputs a left-square-bracket symbol |
|  ,X        | Insert thousands separators. The <X> is the character\\
to use. If this is a dot "." then the decimal point\\
is rendered using a comma. Does not apply to zero-filled\\
fields.                         \\
N.B. if hex or binary output was specified, the \\
separators are every 4 digits otherwise they are \\
every three digits. |
|  T         | If the argument is a number it is output as a text character, \\
otherwise it is output as text string |

Clearly, certain combinations of these qualifier codes do not make sense and in
those situations, the rightmost clashing code is used and the others are ignored.

Any tokens in the format that have no corresponding argument are simply removed
from the result. Any arguments that are not used in the result are ignored.

Any sequence argument that is not a string will be converted to its
//pretty// format before being used in token replacement.

If a token is going to be replaced by a zero-length argument, all white space
following the token until the next non-whitespace character is not copied to
the result string.

===== Example 1:
<eucode>
format("Cannot open file '[]' - code []", {"/usr/temp/work.dat", 32})
-- "Cannot open file '/usr/temp/work.dat' - code 32"

format("Err-[2], Cannot open file '[1]'", {"/usr/temp/work.dat", 32})
-- "Err-32, Cannot open file '/usr/temp/work.dat'"

format("[4w] [3z:2] [6] [5l] [2z:2], [1:4]", {2009,4,21,"DAY","MONTH","of"})
-- "Day 21 of month 04, 2009"

format("The answer is [:6.2]%", {35.22341})
-- "The answer is  35.22%"

format("The answer is [.6]", {1.2345})
-- "The answer is 1.234500"

format("The answer is [,,.2]", {1234.56})
-- "The answer is 1,234.56"

format("The answer is [,..2]", {1234.56})
-- "The answer is 1.234,56"

format("The answer is [,:.2]", {1234.56})
-- "The answer is 1:234.56"

format("[] [?]", {5, {"cats", "cat"}})
-- "5 cats"

format("[] [?]", {1, {"cats", "cat"}})
-- "1 cat"

format("[<:4]", {"abcdef"})
-- "abcd"

format("[>:4]", {"abcdef"})
-- "cdef"

format("[>:8]", {"abcdef"})
-- "  abcdef"

format("seq is []", {{1.2, 5, "abcdef", {3}}})
-- `seq is {1.2,5,"abcdef",{3}}`

format("Today is [{day}], the [{date}]", {"date=10/Oct/2012", "day=Wednesday"})
-- "Today is Wednesday, the 10/Oct/2012"

format("'A' is [T]", 65)
-- `'A' is A`
</eucode>

===== See Also:
[[:sprintf]]



@[:text:wrap|]
==== wrap
<eucode>
include std/text.e
namespace text
public function wrap(sequence content, integer width = 78, sequence wrap_with = "\n",
        sequence wrap_at = " \t")
</eucode>

  wraps text to a column width.

===== Parameters:
* ##content##   ~-- sequence content to wrap
* ##width##     ~-- width to wrap at, defaults to 78
* ##wrap_with## ~-- sequence to wrap with, defaults to ##"\n"##
* ##wrap_at##   ~-- sequence of characters to wrap at, defaults to space and tab

===== Returns:
Sequence containing wrapped text

===== Example 1:
<eucode>
sequence result = wrap("Hello, World")
-- result = "Hello, World"
</eucode>

===== Example 2:
<eucode>
sequence msg = "Hello, World. Today we are going to learn about apples."
sequence result = wrap(msg, 40)
-- result =
--   "Hello, World. today we are going to\n"
--   "learn about apples."
</eucode>

===== Example 3:
<eucode>
sequence msg = "Hello, World. Today we are going to learn about apples."
sequence result = wrap(msg, 40, "\n    ")
-- result =
--   "Hello, World. today we are going to\n"
--   "    learn about apples."
</eucode>

===== Example 4:
<eucode>
sequence msg = "Hello, World. This, Is, A, Dummy, Sentence, Ok, World?"
sequence result = wrap(msg, 30, "\n", ",")
-- result = 
--   "Hello, World. This, Is, A,"
--   "Dummy, Sentence, Ok, World?"
</eucode>



!!CONTEXT:../include/std/wildcard.e
!!namespace:wildcard
%%output = std_wildcard

== Wildcard Matching

<<LEVELTOC level=2 depth=4>>



=== Routines


@[:wildcard:is_match|]
==== is_match
<eucode>
include std/wildcard.e
namespace wildcard
public function is_match(sequence pattern, sequence string)
</eucode>

  determines whether a string matches a pattern. The pattern may contain ##*## and ##?## wildcards.

===== Parameters:
# ##pattern## : a string, the pattern to match
# ##string## : the string to be matched against

===== Returns:
An **integer**, TRUE if ##string## matches ##pattern##, else FALSE.

===== Comments:

Character comparisons are case sensitive.
If you want case insensitive comparisons, pass both ##pattern## and ##string## through [[:upper]], or both through [[:lower]], before calling ##is_match##.

If you want to detect a pattern anywhere within a string, add ##*## to each end of the pattern:

<eucode>
 i = is_match('*' & pattern & '*', string)
</eucode>

There is currently no way to treat ##*## or ##?## literally in a pattern.

===== Example 1:
<eucode>
 i = is_match("A?B*", "AQBXXYY")
-- i is 1 (TRUE)
</eucode>

===== Example 2:
<eucode>
 i = is_match("*xyz*", "AAAbbbxyz")
-- i is 1 (TRUE)
</eucode>

===== Example 3:
<eucode>
 i = is_match("A*B*C", "a111b222c")
-- i is 0 (FALSE) because upper/lower case doesn't match
</eucode>

===== Example 4:
##.../euphoria/demo/search.ex##

===== See Also:
[[:upper]], [[:lower]], [[:Regular Expressions]]




!!CONTEXT:../include/std/base64.e
!!namespace:base64
%%output = std_base64

== Base 64 Encoding and Decoding

<<LEVELTOC level=2 depth=4>>

Base64 is used to encode binary data into an ASCII string; this allows
binary data to be transmitted using media designed to transmit text data only.
See [[en.wikipedia.org/wiki/Base64]] and the RFC 2045 standard for more
information.


=== Routines



@[:base64:encode|]
==== encode
<eucode>
include std/base64.e
namespace base64
public function encode(sequence in, integer wrap_column = 0)
</eucode>

  encodes to base64.

===== Parameters:
# ##in## ~-- must be a simple sequence
# ##wrap_column## ~-- column to wrap the base64 encoded message to;
defaults to ##0## which is do not wrap

===== Returns:
A **sequence**, a base64 encoded sequence representing ##in##.

===== Example 1:
<eucode>
puts(1, encode( "Hello Euphoria!") )
--> SGVsbG8gRXVwaG9yaWEh
</eucode>



@[:base64:decode|]
==== decode
<eucode>
include std/base64.e
namespace base64
public function decode(sequence in)
</eucode>

  decodes from base64.

===== Parameters:
# ##in## ~-- must be a simple sequence of length ##4## to ##76## .

===== Returns:
A **sequence**, base256 decode of passed sequence.
the length of data to decode must be a multiple of ##4## .

===== Comments:
The calling program is expected to strip newlines and so on before calling.




!!CONTEXT:../include/std/math.e
!!namespace:math
%%output = std_math

== Math

<<LEVELTOC level=2 depth=4>>



=== Sign and Comparisons



@[:math:abs|]
==== abs
<eucode>
include std/math.e
namespace math
public function abs(object a)
</eucode>

  returns the absolute value of numbers.

===== Parameters:
# ##value## : an object, each atom is processed, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom,
the result is the same if not less than zero, and the opposite value otherwise.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

===== Example 1:
<eucode>
x = abs({10.5, -12, 3})
-- x is {10.5, 12, 3}

i = abs(-4)
-- i is 4
</eucode>

===== See Also:
[[:sign]]


@[:math:sign|]
==== sign
<eucode>
include std/math.e
namespace math
public function sign(object a)
</eucode>

  returns -1, 0 or 1 for each element according to it being negative, zero or positive.

===== Parameters:
# ##value## : an object, each atom of which will be acted upon, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, the result is -1 if ##value## is less than zero, 1 if greater and 0 if equal.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

For an atom, ##sign(x)## is the same as [[:compare]](x,0).

===== Example 1:
<eucode>
i = sign(5)
i is 1

i = sign(0)
-- i is 0

i = sign(-2)
-- i is -1
</eucode>

===== See Also:
[[:compare]]


@[:math:larger_of|]
==== larger_of
<eucode>
include std/math.e
namespace math
public function larger_of(object objA, object objB)
</eucode>

  returns the larger of two objects.

===== Parameters:
# ##objA## : an object.
# ##objB## : an object.
===== Returns:
Whichever of ##objA## and ##objB## is the larger one.

===== Comments:
Introduced in v4.0.3

===== Example 1:
<eucode>
? larger_of(10, 15.4) -- returns 15.4
? larger_of("cat", "dog") -- returns "dog"
? larger_of("apple", "apes") -- returns "apple"
? larger_of(10, 10) -- returns 10
</eucode>

===== See Also:
[[:max]], [[:compare]], [[:smaller_of]]


@[:math:smaller_of|]
==== smaller_of
<eucode>
include std/math.e
namespace math
public function smaller_of(object objA, object objB)
</eucode>

  returns the smaller of two objects.

===== Parameters:
# ##objA## : an object.
# ##objB## : an object.

===== Returns:
Whichever of ##objA## and ##objB## is the smaller one.

===== Comments:
Introduced in v4.0.3

===== Example 1:
<eucode>
? smaller_of(10, 15.4) -- returns 10
? smaller_of("cat", "dog") -- returns "cat"
? smaller_of("apple", "apes") -- returns "apes"
? smaller_of(10, 10) -- returns 10
</eucode>

===== See Also:
[[:min]], [[:compare]], [[:larger_of]]


@[:math:max|]
==== max
<eucode>
include std/math.e
namespace math
public function max(object a)
</eucode>

  computes the maximum value among all the argument's elements.

===== Parameters:
# ##values## : an object, all atoms of which will be inspected, no matter how deeply nested.

===== Returns:
An **atom**, the maximum of all atoms in [[:flatten]](##values##).

===== Comments:
This function may be applied to an atom or to a sequence of any shape.

===== Example 1:
<eucode>
a = max({10,15.4,3})
-- a is 15.4
</eucode>

===== See Also:
[[:min]], [[:compare]], [[:flatten]]


@[:math:min|]
==== min
<eucode>
include std/math.e
namespace math
public function min(object a)
</eucode>

  computes the minimum value among all the argument's elements.

===== Parameters:
# ##values## : an object, all atoms of which will be inspected, no matter how deeply nested.

===== Returns:
An **atom**, the minimum of all atoms in [[:flatten]](##values##).

===== Comments:
This function may be applied to an atom or to a sequence of any shape.

===== Example 1:
<eucode>
a = min({10,15.4,3})
-- a is 3
</eucode>


@[:math:ensure_in_range|]
==== ensure_in_range
<eucode>
include std/math.e
namespace math
public function ensure_in_range(object item, sequence range_limits)
</eucode>

  ensures that the ##item## is in a range of values supplied by inclusive ##range_limits##.

===== Parameters:
# ##item## : The object to test for.
# ##range_limits## : A sequence of two or more elements. The first is assumed
to be the smallest value and the last is assumed to be the highest value.

===== Returns:
A **object**, If ##item## is lower than the first item in the ##range_limits##
it returns the first item.
If  ##item## is higher than the last element in the ##range_limits##
it returns the last item.
Otherwise it returns ##item##.

===== Example 1:
<eucode>
object valid_data = ensure_in_range(user_data, {2, 75})
if not equal(valid_data, user_data) then
    errmsg("Invalid input supplied. Using %d instead.", valid_data)
end if
procA(valid_data)
</eucode>


@[:math:ensure_in_list|]
==== ensure_in_list
<eucode>
include std/math.e
namespace math
public function ensure_in_list(object item, sequence list, integer default = 1)
</eucode>

  ensures that the ##item## is in a list of values supplied by ##list##.

===== Parameters:
# ##item## : The object to test for.
# ##list## : A sequence of elements that ##item## should be a member of.
# ##default## : an integer, the index of the list item to return if ##item## is not found. Defaults to 1.

===== Returns:
An **object**, if ##item## is not in the list, it returns the list item of index ##default##,
otherwise it returns ##item##.

===== Comments:

If ##default## is set to an invalid index, the first item on the list is returned instead
when ##item## is not on the list.

===== Example 1:
<eucode>
object valid_data = ensure_in_list(user_data, {100, 45, 2, 75, 121})
if not equal(valid_data, user_data) then
    errmsg("Invalid input supplied. Using %d instead.", valid_data)
end if
procA(valid_data)
</eucode>


=== Roundings and Remainders



@[:eu:remainder|]
==== remainder
<eucode>
<built-in> function remainder(object dividend, object divisor)
</eucode>

computes the remainder of the division of two objects using truncated division.

===== Parameters:
# ##dividend## : any Euphoria object.
# ##divisor## : any Euphoria object.

===== Returns:
An **object**, the shape of which depends on ##dividend##'s and
##divisor##'s. For two atoms, this is the remainder of dividing
##dividend## by  ##divisor##, with ##dividend##'s sign.

===== Errors:
# If any atom in ##divisor## is 0, this is an error condition as it
amounts to an attempt to divide by zero.
# If both ##dividend## and ##divisor## are sequences, they must be the
same length as each other.

===== Comments:
* There is a integer ##N## such that ##dividend## = ##N## * ##divisor## + result.
* The result has the sign of ##dividend## and lesser magnitude than ##divisor##.
*  The result has the same sign as the dividend.
* This differs from [[:mod]] in that when the operands' signs are different
this function rounds ##dividend/divisior## towards zero whereas ##mod## rounds
away from zero.

The arguments to this function may be atoms or sequences. The rules for
[[:operations on sequences]] apply, and determine the shape of the returned object.

===== Example 1:
<eucode>
a = remainder(9, 4)
-- a is 1
</eucode>

===== Example 2:
<eucode>
s = remainder({81, -3.5, -9, 5.5}, {8, -1.7, 2, -4})
-- s is {1, -0.1, -1, 1.5}
</eucode>

===== Example 3:
<eucode>
s = remainder({17, 12, 34}, 16)
-- s is {1, 12, 2}
</eucode>

===== Example 4:
<eucode>
s = remainder(16, {2, 3, 5})
-- s is {0, 1, 1}
</eucode>
===== See Also:
[[:mod]], [[:Relational operators]], [[:Operations on sequences]]


@[:math:mod|]
==== mod
<eucode>
include std/math.e
namespace math
public function mod(object x, object y)
</eucode>

  computes the remainder of the division of two objects using floored division.

===== Parameters:
# ##dividend## : any Euphoria object.
# ##divisor## : any Euphoria object.

===== Returns:
An **object**, the shape of which depends on ##dividend##'s and
##divisor##'s. For two atoms, this is the remainder of dividing ##dividend##
by ##divisor##, with ##divisor##'s sign.

===== Comments:
* There is a integer ##N## such that ##dividend## = N * ##divisor## + result.
* The result is non-negative and has lesser magnitude than ##divisor##.
n needs not fit in an Euphoria integer.
*  The result has the same sign as the dividend.
* The arguments to this function may be atoms or sequences. The rules for
[[:operations on sequences]] apply, and determine the shape of the returned object.
* When both arguments have the same sign, mod() and [[:remainder]]
return the same result.
* This differs from [[:remainder]] in that when the operands' signs are different
this function rounds ##dividend/divisior## away from zero whereas ##remainder## rounds
towards zero.

===== Example 1:
<eucode>
a = mod(9, 4)
-- a is 1
</eucode>

===== Example 2:
<eucode>
s = mod({81, -3.5, -9, 5.5}, {8, -1.7, 2, -4})
-- s is {1,-0.1,1,-2.5}
</eucode>

===== Example 3:
<eucode>
s = mod({17, 12, 34}, 16)
-- s is {1, 12, 2}
</eucode>

===== Example 4:
<eucode>
s = mod(16, {2, 3, 5})
-- s is {0, 1, 1}
</eucode>
===== See Also:
[[:remainder]], [[:Relational operators]], [[:Operations on sequences]]


@[:math:trunc|]
==== trunc
<eucode>
include std/math.e
namespace math
public function trunc(object x)
</eucode>

  returns the integer portion of a number.

===== Parameters:
# ##value## : any Euphoria object.

===== Returns:
An **object**, the shape of which depends on ##values##'s. Each item in the
returned object will be an integer. These are the same corresponding items
in ##value## except with any fractional portion removed.

===== Comments:
* This is essentially done by always rounding towards zero. The [[:floor]] function
rounds towards negative infinity, which means it rounds towards zero for positive
values and away from zero for negative values.
* Note that ##trunc(x) + frac(x) = x##

===== Example 1:
<eucode>
a = trunc(9.4)
-- a is 9
</eucode>

===== Example 2:
<eucode>
s = trunc({81, -3.5, -9.999, 5.5})
-- s is {81,-3, -9, 5}
</eucode>
===== See Also:
[[:floor]] [[:frac]]


@[:math:frac|]
==== frac
<eucode>
include std/math.e
namespace math
public function frac(object x)
</eucode>

  returns the fractional portion of a number.

===== Parameters:
# ##value## : any Euphoria object.

===== Returns:
An **object**, the shape of which depends on ##values##'s. Each item in the
returned object will be the same corresponding items
in ##value## except with the integer portion removed.

===== Comments:
Note that ##trunc(x) + frac(x) = x##

===== Example 1:
<eucode>
a = frac(9.4)
-- a is 0.4
</eucode>

===== Example 2:
<eucode>
s = frac({81, -3.5, -9.999, 5.5})
-- s is {0, -0.5, -0.999, 0.5}
</eucode>

===== See Also:
[[:trunc]]


@[:math:intdiv|]
==== intdiv
<eucode>
include std/math.e
namespace math
public function intdiv(object a, object b)
</eucode>

  returns an integral division of two objects.

===== Parameters:
# ##divided## : any Euphoria object.
# ##divisor## : any Euphoria object.

===== Returns:
An **object**, which will be a sequence if either ##dividend## or ##divisor##
is a sequence.

===== Comments:
* This calculates how many non-empty sets when ##dividend## is divided by ##divisor##.
* The result's sign is the same as the ##dividend##'s sign.

===== Example 1:
<eucode>
object Tokens = 101
object MaxPerEnvelope = 5
integer Envelopes = intdiv( Tokens, MaxPerEnvelope) --> 21
</eucode>



@[:eu:floor|]
==== floor
<eucode>
<built-in> function floor(object value)
</eucode>

Rounds ##value## down to the next integer less than or equal to ##value##.

===== Parameters:
# ##value## : any Euphoria object; each atom in ##value## will be acted upon.

===== Comments:
It does not simply truncate the fractional part, but actually rounds towards
negative infinity.

===== Returns:
An **object**, the same shape as ##value## but with each item guarenteed to be
an integer less than or equal to the corresponding item in ##value##.

===== Example 1:
<eucode>
y = floor({0.5, -1.6, 9.99, 100})
-- y is {0, -2, 9, 100}
</eucode>

===== See Also:
[[:ceil]], [[:round]]


@[:math:ceil|]
==== ceil
<eucode>
include std/math.e
namespace math
public function ceil(object a)
</eucode>

  computes the next integer equal or greater than the argument.

===== Parameters:
# ##value## : an object, each atom of which processed, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##value##. Each atom in ##value##
is returned as an integer that is the smallest integer equal to or greater
than the corresponding atom in ##value##.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

##ceil(X)## is 1 more than ##floor(X)## for non-integers. For integers, ##X = floor(X) = ceil(X)##.

===== Example 1:
<eucode>
sequence nums
nums = {8, -5, 3.14, 4.89, -7.62, -4.3}
nums = ceil(nums) -- {8, -5, 4, 5, -7, -4}
</eucode>

===== See Also:
[[:floor]], [[:round]]


@[:math:round|]
==== round
<eucode>
include std/math.e
namespace math
public function round(object a, object precision = 1)
</eucode>

  returns the argument's elements rounded to some precision.

===== Parameters:
# ##value## : an object, each atom of which will be acted upon, no matter how deeply nested.
# ##precision## : an object, the rounding precision(s). If not passed, this defaults to 1.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, the result is that atom rounded to the nearest integer multiple of 1/##precision##.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

===== Example 1:
<eucode>
round(5.2) -- 5
round({4.12, 4.67, -5.8, -5.21}, 10) -- {4.1, 4.7, -5.8, -5.2}
round(12.2512, 100) -- 12.25
</eucode>

===== See Also:
[[:floor]], [[:ceil]]


=== Trigonometry


@[:eu:arctan|]
==== arctan
<eucode>
<built-in> function arctan(object tangent)
</eucode>

returns an angle with given tangent.

===== Parameters:
# ##tangent## : an object, each atom of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, of the same shape as ##tangent##. For each atom in ##flatten(tangent)##,
the angle with smallest magnitude that has this atom as tangent is computed.

===== Comments:
All atoms in the returned value lie between ##-PI/2## and ##PI/2##, exclusive.

This function may be applied to an atom or to all elements of a sequence (of sequence (...)).

##arctan## is faster than ##[[:arcsin]]## or ##[[:arccos]]##.

===== Example 1:
<eucode>
s = arctan({1,2,3})
-- s is {0.785398, 1.10715, 1.24905}
</eucode>
===== See Also:
[[:arcsin]], [[:arccos]], [[:tan]], [[:flatten]]


@[:eu:tan|]
==== tan
<eucode>
<built-in> function tan(object angle)
</eucode>

returns the tangent of an angle, or a sequence of angles.

===== Parameters:
# ##angle## : an object, each atom of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, of the same shape as ##angle##. Each atom in the flattened ##angle## is
replaced by its tangent.

===== Errors:
If any atom in ##angle## is an odd multiple of PI/2, an error occurs, as its tangent
would be infinite.

===== Comments:
This function may be applied to an atom or to all elements of a sequence of arbitrary
shape, recursively.

===== Example 1:
<eucode>
t = tan(1.0)
-- t is 1.55741
</eucode>
===== See Also:
[[:sin]], [[:cos]], [[:arctan]]


@[:eu:cos|]
==== cos
<eucode>
<built-in> function cos(object angle)
</eucode>

returns the cosine of an angle expressed in radians.

===== Parameters:
# ##angle## : an object, each atom of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##angle##. Each atom in ##angle## is turned into its cosine.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

The cosine of an angle is an atom between -1 and 1 inclusive. 0.0 is hit by odd multiples of ##PI/2## only.

===== Example 1:
<eucode>
x = cos({.5, .6, .7})
-- x is {0.8775826, 0.8253356, 0.7648422}
</eucode>

===== See Also:
[[:sin]], [[:tan]], [[:arccos]], [[:PI]], [[:deg2rad]]


@[:eu:sin|]
==== sin
<eucode>
<built-in> function sin(object angle)
</eucode>

returns the sine of an angle expressed in radians.

===== Parameters:
# ##angle## : an object, each atom in which will be acted upon.

===== Returns:
An **object**, the same shape as ##angle##. When ##angle## is an atom, the
result is the sine of ##angle##.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

The sine of an angle is an atom between -1 and 1 inclusive. 0.0 is hit by integer
multiples of ##PI## only.

===== Example 1:
<eucode>
sin_x = sin({.5, .9, .11})
-- sin_x is {.479, .783, .110}
</eucode>

===== See Also:
[[:cos]], [[:arcsin]], [[:PI]], [[:deg2rad]]


@[:math:arccos|]
==== arccos
<eucode>
include std/math.e
namespace math
public function arccos(trig_range x)
</eucode>

  returns an angle given its cosine.

===== Parameters:
# ##value## : an object, each atom in which will be acted upon.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, the result is
an atom, an angle whose cosine is ##value##.

===== Errors:
If any atom in ##value## is not in the -1..1 range, it cannot be the cosine of a real
number, and an error occurs.

===== Comments:

A value between 0 and [[:PI]] radians will be returned.

This function may be applied to an atom or to all elements of a sequence.

##arccos## is not as fast as [[:arctan]].

===== Example 1:
<eucode>
s = arccos({-1,0,1})
-- s is {3.141592654, 1.570796327, 0}
</eucode>

===== See Also:
[[:cos]], [[:PI]], [[:arctan]]


@[:math:arcsin|]
==== arcsin
<eucode>
include std/math.e
namespace math
public function arcsin(trig_range x)
</eucode>

  returns an angle given its sine.

===== Parameters:
# ##value## : an object, each atom in which will be acted upon.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, the result is an atom, an angle whose sine is ##value##.

===== Errors:
If any atom in ##value## is not in the -1..1 range, it cannot be the sine of a real number, and an error occurs.

===== Comments:
A value between ##-PI/2## and ##+PI/2## (radians) inclusive will be returned.

This function may be applied to an atom or to all elements of a sequence.

##arcsin## is not as fast as [[:arctan]].

===== Example 1:
<eucode>
s = arcsin({-1,0,1})
s is {-1.570796327, 0, 1.570796327}
</eucode>

===== See Also:
[[:arccos]], [[:arccos]], [[:sin]]


@[:math:atan2|]
==== atan2
<eucode>
include std/math.e
namespace math
public function atan2(atom y, atom x)
</eucode>

  calculate the arctangent of a ratio.

===== Parameters:
# ##y## : an atom, the numerator of the ratio
# ##x## : an atom, the denominator of the ratio

===== Returns:
An **atom**, which is equal to [[:arctan]](##y##/##x##), except that it can handle zero denominator and is more accurate.

===== Example 1:
<eucode>
a = atan2(10.5, 3.1)
-- a is 1.283713958
</eucode>

===== See Also:
[[:arctan]]


@[:math:rad2deg|]
==== rad2deg
<eucode>
include std/math.e
namespace math
public function rad2deg(object x)
</eucode>

  converts an angle measured in radians to an angle measured in degrees.

===== Parameters:
# ##angle## : an object, all atoms of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##angle##, all atoms of which were multiplied by ##180/PI##.

===== Comments:
This function may be applied to an atom or sequence. A flat angle is ##PI## radians and 180 degrees.

[[:arcsin]], [[:arccos]] and [[:arctan]] return angles in radians.

===== Example 1:
<eucode>
x = rad2deg(3.385938749)
-- x is 194
</eucode>

===== See Also:
[[:deg2rad]]


@[:math:deg2rad|]
==== deg2rad
<eucode>
include std/math.e
namespace math
public function deg2rad(object x)
</eucode>

  converts an angle measured in degrees to an angle measured in radians.

===== Parameters:
# ##angle## : an object, all atoms of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##angle##, all atoms of which were multiplied by ##PI/180##.

===== Comments:
This function may be applied to an atom or sequence. A flat angle is ##PI## radians and 180 degrees.
[[:sin]], [[:cos]] and [[:tan]] expect angles in radians.

===== Example 1:
<eucode>
x = deg2rad(194)
-- x is 3.385938749
</eucode>
===== See Also:
[[:rad2deg]]


=== Logarithms and Powers



@[:eu:log|]
==== log
<eucode>
<built-in> function log(object value)
</eucode>

returns the natural logarithm of a positive number.

===== Parameters:
# ##value## : an object, any atom of which ##log## acts upon.

===== Returns:
An **object**, the same shape as ##value##. For an atom, the returned atom is its logarithm of base E.

===== Errors:
If any atom in ##value## is not greater than zero, an error occurs as its logarithm is not defined.

===== Comments:
This function may be applied to an atom or to all elements
of a sequence.

To compute the inverse, you can use ##power(E, x)##
where E is 2.7182818284590452, or equivalently [[:exp]](x). Beware that the logarithm grows very slowly with x, so that [[:exp]] grows very fast.

===== Example 1:
<eucode>
a = log(100)
-- a is 4.60517
</eucode>
===== See Also:
[[:E]], [[:exp]], [[:log10]]



@[:math:log10|]
==== log10
<eucode>
include std/math.e
namespace math
public function log10(object x1)
</eucode>

  returns the base 10 logarithm of a number.

===== Parameters:
# ##value## : an object, each atom of which will be converted, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, raising 10 to the returned atom yields ##value## back.

===== Errors:
If any atom in ##value## is not greater than zero, its logarithm is not a real number and an error occurs.

===== Comments:
This function may be applied to an atom or to all elements
of a sequence.

##log10## is proportional to ##log## by a factor of ##1/log(10)##,
which is about ##0.435## .

===== Example 1:
<eucode>
a = log10(12)
-- a is 2.48490665
</eucode>

===== See Also:
[[:log]]


@[:math:exp|]
==== exp
<eucode>
include std/math.e
namespace math
public function exp(atom x)
</eucode>

  computes some power of E.

===== Parameters:
# ##value## : an object, all atoms of which will be acted upon, no matter how deeply nested.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, its exponential is being returned.

===== Comments:
This function can be applied to a single atom or to a sequence of any shape.

Due to its rapid growth, the returned values start losing accuracy as soon as values are greater than 10.  Values above 710 will cause an overflow in hardware.

===== Example 1:
<eucode>
x = exp(5.4)
-- x is 221.4064162
</eucode>
===== See Also:
[[:log]]


@[:eu:power|]
==== power
<eucode>
<built-in> function power(object base, object exponent)
</eucode>

raises a base value to some power.

===== Parameters:
# ##base## : an object, the value or values to raise to some power.
# ##exponent## : an object, the exponent or exponents to apply to ##base##.

===== Returns:
An **object**, the shape of which depends on ##base##'s and ##exponent##'s. For two atoms, this will be ##base## raised to the power ##exponent##.

===== Errors:
If some atom in ##base## is negative and is raised to a non integer exponent, an error will occur, as the result is undefined.

If 0 is raised to any negative power, this is the same as a zero divide and causes an error.

##power(0,0)## is illegal, because there is not an unique value that can be assigned to that quantity.

===== Comments:

The arguments to this function may be atoms or sequences. The rules for
[[:operations on sequences]] apply.

Powers of 2 are calculated very efficiently.

Other languages have a ##~**## or ##^## operator to perform the same action. But they do not have  sequences.

===== Example 1:
<eucode>
? power(5, 2)
-- 25 is printed
</eucode>

===== Example 2:
<eucode>
? power({5, 4, 3.5}, {2, 1, -0.5})
-- {25, 4, 0.534522} is printed
</eucode>

===== Example 3:
<eucode>
? power(2, {1, 2, 3, 4})
-- {2, 4, 8, 16}
</eucode>

===== Example 4:
<eucode>
? power({1, 2, 3, 4}, 2)
-- {1, 4, 9, 16}
</eucode>

===== See Also:
[[:log]], [[:Operations on sequences]]


@[:eu:sqrt|]
==== sqrt
<eucode>
<built-in> function sqrt(object value)
</eucode>

calculates the square root of a number.

===== Parameters:
# ##value## : an object, each atom in which will be acted upon.

===== Returns:
An **object**, the same shape as ##value##. When ##value## is an atom, the result is the positive atom whose square is ##value##.

===== Errors:
If any atom in ##value## is less than zero, an error will occur, as no squared real can be less than zero.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

===== Example 1:
<eucode>
r = sqrt(16)
-- r is 4
</eucode>

===== See Also:
[[:power]], [[:Operations on sequences]]



@[:math:fib|]
==== fib
<eucode>
include std/math.e
namespace math
public function fib(integer i)
</eucode>

  computes the nth Fibonacci Number.

===== Parameters:
# ##value## : an integer. The starting value to compute a Fibonacci Number from.

===== Returns:
An **atom**,
* The Fibonacci Number specified by value.

===== Comments:
* Note that due to the limitations of the floating point implementation,
only 'i' values less than 76 are accurate on //Windows// platforms, and
69 on other platforms (due to rounding differences in the native C
runtime libraries).

===== Example 1:
<eucode>
  ? fib(6)
-- output ... 
-- 8
</eucode>



=== Hyperbolic Trigonometry



@[:math:cosh|]
==== cosh
<eucode>
include std/math.e
namespace math
public function cosh(object a)
</eucode>

  computes the hyperbolic cosine of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Comments:

The hyperbolic cosine grows like the exponential function.

For all reals, ##power(cosh(x), 2) - power(sinh(x), 2) = 1##. Compare
with ordinary trigonometry.

===== Example 1:
<eucode>
? cosh(LN2) -- prints out 1.25
</eucode>

===== See Also:
[[:cos]], [[:sinh]], [[:arccosh]]


@[:math:sinh|]
==== sinh
<eucode>
include std/math.e
namespace math
public function sinh(object a)
</eucode>

  computes the hyperbolic sine of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Comments:

The hyperbolic sine grows like the exponential function.

For all reals, ##power(cosh(x), 2) - power(sinh(x), 2) = 1##. Compare
with ordinary trigonometry.

===== Example 1:
<eucode>
? sinh(LN2) -- prints out 0.75
</eucode>

===== See Also:
[[:cosh]], [[:sin]], [[:arcsinh]]


@[:math:tanh|]
==== tanh
<eucode>
include std/math.e
namespace math
public function tanh(object a)
</eucode>

  computes the hyperbolic tangent of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Comments:

The hyperbolic tangent takes values from -1 to +1.

##tanh## is the ratio ##sinh / cosh##. Compare with ordinary trigonometry.

===== Example 1:
<eucode>
? tanh(LN2) -- prints out 0.6
</eucode>

===== See Also:
[[:cosh]], [[:sinh]], [[:tan]], [[:arctanh]]


@[:math:arcsinh|]
==== arcsinh
<eucode>
include std/math.e
namespace math
public function arcsinh(object a)
</eucode>

  computes the reverse hyperbolic sine of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Comments:

The hyperbolic sine grows like the logarithm function.

===== Example 1:
<eucode>
? arcsinh(1) -- prints out 0,4812118250596034
</eucode>

===== See Also:
[[:arccosh]], [[:arcsin]], [[:sinh]]


@[:math:arccosh|]
==== arccosh
<eucode>
include std/math.e
namespace math
public function arccosh(not_below_1 a)
</eucode>

  computes the reverse hyperbolic cosine of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Errors:
Since [[:cosh]] only takes values not below 1, an argument below 1 causes an error.

===== Comments:

The hyperbolic cosine grows like the logarithm function.

===== Example 1:
<eucode>
? arccosh(1) -- prints out 0
</eucode>

===== See Also:
[[:arccos]], [[:arcsinh]], [[:cosh]]


@[:math:arctanh|]
==== arctanh
<eucode>
include std/math.e
namespace math
public function arctanh(abs_below_1 a)
</eucode>

  computes the reverse hyperbolic tangent of an object.

===== Parameters:
# ##x## : the object to process.

===== Returns:
An **object**, the same shape as ##x##, each atom of which was acted upon.

===== Errors:
Since [[:tanh]] only takes values between -1 and +1 excluded, an out of range argument causes an error.

===== Comments:

The hyperbolic cosine grows like the logarithm function.

===== Example 1:
<eucode>
? arctanh(1/2) -- prints out 0,5493061443340548456976
</eucode>

===== See Also:
[[:arccos]], [[:arcsinh]], [[:cosh]]


=== Accumulation



@[:math:sum|]
==== sum
<eucode>
include std/math.e
namespace math
public function sum(object a)
</eucode>

  computes the sum of all atoms in the argument, no matter how deeply nested.

===== Parameters:
# ##values## : an object, all atoms of which will be added up, no matter how nested.

===== Returns:
An **atom**, the sum of all atoms in [[:flatten]](##values##).

===== Comments:
This function may be applied to an atom or to all elements of a sequence.

===== Example 1:
<eucode>
a = sum({10, 20, 30})
-- a is 60

a = sum({10.5, {11.2} , 8.1})
-- a is 29.8
</eucode>

===== See Also:
[[:product]], [[:or_all]]


@[:math:product|]
==== product
<eucode>
include std/math.e
namespace math
public function product(object a)
</eucode>

  computes the product of all the atom in the argument, no matter how deeply nested.

===== Parameters:
# ##values## : an object, all atoms of which will be multiplied up, no matter how nested.

===== Returns:
An **atom**, the product of all atoms in [[:flatten]](##values##).

===== Comments:
This function may be applied to an atom or to all elements of a sequence

===== Example 1:
<eucode>
a = product({10, 20, 30})
-- a is 6000

a = product({10.5, {11.2} , 8.1})
-- a is 952.56
</eucode>

===== See Also:
[[:sum]], [[:or_all]]


@[:math:or_all|]
==== or_all
<eucode>
include std/math.e
namespace math
public function or_all(object a)
</eucode>

  or's together all atoms in the argument, no matter how deeply nested.

===== Parameters:
# ##values## : an object, all atoms of which will be added up, no matter how nested.

===== Returns:
An **atom**, the result of bitwise or of all atoms in [[:flatten]](##values##).

===== Comments:

This function may be applied to an atom or to all elements of a sequence. It performs [[:or_bits]] operations repeatedly.

===== Example 1:
<eucode>
a = or_all({10, 7, 35})
-- a is 47 
-- To see why notice:
-- 10=0b1010, 7=0b111 and 35=0b100011.
-- combining these gives:
--               0b001010
--      (or_bits)0b000111
--               0b100011
--               --------
--               0b101111 = 47
</eucode>

===== See Also:
[[:sum]], [[:product]], [[:or_bits]]


=== Bitwise Operations



@[:eu:and_bits|]
==== and_bits
<eucode>
<built-in> function and_bits(object a, object b)
</eucode>

performs the bitwise AND operation on corresponding bits in two objects. A bit in the
result will be 1 only if the corresponding bits in both arguments are 1.

===== Parameters:
# ##a## : one of the objects involved
# ##b## : the second object

===== Returns:
An **object**, whose shape depends on the shape of both arguments. Each atom in this object
is obtained by bitwise AND between atoms on both objects.

===== Comments:

The arguments to this function may be atoms or sequences. The rules for operations on sequences apply.
The atoms in the arguments must be representable as 32-bit numbers, either signed or unsigned.

If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits.

Results are treated as signed numbers. They will be negative when the highest-order bit is 1.

To understand the binary representation of a number you should display it in hexadecimal notation.
Use the %x format of [[:printf]]. Using [[:int_to_bits]] is an even more direct approach.

===== Example 1:
<eucode>
 a = and_bits(#0F0F0000, #12345678)
-- a is #02040000
</eucode>

===== Example 2:
<eucode>
 a = and_bits(#FF, {#123456, #876543, #2211})
-- a is {#56, #43, #11}
</eucode>

===== Example 3:
<eucode>
 a = and_bits(#FFFFFFFF, #FFFFFFFF)
-- a is -1
-- Note that #FFFFFFFF is a positive number,
-- but the result of a bitwise operation is interpreted
-- as a signed 32-bit number, so it's negative.
</eucode>

===== See Also:
[[:or_bits]], [[:xor_bits]], [[:not_bits]], [[:int_to_bits]]



@[:eu:xor_bits|]
==== xor_bits
<eucode>
<built-in> function xor_bits(object a, object b)
</eucode>

performs the bitwise XOR operation on corresponding bits in two objects. A bit in the
result will be 1 only if the corresponding bits in both arguments are different.

===== Parameters:
# ##a## : one of the objects involved
# ##b## : the second object

===== Returns:
An **object**, whose shape depends on the shape of both arguments. Each atom in this object
is obtained by bitwisel XOR between atoms on both objects.

===== Comments:
The arguments must be representable as 32-bit numbers, either signed or unsigned.

If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits.

Results are treated as signed numbers. They will be negative when the highest-order bit is 1.

===== Example 1:
<eucode>
 a = xor_bits(#0110, #1010)
-- a is #1100
</eucode>

===== See Also:
[[:and_bits]], [[:or_bits]], [[:not_bits]], [[:int_to_bits]]


@[:eu:or_bits|]
==== or_bits
<eucode>
<built-in> function or_bits(object a, object b)
</eucode>

performs the bitwise OR operation on corresponding bits in two objects. A bit in the
result will be 1 only if the corresponding bits in both arguments are both 0.

===== Parameters:
# ##a## : one of the objects involved
# ##b## : the second object

===== Returns:
An **object**, whose shape depends on the shape of both arguments. Each atom in this object
is obtained by bitwise OR between atoms on both objects.

===== Comments:
The arguments must be representable as 32-bit numbers, either signed or unsigned.

If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits.

Results are treated as signed numbers. They will be negative when the highest-order bit is 1.

===== Example 1:
<eucode>
 a = or_bits(#0F0F0000, #12345678)
-- a is #1F3F5678
</eucode>

===== Example 2:
<eucode>
 a = or_bits(#FF, {#123456, #876543, #2211})
-- a is {#1234FF, #8765FF, #22FF}
</eucode>

===== See Also:
[[:and_bits]], [[:xor_bits]], [[:not_bits]], [[:int_to_bits]]


@[:eu:not_bits|]
==== not_bits
<eucode>
<built-in> function not_bits(object a)
</eucode>

performs the bitwise NOT operation on each bit in an object. A bit in the result will be 1
when the corresponding bit in x1 is 0, and will be 0 when the corresponding bit in x1 is 1.

===== Parameters:
# ##a## : the object to invert the bits of.

===== Returns:
An **object**, the same shape as ##a##. Each bit in an atom of the result is the reverse of the corresponding bit inside ##a##.

===== Comments:
The argument to this function may be an atom or a sequence.

The argument must be representable as a 32-bit number, either signed or unsigned.

If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits.

Results are treated as signed numbers. They will be negative when the highest-order bit is 1.

A simple equality holds for an atom ##a##: ##a + not_bits(a) = -1##.

===== Example 1:
<eucode>
 a = not_bits(#000000F7)
-- a is -248 (i.e. FFFFFF08 interpreted as a negative number)
</eucode>

===== See Also:
[[:and_bits]], [[:or_bits]], [[:xor_bits]], [[:int_to_bits]]


@[:math:shift_bits|]
==== shift_bits
<eucode>
include std/math.e
namespace math
public function shift_bits(object source_number, integer shift_distance)
</eucode>

  moves the bits in the input value by the specified distance.

===== Parameters:
# ##source_number## : object: The value or values whose bits will be be moved.
# ##shift_distance## : integer: number of bits to be moved by.
===== Comments:
* If ##source_number## is a sequence, each element is shifted.
* The value or values in ##source_number## are first truncated to a 32-bit integer.
* The output is truncated to a 32-bit integer.
* Vacated bits are replaced with zero.
* If ##shift_distance## is negative, the bits in ##source_number## are moved left.
* If ##shift_distance## is positive, the bits in ##source_number## are moved right.
* If ##shift_distance## is zero, the bits in ##source_number## are not moved.

===== Returns:
Atom or atoms containing a 32-bit integer. A single atom in ##source_number## is an atom, or
a sequence in the same form as ##source_number## containing 32-bit integers.

===== Example 1:
<eucode>
? shift_bits((7, -3) --> 56
? shift_bits((0, -9) --> 0
? shift_bits((4, -7) --> 512
? shift_bits((8, -4) --> 128
? shift_bits((0xFE427AAC, -7) --> 0x213D5600
? shift_bits((-7, -3) --> -56  which is 0xFFFFFFC8 
? shift_bits((131, 0) --> 131
? shift_bits((184.464, 0) --> 184
? shift_bits((999_999_999_999_999, 0) --> -1530494977 which is 0xA4C67FFF
? shift_bits((184, 3) -- 23
? shift_bits((48, 2) --> 12
? shift_bits((121, 3) --> 15
? shift_bits((0xFE427AAC, 7) -->  0x01FC84F5
? shift_bits((-7, 3) --> 0x1FFFFFFF
? shift_bits({48, 121}, 2) --> {12, 30}
</eucode>

===== See Also:
[[:rotate_bits]]


@[:math:rotate_bits|]
==== rotate_bits
<eucode>
include std/math.e
namespace math
public function rotate_bits(object source_number, integer shift_distance)
</eucode>

  rotates the bits in the input value by the specified distance.

===== Parameters:
# ##source_number## : object: value or values whose bits will be be rotated.
# ##shift_distance## : integer: number of bits to be moved by.
===== Comments:
* If ##source_number## is a sequence, each element is rotated.
* The value(s) in ##source_number## are first truncated to a 32-bit integer.
* The output is truncated to a 32-bit integer.
* If ##shift_distance## is negative, the bits in ##source_number## are rotated left.
* If ##shift_distance## is positive, the bits in ##source_number## are rotated right.
* If ##shift_distance## is zero, the bits in ##source_number## are not rotated.

===== Returns:
Atom or atoms containing a 32-bit integer. A single atom in ##source_number## is an atom, or
a sequence in the same form as ##source_number## containing 32-bit integers.

===== Example 1:
<eucode>
? rotate_bits(7, -3) --> 56
? rotate_bits(0, -9) --> 0
? rotate_bits(4, -7) --> 512
? rotate_bits(8, -4) --> 128
? rotate_bits(0xFE427AAC, -7) --> 0x213D567F
? rotate_bits(-7, -3) --> -49  which is 0xFFFFFFCF 
? rotate_bits(131, 0) --> 131
? rotate_bits(184.464, 0) --> 184
? rotate_bits(999_999_999_999_999, 0) --> -1530494977 which is 0xA4C67FFF
? rotate_bits(184, 3) -- 23
? rotate_bits(48, 2) --> 12
? rotate_bits(121, 3) --> 536870927
? rotate_bits(0xFE427AAC, 7) -->  0x59FC84F5
? rotate_bits(-7, 3) --> 0x3FFFFFFF
? rotate_bits({48, 121}, 2) --> {12, 1073741854}
</eucode>

===== See Also:
[[:shift_bits]]


Arithmetic



@[:math:gcd|]
==== gcd
<eucode>
include std/math.e
namespace math
public function gcd(atom p, atom q)
</eucode>

  returns the greater common divisor of to atoms.

===== Parameters:
# ##p## : one of the atoms to consider
# ##q## : the other atom.

===== Returns:
A positive **integer**, which is the largest value that evenly divides
into both parameters.

===== Comments:

* Signs are ignored. Atoms are rounded down to integers.
* If both parameters are zero, 0 is returned.
* If one parameter is zero, the other parameter is returned.

Parameters and return value are atoms so as to take mathematical integers up to ##power(2,53)##.

===== Example 1:
<eucode>
? gcd(76.3, -114) --> 38
? gcd(0, -114) --> 114
? gcd(0, 0) --> 0 (This is often regarded as an error condition)
</eucode>



Floating Point



@[:math:approx|]
==== approx
<eucode>
include std/math.e
namespace math
public function approx(object p, object q, atom epsilon = 0.005)
</eucode>

  compares two (sets of) numbers based on approximate equality.

===== Parameters:
# ##p## : an object, one of the sets to consider
# ##q## : an object, the other set.
# ##epsilon## : an atom used to define the amount of inequality allowed.
This must be a positive value. Default is 0.005

===== Returns:
An **integer**,
* 1 when p > (q + epsilon) : P is definitely greater than q.
* -1 when p < (q - epsilon) : P is definitely less than q.
* 0 when p >= (q - epsilon) and p <= (q + epsilon) : p and q are approximately equal.

===== Comments:
This can be used to see if two numbers are near enough to each other.

Also, because of the way floating point numbers are stored, it not always possible
express every real number exactly, especially after a series of arithmetic
operations. You can use ##approx## to see if two floating point numbers
are almost the same value.

If ##p## and ##q## are both sequences, they must be the same length as each other.

If ##p## or ##q## is a sequence, but the other is not, then the result is a
sequence of results whose length is the same as the sequence argument.

===== Example 1:
<eucode>
? approx(10, 33.33 * 30.01 / 100) 
          --> 0 because 10 and 10.002333 are within 0.005 of each other
? approx(10, 10.001) 
          --> 0 because 10 and 10.001 are within 0.005 of each other
? approx(10, {10.001,9.999, 9.98, 10.04}) 
          --> {0,0,1,-1}
? approx({10.001,9.999, 9.98, 10.04}, 10) 
          --> {0,0,-1,1}
? approx({10.001,{9.999, 10.01}, 9.98, 10.04}, {10.01,9.99, 9.8, 10.4}) 
          --> {-1,{1,1},1,-1}
? approx(23,32, 10) 
          --> 0 because 23 and 32 are within 10 of each other.
</eucode>



@[:math:powof2|]
==== powof2
<eucode>
include std/math.e
namespace math
public function powof2(object p)
</eucode>

  tests for power of 2.

===== Parameters:
# ##p## : an object. The item to test. This can be an integer, atom or sequence.

===== Returns:
An **integer**,
* 1 for each item in ##p## that is a power of two (like ## 2,4,8,16,32, ...##)
* 0 for each item in ##p## that is **not** a power of two (like ##3, 54.322, -2##)

===== Example 1:
<eucode>
for i = 1 to 10 do
  ? {i, powof2(i)}
end for
-- output ... 
-- {1,1}
-- {2,1}
-- {3,0}
-- {4,1}
-- {5,0}
-- {6,0}
-- {7,0}
-- {8,1}
-- {9,0}
-- {10,0}
</eucode>



@[:math:is_even|]
==== is_even
<eucode>
include std/math.e
namespace math
public function is_even(integer test_integer)
</eucode>

  tests if the supplied integer is a even or odd number.

===== Parameters:
# ##test_integer## : an integer. The item to test.

===== Returns:
An **integer**,
* 1 if its even.
* 0 if its odd.

===== Example 1:
<eucode>
for i = 1 to 10 do
  ? {i, is_even(i)}
end for
-- output ... 
-- {1,0}
-- {2,1}
-- {3,0}
-- {4,1}
-- {5,0}
-- {6,1}
-- {7,0}
-- {8,1}
-- {9,0}
-- {10,1}
</eucode>



@[:math:is_even_obj|]
==== is_even_obj
<eucode>
include std/math.e
namespace math
public function is_even_obj(object test_object)
</eucode>

  tests if the supplied Euphoria object is even or odd.

===== Parameters:
# ##test_object## : any Euphoria object. The item to test.

===== Returns:
An **object**,
* If ##test_object## is an integer...
** 1 if its even.
** 0 if its odd.
* Otherwise if ##test_object## is an atom this always returns 0
* otherwise if ##test_object## is an sequence it tests each element recursively, returning a
sequence of the same structure containing ones and zeros for each element. A
1 means that the element at this position was even otherwise it was odd.

===== Example 1:
<eucode>
for i = 1 to 5 do
  ? {i, is_even_obj(i)}
end for
-- output ... 
-- {1,0}
-- {2,1}
-- {3,0}
-- {4,1}
-- {5,0}
</eucode>

===== Example 2:
<eucode>
? is_even_obj(3.4) --> 0 
</eucode>

===== Example 3:
<eucode>
? is_even_obj({{1,2,3}, {{4,5},6,{7,8}},9}) --> {{0,1,0},{{1,0},1,{0,1}},0}
</eucode>




!!CONTEXT:../include/std/mathcons.e
!!namespace:mathcons
%%output = std_mathcons

== Math Constants

<<LEVELTOC level=2 depth=4>>



=== Constants



@[:mathcons:PI|]
==== PI
<eucode>
include std/mathcons.e
namespace mathcons
public constant PI
</eucode>

 PI is the ratio of a circle's circumference to it's diameter.

PI = C / D  :: C = PI * D :: C = PI * 2 * R(radius)




@[:mathcons:QUARTPI|]
==== QUARTPI
<eucode>
include std/mathcons.e
namespace mathcons
public constant QUARTPI
</eucode>

Quarter of PI




@[:mathcons:HALFPI|]
==== HALFPI
<eucode>
include std/mathcons.e
namespace mathcons
public constant HALFPI
</eucode>

Half of PI




@[:mathcons:TWOPI|]
==== TWOPI
<eucode>
include std/mathcons.e
namespace mathcons
public constant TWOPI
</eucode>

Two times PI




@[:mathcons:PISQR|]
==== PISQR
<eucode>
include std/mathcons.e
namespace mathcons
public constant PISQR
</eucode>

PI ^ 2




@[:mathcons:INVSQ2PI|]
==== INVSQ2PI
<eucode>
include std/mathcons.e
namespace mathcons
public constant INVSQ2PI
</eucode>

1 / (sqrt(2PI))




@[:mathcons:PHI|]
==== PHI
<eucode>
include std/mathcons.e
namespace mathcons
public constant PHI
</eucode>

phi  => Golden Ratio = (1 + sqrt(5)) / 2




@[:mathcons:E|]
==== E
<eucode>
include std/mathcons.e
namespace mathcons
public constant E
</eucode>

 Euler (e)The base of the natural logarithm.




@[:mathcons:LN2|]
==== LN2
<eucode>
include std/mathcons.e
namespace mathcons
public constant LN2
</eucode>

ln(2) :: 2 = power(E, LN2)




@[:mathcons:INVLN2|]
==== INVLN2
<eucode>
include std/mathcons.e
namespace mathcons
public constant INVLN2
</eucode>

1 / (ln(2))




@[:mathcons:LN10|]
==== LN10
<eucode>
include std/mathcons.e
namespace mathcons
public constant LN10
</eucode>

ln(10) :: 10 = power(E, LN10)




@[:mathcons:INVLN10|]
==== INVLN10
<eucode>
include std/mathcons.e
namespace mathcons
public constant INVLN10
</eucode>

1 / ln(10)




@[:mathcons:SQRT2|]
==== SQRT2
<eucode>
include std/mathcons.e
namespace mathcons
public constant SQRT2
</eucode>

sqrt(2)




@[:mathcons:HALFSQRT2|]
==== HALFSQRT2
<eucode>
include std/mathcons.e
namespace mathcons
public constant HALFSQRT2
</eucode>

sqrt(2)/ 2




@[:mathcons:SQRT3|]
==== SQRT3
<eucode>
include std/mathcons.e
namespace mathcons
public constant SQRT3
</eucode>

Square root of 3




@[:mathcons:DEGREES_TO_RADIANS|]
==== DEGREES_TO_RADIANS
<eucode>
include std/mathcons.e
namespace mathcons
public constant DEGREES_TO_RADIANS
</eucode>

Conversion factor: Degrees to Radians = PI / 180




@[:mathcons:RADIANS_TO_DEGREES|]
==== RADIANS_TO_DEGREES
<eucode>
include std/mathcons.e
namespace mathcons
public constant RADIANS_TO_DEGREES
</eucode>

Conversion factor: Radians to Degrees = 180 / PI




@[:mathcons:EULER_GAMMA|]
==== EULER_GAMMA
<eucode>
include std/mathcons.e
namespace mathcons
public constant EULER_GAMMA
</eucode>

Gamma (Euler Gamma)




@[:mathcons:SQRTE|]
==== SQRTE
<eucode>
include std/mathcons.e
namespace mathcons
public constant SQRTE
</eucode>

sqrt(e)




@[:mathcons:PINF|]
==== PINF
<eucode>
include std/mathcons.e
namespace mathcons
public constant PINF
</eucode>

Positive Infinity






@[:mathcons:MINF|]
==== MINF
<eucode>
include std/mathcons.e
namespace mathcons
public constant MINF
</eucode>

Negative Infinity




@[:mathcons:SQRT5|]
==== SQRT5
<eucode>
include std/mathcons.e
namespace mathcons
public constant SQRT5
</eucode>

sqrt(5)





!!CONTEXT:../include/std/rand.e
!!namespace:random
%%output = std_rand

== Random Numbers

<<LEVELTOC level=2 depth=4>>



@[:eu:rand|]
==== rand
<eucode>
<built-in> function rand(object maximum)
</eucode>

returns a random integral value.

===== Parameters:
# ##maximum## : an atom, a cap on the value to return.

===== Returns:
An **atom**, from 1 to ##maximum##.

===== Comments:
* The minimum value of ##maximum## is 1.
* The maximum value that can possibly be returned is ###FFFFFFFF## (##4_294_967_295##)
* This function may be applied to an atom or to all elements of a sequence.
* In order to get reproducible results from this function, you should call
[[:set_rand]] with a reproducible value prior.

===== Example 1:
<eucode>
s = rand({10, 20, 30})
-- s might be: {5, 17, 23} or {9, 3, 12} etc.
</eucode>

===== See Also:
[[:set_rand]], [[:ceil]]


@[:random:rand_range|]
==== rand_range
<eucode>
include std/rand.e
namespace random
public function rand_range(atom lo, atom hi)
</eucode>

  returns a random integer from a specified inclusive integer range.

===== Parameters:
# ##lo## : an atom, the lower bound of the range
# ##hi## : an atom, the upper bound of the range.

===== Returns:
An **atom**, randomly drawn between ##lo## and ##hi## inclusive.

===== Comments:
This function may be applied to an atom or to all elements of a sequence.
In order to get reproducible results from this function, you should
call ##set_rand## with a reproducible value prior.

===== Example 1:
<eucode>
s = rand_range(18, 24)
-- s could be any of: 18, 19, 20, 21, 22, 23 or 24
</eucode>

===== See Also:
[[:rand]], [[:set_rand]], [[:rnd]]


@[:random:rnd|]
==== rnd
<eucode>
include std/rand.e
namespace random
public function rnd()
</eucode>

  returns a random floating point number in the range 0 to 1.

===== Parameters:
None.

===== Returns:
An **atom**, randomly drawn between 0.0 and 1.0 inclusive.

===== Comments:
In order to get reproducible results from this function, you should
call ##set_rand## with a reproducible value prior to calling this.

===== Example 1:
<eucode>
set_rand(1001)
s = rnd()
  -- s is 0.6277338201
</eucode>

===== See Also:
[[:rand]], [[:set_rand]], [[:rand_range]]


@[:random:rnd_1|]
==== rnd_1
<eucode>
include std/rand.e
namespace random
public function rnd_1()
</eucode>

  returns a random floating point number in the range 0 to less than 1.

===== Parameters:
None.

===== Returns:
An **atom**, randomly drawn between 0.0 and a number less than 1.0

===== Comments:
In order to get reproducible results from this function, you should
call ##set_rand## with a reproducible value prior to calling this.

===== Example 1:
<eucode>
set_rand(1001)
s = rnd_1()
  -- s is 0.6277338201
</eucode>

===== See Also:
[[:rand]], [[:set_rand]], [[:rand_range]]


@[:random:set_rand|]
==== set_rand
<eucode>
include std/rand.e
namespace random
public procedure set_rand(object seed)
</eucode>

  resets the random number generator.

===== Parameters:
# ##seed## : an object. The generator uses this initialize itself for the next
random number generated. This can be a single integer or atom,
or a sequence of two integers, or an empty sequence or any
other sort of sequence.

===== Comments:
* Starting from a ##seed##, the values returned by ##rand## are
reproducible. This is useful for demos and stress tests based on random
data. Normally the numbers returned by the ##rand## function are totally
unpredictable, and will be different each time you run your program.
Sometimes however you may wish to repeat the same series of numbers,
perhaps because you are trying to debug your program, or maybe you want
the ability to generate the same output (for example random picture) for your
user upon request.
* Internally there are actually two seed values.
** When ##set_rand## is called with a single integer or atom, the two
internal seeds are derived from the parameter.
** When ##set_rand## is called with a sequence of exactly two integers or atoms
the internal seeds are set to the parameter values.
** When ##set_rand## is called with an empty sequence, the internal seeds are
set to random values and are unpredictable. This is how to reset the generator.
** When ##set_rand## is called with any other sequence, the internal seeds are
set based on the length of the sequence and the hashed value of the sequence.
* Aside from an empty ##seed## parameter, this sets the generator to a known state
and the random numbers generated after come in a predicable order, though they still
appear to be random.

===== Example 1:
<eucode>
 sequence s, t
s = repeat(0, 3)
t = s

set_rand(12345)
s[1] = rand(10)
s[2] = rand(100)
s[3] = rand(1000)

set_rand(12345)  -- same value for set_rand()
t[1] = rand(10)  -- same arguments to rand() as before
t[2] = rand(100)
t[3] = rand(1000)
-- at this point s and t will be identical
set_rand("") -- Reset the generator to an unknown seed.
t[1] = rand(10)  -- Could be anything now, no way to predict it.
</eucode>

===== See Also:
[[:rand]]


@[:random:get_rand|]
==== get_rand
<eucode>
include std/rand.e
namespace random
public function get_rand()
</eucode>

  retrieves the current values of the random generator's seeds.

===== Returns:
a sequence. A 2-element sequence containing the values of the two internal seeds.

===== Comments:
You can use this to save the current seed values so that you can later reset them
back to a known state.

===== Example 1:
<eucode>
 sequence seeds
 seeds = get_rand()
 some_func() -- Which might set the seeds to anything.
 set_rand(seeds) -- reset them back to whatever they were
                 -- before calling 'some_func()'.
</eucode>

===== See Also:
[[:set_rand]]


@[:random:chance|]
==== chance
<eucode>
include std/rand.e
namespace random
public function chance(atom my_limit, atom top_limit = 100)
</eucode>

  simulates the probability of a desired outcome.

===== Parameters:
# ##my_limit## : an atom. The desired chance of something happening.
# ##top_limit##: an atom. The maximum chance of something happening. The
default is 100.

===== Returns:
an integer. 1 if the desired chance happened otherwise 0.

===== Comments:
This simulates the chance of something happening. For example, if you
wnat something to happen with a probablity of 25 times out of 100 times then you code ##chance(25)##
and if you want something to (most likely) occur 345 times out of 999 times, you code
##chance(345, 999)##.

===== Example 1:
<eucode>
 -- 65% of the days are sunny, so ...
 if chance(65) then
     puts(1, "Today will be a sunny day")
 elsif chance(40) then
     -- And 40% of non-sunny days it will rain.
     puts(1, "It will rain today")
 else
     puts(1, "Today will be a overcast day")
 end if
</eucode>

===== See Also:
[[:rnd]], [[:roll]]


@[:random:roll|]
==== roll
<eucode>
include std/rand.e
namespace random
public function roll(object desired, integer sides = 6)
</eucode>

  simulates the probability of a dice throw.

===== Parameters:
# ##desired## : an object. One or more desired outcomes.
# ##sides##: an integer. The number of sides on the dice. Default is 6.

===== Returns:
an integer. 0 if none of the desired outcomes occured, otherwise
the face number that was rolled.

===== Comments:
The minimum number of sides is two and there is no maximum.

===== Example 1:
<eucode>
res = roll(1, 2) 
      --> Simulate a coin toss.
res = roll({1,6}) 
      --> Try for a 1 or a 6 from a standard die toss.
res = roll({1,2,3,4}, 20) 
      --> Looking for any number under 5 from a 20-sided die.
</eucode>

===== See Also:
[[:rnd]], [[:chance]]


@[:random:sample|]
==== sample
<eucode>
include std/rand.e
namespace random
public function sample(sequence population, integer sample_size, integer sampling_method = 0)
</eucode>

  selects a set of random samples from a population set.

===== Parameters:
# ##population## : a sequence. The set of items from which to take a sample.
# ##sample_size##: an integer. The number of samples to take.
# ##sampling_method##: an integer.
## When < 0, "with-replacement" method used.
## When = 0, "without-replacement" method used and a single set of samples returned.
## When > 0, "without-replacement" method used and a sequence containing the
set of samples (chosen items) and the set unchosen items, is returned.

===== Returns:
A sequence. When ##sampling_method## less than or equal to 0 then this is
the set of samples, otherwise it returns a two-element sequence; the first
is the samples, and the second is the remainder of the population
(in the original order).

===== Comments:
Selects a set of random samples from a population set. This can be done with either
the "with-replacement" or "without-replacement" methods. When using the "with-replacement"
method, after each sample is taken it is returned to the population set so that it
could possible be taken again. The "without-replacement" method does not return the sample so
these items can only ever be chosen once.

* If ##sample_size## is less than ##1## , an empty set is returned.
* When using "without-replacement" method, if ##sample_size## is greater than
or equal to the population count, the entire population set is returned,
but in a random order.
* When using "with-replacement" method, if ##sample_size## can be any positive
integer, thus it is possible to return more samples than there are items in
the population set as items can be chosen more than once.

===== Example 1:
<eucode>
-- without replacement

set_rand("example")
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 1)})  
     --> "t"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 5)})  
     --> "flukq"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", -1)}) 
     --> ""
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 26)}) 
     --> "kghrsxmjoeubaywlzftcpivqnd"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 25)}) 
    --> "omntrqsbjguaikzywvxflpedc"
</eucode>

===== Example 2:
<eucode>
-- with replacement

set_rand("example")
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 1, -1)})  
     --> "t"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 5, -1)})  
     --> "fzycn"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", -1, -1)}) 
     --> ""
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 26, -1)}) 
     --> "keeamenuvvfyelqapucerghgfa"
printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 45, -1)}) 
    --> "orwpsaxuwuyrbstqqwfkykujukuzkkuxvzvzniinnpnxm"
</eucode>

===== Example 3:
<eucode>
-- Deal 4 hands of 5 cards from a standard deck of cards.
sequence theDeck
sequence hands = {}
sequence rt
function new_deck(integer suits = 4, integer cards_per_suit = 13, integer wilds = 0)
	sequence nd = {}
	for i = 1 to suits do
		for j = 1 to cards_per_suit do
			nd = append(nd, {i,j})
		end for
	end for
 for i = 1 to wilds do
     nd = append(nd, {suits+1 , i})
 end for
	return nd
end function

theDeck = new_deck(4, 13, 2) -- Build the initial deck of cards
for i = 1 to 4 do
 -- Pick out 5 cards and also return the remaining cards.
	rt = sample(theDeck, 5, 1)
	theDeck = rt[2] -- replace the 'deck' with the remaining cards.
	hands = append(hands, rt[1])
end for

</eucode>



!!CONTEXT:../include/std/stats.e
!!namespace:stats
%%output = std_stats

== Statistics

<<LEVELTOC level=2 depth=4>>

=== Routines


@[:stats:small|]
==== small
<eucode>
include std/stats.e
namespace stats
public function small(sequence data_set, integer ordinal_idx)
</eucode>

  determines the k-th smallest value from the supplied set of numbers.

===== Parameters:
# ##data_set## : The list of values from which the smallest value is chosen.
# ##ordinal_idx## : The relative index of the desired smallest value.

===== Returns:
A **sequence**, ##{The k-th smallest value, its index in the set}##.

===== Comments:
##small## is used to return a value based on its size relative to
all the other elements in the sequence. When ##index## is 1, the smallest index is returned. Use ##index = length(data_set)## to return the highest.

If ##ordinal_idx## is less than one, or greater then length of ##data_set##,
an empty sequence is returned.

The set of values does not have to be in any particular order. The values may be any Euphoria object.

===== Example 1:
<eucode>
small( {4,5,6,8,5,4,3,"text"}, 3 ) 
--> Ans: {4,1} (The 3rd smallest value)
small( {4,5,6,8,5,4,3,"text"}, 1 ) 
--> Ans: {3,7} (The 1st smallest value)
small( {4,5,6,8,5,4,3,"text"}, 7 ) 
--> Ans: {8,4} (The 7th smallest value)
small( {"def", "qwe", "abc", "try"}, 2 ) 
--> Ans: {"def", 1} (The 2nd smallest value)
small( {1,2,3,4}, -1) 
--> Ans: {} -- no-value
small( {1,2,3,4}, 10) 
--> Ans: {} -- no-value
</eucode>



@[:stats:largest|]
==== largest
<eucode>
include std/stats.e
namespace stats
public function largest(object data_set)
</eucode>

  returns the largest of the data points that are atoms.

===== Parameters:
# ##data_set## : a list of 1 or more numbers among which you want the largest.

===== Returns:
An **object**, either of:
* an atom (the largest value) if there is at least one atom item in the set\\
* ##{} ##if there //is// no largest value.

===== Comments:
Any ##data_set## element which is not an atom is ignored.

===== Example 1:
<eucode>
largest( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"} ) -- Ans: 8
largest( {"just","text"} ) -- Ans: {}
</eucode>

===== See Also:
[[:range]]



@[:stats:smallest|]
==== smallest
<eucode>
include std/stats.e
namespace stats
public function smallest(object data_set)
</eucode>

  returns the smallest of the data points.

===== Parameters:
# ##data_set## : A list of 1 or more numbers for which you want the smallest.
**Note:** only atom elements are included and any sub-sequences
elements are ignored.

===== Returns:
An **object**, either of~:
* an atom (the smallest value) if there is at least one atom item in the set\\
* ##{} ##if there //is// no largest value.

===== Comments:
Any ##data_set## element which is not an atom is ignored.

===== Example 1:
<eucode>
? smallest( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"} ) -- Ans: 1
? smallest( {"just","text"} ) -- Ans: {}
</eucode>

===== See Also:
[[:range]]


@[:stats:range|]
==== range
<eucode>
include std/stats.e
namespace stats
public function range(object data_set)
</eucode>

  determines a number of //range// statistics for the data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the range data.

===== Returns:
A **sequence**, empty if no atoms were found, else like ##{Lowest, Highest, Range, Mid-range}## ,

===== Comments:
Any sequence element in ##data_set## is ignored.

===== Example 1:
<eucode>
? range( {7,2,8,5,6,6,4,8,6,16,3,3,4,1,8,"text"} ) -- Ans: {1, 16, 15, 8.5}
</eucode>

===== See Also:
[[:smallest]] [[:largest]]



Enums used to influence the results of some of these functions.


@[:stats:ST_FULLPOP|]
==== ST_FULLPOP
<eucode>
include std/stats.e
namespace stats
public enum ST_FULLPOP
</eucode>

 The supplied data is the entire population.




@[:stats:ST_SAMPLE|]
==== ST_SAMPLE
<eucode>
include std/stats.e
namespace stats
public enum ST_SAMPLE
</eucode>

The supplied data is only a random sample of the population.




@[:stats:ST_ALLNUM|]
==== ST_ALLNUM
<eucode>
include std/stats.e
namespace stats
public enum ST_ALLNUM
</eucode>

 The supplied data consists of only atoms.




@[:stats:ST_IGNSTR|]
==== ST_IGNSTR
<eucode>
include std/stats.e
namespace stats
public enum ST_IGNSTR
</eucode>

 Any sub-sequences (such as strings) in the supplied data are ignored.




@[:stats:ST_ZEROSTR|]
==== ST_ZEROSTR
<eucode>
include std/stats.e
namespace stats
public enum ST_ZEROSTR
</eucode>

 Any sub-sequences (such as strings) in the supplied data are assumed to
have the value zero.




@[:stats:stdev|]
==== stdev
<eucode>
include std/stats.e
namespace stats
public function stdev(sequence data_set, object subseq_opt = ST_ALLNUM,
        integer population_type = ST_SAMPLE)
</eucode>

  returns the standard deviation based on the population.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the estimated standard deviation.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.
# ##population_type## : an integer. ##ST_SAMPLE## (the default) assumes that ##data_set## is a random
sample of the total population. ##ST_FULLPOP## means that ##data_set## is the
entire population.

===== Returns:
An **atom**, the estimated standard deviation.
An empty **sequence** means that there is no meaningful data to calculate from.

===== Comments:
##stdev## is a measure of how values are different from the average.

The numbers in ##data_set## can either be the entire population of values or
just a random subset. You indicate which in the ##population_type## parameter. By default
##data_set## represents a sample and not the entire population. When using this
function with sample data, the result is an //estimated// standard deviation.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

The equation for standard deviation is~:
{{{
stdev(X) ==> SQRT(SUM(SQ(X{1..N} - MEAN)) / (N))
}}}

===== Example 1:
<eucode>
? stdev( {4,5,6,7,5,4,3,7} )                             -- Ans: 1.457737974
? stdev( {4,5,6,7,5,4,3,7} ,, ST_FULLPOP)                -- Ans: 1.363589014
? stdev( {4,5,6,7,5,4,3,"text"} , ST_IGNSTR)             -- Ans: 1.345185418
? stdev( {4,5,6,7,5,4,3,"text"}, ST_IGNSTR, ST_FULLPOP ) -- Ans: 1.245399698
? stdev( {4,5,6,7,5,4,3,"text"} , 0)                     -- Ans: 2.121320344
? stdev( {4,5,6,7,5,4,3,"text"}, 0, ST_FULLPOP )         -- Ans: 1.984313483
</eucode>

===== See Also:
[[:average]], [[:avedev]]



@[:stats:avedev|]
==== avedev
<eucode>
include std/stats.e
namespace stats
public function avedev(sequence data_set, object subseq_opt = ST_ALLNUM,
        integer population_type = ST_SAMPLE)
</eucode>

  returns the average of the absolute deviations of data points from their mean.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the mean of the absolute deviations.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.
# ##population_type## : an integer. ##ST_SAMPLE## (the default) assumes that ##data_set## is a random
sample of the total population. ##ST_FULLPOP## means that ##data_set## is the
entire population.

===== Returns:
An **atom** , the deviation from the mean.\\
An empty **sequence**, means that there is no meaningful data to calculate from.

===== Comments:
##avedev## is a measure of the variability in a data set. Its statistical
properties are less well behaved than those of the standard deviation, which is
why it is used less.

The numbers in ##data_set## can either be the entire population of values or
just a random subset. You indicate which in the ##population_type## parameter. By default
##data_set## represents a sample and not the entire population. When using this
function with sample data, the result is an //estimated// deviation.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

The equation for absolute average deviation is~:
{{{
avedev(X) ==> SUM( ABS(X{1..N} - MEAN(X)) ) / N
}}}

===== Example 1:
<eucode>
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,7} ) 
   --> Ans: 1.966666667
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,7},, ST_FULLPOP ) 
   --> Ans: 1.84375
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"}, ST_IGNSTR  ) 
   --> Ans: 1.99047619
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"}, ST_IGNSTR,ST_FULLPOP ) 
   --> Ans: 1.857777778
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"}, 0 ) 
    --> Ans: 2.225
? avedev( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"}, 0, ST_FULLPOP ) 
   --> Ans: 2.0859375
</eucode>

===== See Also:
[[:average]], [[:stdev]]



@[:stats:sum|]
==== sum
<eucode>
include std/stats.e
namespace stats
public function sum(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the sum of all the atoms in an object.

===== Parameters:
# ##data_set## : Either an atom or a list of numbers to sum.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **atom**,  the sum of the set.

===== Comments:
##sum## is used as a measure of the magnitude of a sequence of positive values.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

The equation is~:

{{{
sum(X) ==> SUM( X{1..N} )
}}}

===== Example 1:
<eucode>
? sum( {7,2,8.5,6,6,-4.8,6,6,3.341,-8,"text"}, 0 ) -- Ans: 32.041
</eucode>

===== See Also:
[[:average]]


@[:stats:count|]
==== count
<eucode>
include std/stats.e
namespace stats
public function count(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the count of all the atoms in an object.

===== Parameters:
# ##data_set## : either an atom or a list.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Comments:
This returns the number of numbers in ##data_set##

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Returns:

An **integer**, the number of atoms in the set. When ##data_set## is an atom, 1 is returned.

===== Example 1:
<eucode>
? count( {7,2,8.5,6,6,-4.8,6,6,3.341,-8,"text"} ) -- Ans: 10
? count( {"cat", "dog", "lamb", "cow", "rabbit"} ) -- Ans: 0 (no atoms)
? count( 5 ) -- Ans: 1
</eucode>

===== See Also:
[[:average]], [[:sum]]


@[:stats:average|]
==== average
<eucode>
include std/stats.e
namespace stats
public function average(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the average (mean) of the data points.

===== Parameters:
# ##data_set## : A list of 1 or more numbers for which you want the mean.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.


===== Returns:
An **object**,
* ##{}## (the empty sequence) if there are no atoms in the set.
* an atom (the mean) if there are one or more atoms in the set.

===== Comments:

##average## is the theoretical probable value of a randomly selected item from the set.

The equation for average is~:

{{{
average(X) ==> SUM( X{1..N} ) / N
}}}

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
? average( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,"text"}, ST_IGNSTR ) -- Ans: 5.13333333
</eucode>

===== See Also:
[[:geomean]], [[:harmean]], [[:movavg]], [[:emovavg]]



@[:stats:geomean|]
==== geomean
<eucode>
include std/stats.e
namespace stats
public function geomean(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the geometric mean of the atoms in a sequence.

===== Parameters:
# ##data_set## : the values to take the geometric mean of.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:

An **atom**, the geometric mean of the atoms in ##data_set##.
If there is no atom to take the mean of, 1 is returned.

===== Comments:

The geometric mean of ##N## atoms is the n-th root of their product. Signs are ignored.

This is useful to compute average growth rates.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
? geomean({3, "abc", -2, 6}, ST_IGNSTR) -- prints out power(36,1/3) = 3,30192724889462669
? geomean({1,2,3,4,5,6,7,8,9,10}) -- = 4.528728688
</eucode>

===== See Also:
[[:average]]


@[:stats:harmean|]
==== harmean
<eucode>
include std/stats.e
namespace stats
public function harmean(sequence data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the harmonic mean of the atoms in a sequence.

===== Parameters:
# ##data_set## : the values to take the harmonic mean of.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:

An **atom**, the harmonic mean of the atoms in ##data_set##.

===== Comments:
The harmonic mean is the inverse of the average of their inverses.

This is useful in engineering to compute equivalent capacities and resistances.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
? harmean({3, "abc", -2, 6}, ST_IGNSTR) -- =  0.
? harmean({{2, 3, 4}) -- 3 / (1/2 + 1/3 + 1/4) = 2.769230769
</eucode>

===== See Also:
[[:average]]


@[:stats:movavg|]
==== movavg
<eucode>
include std/stats.e
namespace stats
public function movavg(object data_set, object period_delta)
</eucode>

  returns the average (mean) of the data points for overlaping periods. This
can be either a simple or weighted moving average.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want a moving average.
# ##period_delta## : an object, either
* an integer representing the size of the period, or
* a list of weightings to apply to the respective period positions.

===== Returns:
A **sequence**, either the requested averages or ##{}## if the Data sequence is empty or
the supplied period is less than one.

If a list of weights was supplied, the result is a weighted average; otherwise, it is a simple average.

===== Comments:

A moving average is used to smooth out a set of data points over a period.\\
For example, given a period of 5:
# the first returned element is the average
of the first five data points ##[1..5]##,
# the second returned element is
the average of the second five data points ##[2..6]##, \\and so on \\until
the last returned value is the average of the last 5 data points
##[$-4 .. $]##.

When ##period_delta## is an atom, it is rounded down to the width of the average. When it is a
sequence, the width is its length. If there are not enough data points, zeroes are inserted.

Note that only atom elements are included and any sub-sequence elements are ignored.

===== Example 1:
<eucode>
? movavg( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8}, 10 ) 
 -- Ans: {5.8, 5.4, 5.5, 5.1, 4.7, 4.9}
? movavg( {7,2,8,5,6}, 2 ) 
 -- Ans: {4.5, 5, 6.5, 5.5}
? movavg( {7,2,8,5,6}, {0.5, 1.5} ) 
 -- Ans: {3.25, 6.5, 5.75, 5.75}
</eucode>

===== See Also:
[[:average]]



@[:stats:emovavg|]
==== emovavg
<eucode>
include std/stats.e
namespace stats
public function emovavg(object data_set, atom smoothing_factor)
</eucode>

  returns the exponential moving average of a set of data points.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want a moving average.
# ##smoothing_factor## : an atom, the smoothing factor, typically between 0 and 1.

===== Returns:
A **sequence**, made of the requested averages, or ##{}## if ##data_set## is empty or
the supplied period is less than one.

===== Comments:

A moving average is used to smooth out a set of data points over a period.

The formula used is~:\\
: ##Y,,i,, = Y,,i-1,, + F * (X,,i,, - Y,,i-1,,)##

Note that only atom elements are included and any sub-sequences elements are ignored.

The smoothing factor controls how data is smoothed. 0 smooths everything to 0, and 1 means no smoothing at all.

Any value for ##smoothing_factor## outside the ##0.0..1.0## range causes ##smoothing_factor##
to be set to the periodic factor ##(2/(N+1))##.

===== Example 1:
<eucode>
? emovavg( {7,2,8,5,6}, 0.75 ) 
 -- Ans: {6.65,3.1625,6.790625,5.44765625,5.861914063}
? emovavg( {7,2,8,5,6}, 0.25 ) 
 -- Ans: {5.95,4.9625,5.721875,5.54140625,5.656054687}
? emovavg( {7,2,8,5,6}, -1 ) 
 -- Ans: {6.066666667,4.711111111,5.807407407,5.538271605,5.69218107}
</eucode>

===== See Also:
[[:average]]


@[:stats:median|]
==== median
<eucode>
include std/stats.e
namespace stats
public function median(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the mid point of the data points.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the mean.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **object**, either ##{}## if there are no items in the set, or an **atom** (the median) otherwise.

===== Comments:

##median## is the item for which half the items are below it and half
are above it.

All elements are included; any sequence elements are assumed to have the value zero.

The equation for average  is~:

{{{
median(X) ==> sort(X)[N/2]
}}}

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
? median( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,4} ) -- Ans: 5
</eucode>

===== See Also:
[[:average]], [[:geomean]], [[:harmean]], [[:movavg]], [[:emovavg]]



@[:stats:raw_frequency|]
==== raw_frequency
<eucode>
include std/stats.e
namespace stats
public function raw_frequency(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the frequency of each unique item in the data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the frequencies.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
A **sequence**. This will contain zero or more 2-element sub-sequences. The
first element is the frequency count and the second element is the data item
that was counted. The returned values are in descending order, meaning that
the highest frequencies are at the beginning of the returned list.

===== Comments:
If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
? raw_frequency("the cat is the hatter") 
</eucode>
This returns
{{{
{
{5,116},
{4,32},
{3,104},
{3,101},
{2,97},
{1,115},
{1,114},
{1,105},
{1,99}
}
}}}



@[:stats:mode|]
==== mode
<eucode>
include std/stats.e
namespace stats
public function mode(sequence data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns the most frequent point(s) of the data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers for which you want the mode.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
A **sequence**. The list of modal items in the data set.

===== Comments:

It is possible for the ##mode## to return more than one item when more than
one item in the set has the same highest frequency count.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
mode( {7,2,8,5,6,6,4,8,6,6,3,3,4,1,8,4} ) -- Ans: {6}
mode( {8,2,8,5,6,6,4,8,6,6,3,3,4,1,8,4} ) -- Ans: {8,6}
</eucode>

===== See Also:
[[:average]], [[:geomean]], [[:harmean]], [[:movavg]], [[:emovavg]]



@[:stats:central_moment|]
==== central_moment
<eucode>
include std/stats.e
namespace stats
public function central_moment(sequence data_set, object datum, integer order_mag = 1,
        object subseq_opt = ST_ALLNUM)
</eucode>

  returns the distance between a supplied value and the mean, to some supplied
order of magnitude. This is used to get a measure of the //shape// of a
data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers whose mean is used.
# ##datum##: either a single value or a list of values for which you require
the central moments.
# ##order_mag##: An integer. This is the order of magnitude required. Usually
a number from 1 to 4, but can be anything.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **object**. The same data type as ##datum##. This is the set of calculated
central moments.

===== Comments:

For each of the items in ##datum##, its central moment is calculated as~:
{{{
CM = power( ITEM - AVG, MAGNITUDE)
}}}

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
central_moment("the cat is the hatter", "the",1) --> {23.14285714, 11.14285714, 8.142857143}
central_moment("the cat is the hatter", 't',2) -->   535.5918367                          
central_moment("the cat is the hatter", 't',3) -->   12395.12536                          
</eucode>

===== See Also:
[[:average]]



@[:stats:sum_central_moments|]
==== sum_central_moments
<eucode>
include std/stats.e
namespace stats
public function sum_central_moments(object data_set, integer order_mag = 1,
        object subseq_opt = ST_ALLNUM)
</eucode>

  returns sum of the central moments of each item in a data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers whose mean is used.
# ##order_mag##: An integer. This is the order of magnitude required. Usually
a number from 1 to 4, but can be anything.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **atom**. The total of the central moments calculated for each of the
items in ##data_set##.

===== Comments:
If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
sum_central_moments("the cat is the hatter", 1) --> -8.526512829e-14
sum_central_moments("the cat is the hatter", 2) --> 19220.57143     
sum_central_moments("the cat is the hatter", 3) --> -811341.551     
sum_central_moments("the cat is the hatter", 4) --> 56824083.71
</eucode>

===== See Also:
[[:central_moment]], [[:average]]



@[:stats:skewness|]
==== skewness
<eucode>
include std/stats.e
namespace stats
public function skewness(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns a measure of the asymmetry of a data set. Usually the data_set is a
probablity distribution but it can be anything. This value is used to assess
how suitable the data set is in representing the required analysis. It can
help detect if there are too many extreme values in the data set.

===== Parameters:
# ##data_set## : a list of 1 or more numbers whose mean is used.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **atom**. The skewness measure of the data set.

===== Comments:
Generally speaking, a negative return indicates that most of the values are
lower than the mean, while positive values indicate that most values are
greater than the mean. However this might not be the case when there are a few
extreme values on one side of the mean.

The larger the magnitude of the returned value, the more the data is skewed
in that direction.

A returned value of zero indicates that the mean and median values are identical
and that the data is symmetrical.


If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
skewness("the cat is the hatter") --> -1.36166186
skewness("thecatisthehatter")     --> 0.1093730315
</eucode>

===== See Also:
[[:kurtosis]]



@[:stats:kurtosis|]
==== kurtosis
<eucode>
include std/stats.e
namespace stats
public function kurtosis(object data_set, object subseq_opt = ST_ALLNUM)
</eucode>

  returns a measure of the spread of values in a dataset when compared to a
//normal// probability curve.

===== Parameters:
# ##data_set## : a list of 1 or more numbers whose kurtosis is required.
# ##subseq_opt## : an object. When this is ##ST_ALLNUM## (the default) it
means that ##data_set## is assumed to contain no sub-sequences otherwise this
gives instructions about how to treat sub-sequences. See comments for details.

===== Returns:
An **object**. If this is an atom it is the kurtosis measure of the data set.
Othewise it is a sequence containing an error integer. The return value ##{0}##
indicates that an empty dataset was passed, ##{1}## indicates that the standard
deviation is zero (all values are the same).

===== Comments:
Generally speaking, a negative return indicates that most of the values are
further from the mean, while positive values indicate that most values are
nearer to the mean.

The larger the magnitude of the returned value, the more the data is 'peaked'
or 'flatter' in that direction.

If the data can contain sub-sequences, such as strings, you need to let the
the function know about this otherwise it assumes every value in ##data_set## is
an number. If that is not the case then the function will crash. So it is
important that if it can possibly contain sub-sequences that you tell this
function what to do with them. Your choices are to ignore them or assume they
have the value zero. To ignore them, use ##ST_IGNSTR## as the ##subseq_opt## parameter
value otherwise use ##ST_ZEROSTR##. However, if you know that ##data_set## only
contains numbers use the default ##subseq_opt## value, ##ST_ALLNUM##.

**Note** It is faster if the data only contains numbers.

===== Example 1:
<eucode>
kurtosis("thecatisthehatter")     --> -1.737889192
</eucode>

===== See Also:
[[:skewness]]




!!CONTEXT:../include/std/eds.e
!!namespace:eds
%%output = std_eds

== Euphoria Database (EDS)

<<LEVELTOC level=2 depth=4>>


=== Error Status Constants


@[:eds:DB_OK|]
==== DB_OK
<eucode>
include std/eds.e
namespace eds
public enum DB_OK
</eucode>

 Database is OK, not error has occurred.



@[:eds:DB_OPEN_FAIL|]
==== DB_OPEN_FAIL
<eucode>
include std/eds.e
namespace eds
public enum DB_OPEN_FAIL
</eucode>

 The database could not be opened.



@[:eds:DB_EXISTS_ALREADY|]
==== DB_EXISTS_ALREADY
<eucode>
include std/eds.e
namespace eds
public enum DB_EXISTS_ALREADY
</eucode>

 The database could not be created, it already exists.



@[:eds:DB_LOCK_FAIL|]
==== DB_LOCK_FAIL
<eucode>
include std/eds.e
namespace eds
public enum DB_LOCK_FAIL
</eucode>

 A lock could not be gained on the database.



@[:eds:DB_BAD_NAME|]
==== DB_BAD_NAME
<eucode>
include std/eds.e
namespace eds
public enum DB_BAD_NAME
</eucode>

 An invalid name suppled when creating a table.



@[:eds:DB_FATAL_FAIL|]
==== DB_FATAL_FAIL
<eucode>
include std/eds.e
namespace eds
public enum DB_FATAL_FAIL
</eucode>

 A fatal error has occurred.



=== Lock Type Constants


@[:eds:DB_LOCK_NO|]
==== DB_LOCK_NO
<eucode>
include std/eds.e
namespace eds
public enum DB_LOCK_NO
</eucode>

 Do not lock the file.



@[:eds:DB_LOCK_SHARED|]
==== DB_LOCK_SHARED
<eucode>
include std/eds.e
namespace eds
public enum DB_LOCK_SHARED
</eucode>

 Open the database with read-only access but allow others to update it.



@[:eds:DB_LOCK_EXCLUSIVE|]
==== DB_LOCK_EXCLUSIVE
<eucode>
include std/eds.e
namespace eds
public enum DB_LOCK_EXCLUSIVE
</eucode>

 Open the database with read and write access.



@[:eds:DB_LOCK_READ_ONLY|]
==== DB_LOCK_READ_ONLY
<eucode>
include std/eds.e
namespace eds
public enum DB_LOCK_READ_ONLY
</eucode>

 Open the database with read-only access and ignore others updating it



=== Error Code Constants


@[:eds:MISSING_END|]
==== MISSING_END
<eucode>
include std/eds.e
namespace eds
public enum MISSING_END
</eucode>

 Missing 0 terminator



@[:eds:NO_DATABASE|]
==== NO_DATABASE
<eucode>
include std/eds.e
namespace eds
public enum NO_DATABASE
</eucode>

 current_db is not set



@[:eds:BAD_SEEK|]
==== BAD_SEEK
<eucode>
include std/eds.e
namespace eds
public enum BAD_SEEK
</eucode>

 ##io:seek## failed.



@[:eds:NO_TABLE|]
==== NO_TABLE
<eucode>
include std/eds.e
namespace eds
public enum NO_TABLE
</eucode>

 no table was found.



@[:eds:DUP_TABLE|]
==== DUP_TABLE
<eucode>
include std/eds.e
namespace eds
public enum DUP_TABLE
</eucode>

 this table already exists.



@[:eds:BAD_RECNO|]
==== BAD_RECNO
<eucode>
include std/eds.e
namespace eds
public enum BAD_RECNO
</eucode>

 unknown key_location index was supplied.



@[:eds:INSERT_FAILED|]
==== INSERT_FAILED
<eucode>
include std/eds.e
namespace eds
public enum INSERT_FAILED
</eucode>

 could not insert a new record.



@[:eds:LAST_ERROR_CODE|]
==== LAST_ERROR_CODE
<eucode>
include std/eds.e
namespace eds
public enum LAST_ERROR_CODE
</eucode>

 last error code



@[:eds:BAD_FILE|]
==== BAD_FILE
<eucode>
include std/eds.e
namespace eds
public enum BAD_FILE
</eucode>

 bad file



=== Indexes for Connection Option Structure.


@[:eds:CONNECT_LOCK|]
==== CONNECT_LOCK
<eucode>
include std/eds.e
namespace eds
public enum CONNECT_LOCK
</eucode>

 Locking method



@[:eds:CONNECT_TABLES|]
==== CONNECT_TABLES
<eucode>
include std/eds.e
namespace eds
public enum CONNECT_TABLES
</eucode>

 Initial number of tables to create



@[:eds:CONNECT_FREE|]
==== CONNECT_FREE
<eucode>
include std/eds.e
namespace eds
public enum CONNECT_FREE
</eucode>

 Initial number of free pointers to create



=== Database Connection Options


@[:eds:DISCONNECT|]
==== DISCONNECT
<eucode>
include std/eds.e
namespace eds
public constant DISCONNECT
</eucode>

 Disconnect a connected database



@[:eds:LOCK_METHOD|]
==== LOCK_METHOD
<eucode>
include std/eds.e
namespace eds
public constant LOCK_METHOD
</eucode>

 Locking method to use



@[:eds:INIT_TABLES|]
==== INIT_TABLES
<eucode>
include std/eds.e
namespace eds
public constant INIT_TABLES
</eucode>

 The initial number of tables to reserve space for when creating a database.



@[:eds:INIT_FREE|]
==== INIT_FREE
<eucode>
include std/eds.e
namespace eds
public constant INIT_FREE
</eucode>

 The initial number of free space pointers to reserve space for when creating a database.



@[:eds:CONNECTION|]
==== CONNECTION
<eucode>
include std/eds.e
namespace eds
public constant CONNECTION
</eucode>

 Fetch the details about the alias



=== Variables


@[:eds:db_fatal_id|]
==== db_fatal_id
<eucode>
include std/eds.e
namespace eds
public integer db_fatal_id
</eucode>

  This is an //Exception handler//.

Set this to a valid routine_id value for a procedure that
will be called whenever the library detects a serious error. Your procedure
will be passed a single text string that describes the error. It may also
call [[:db_get_errors]] to get more detail about the cause of the error.


=== Routines


@[:eds:db_get_errors|]
==== db_get_errors
<eucode>
include std/eds.e
namespace eds
public function db_get_errors(integer clearing = 1)
</eucode>

  fetches the most recent set of errors recorded by the library.

===== Parameters:
# ##clearing## : if zero the set of errors is not reset, otherwise
it will be cleared out. The default is to clear the set.

===== Returns:
A **sequence**, each element is a set of four fields.
# Error Code.
# Error Text.
# Name of library routine that recorded the error.
# Parameters passed to that routine.

===== Comments:
* A number of library routines can detect errors. If the routine is a
function, it usually returns an error code. However, procedures that
detect an error can not do that. Instead, they record the error details
and you can query that after calling the library routine.
* Both functions and procedures that detect errors record the details
in the ##Last Error Set##, which is fetched by this function.


===== Example 1:
<eucode>
db_replace_data(recno, new_data)
errs = db_get_errors()
if length(errs) != 0 then
    display_errors(errs)
    abort(1)
end if
</eucode>


@[:eds:db_dump|]
==== db_dump
<eucode>
include std/eds.e
namespace eds
public procedure db_dump(object file_id, integer low_level_too = 0)
</eucode>

  prints the current database in readable form to file ##fn##.

===== Parameters:
# ##fn## : the destination file for printing the current Euphoria database;
# ##low_level_too## : a boolean. If //true//, a byte-by-byte binary dump
is presented as well; otherwise this step is skipped. If omitted,
//false// is assumed.

===== Errors:
If the current database is not defined, an error will occur.

===== Comments:
* All records in all tables are shown.
* If low_level_too is non-zero,
then a low-level byte-by-byte dump is also shown. The low-level
dump will only be meaningful to someone who is familiar
with the internal format of a Euphoria database.

===== Example 1:
<eucode>
if db_open("mydata", DB_LOCK_SHARED) != DB_OK then
    puts(2, "Couldn't open the database!\n")
    abort(1)
end if
fn = open("db.txt", "w")
db_dump(fn) -- Simple output
db_dump("lowlvl_db.txt", 1) -- Full low-level dump created.
</eucode>


@[:eds:check_free_list|]
==== check_free_list
<eucode>
include std/eds.e
namespace eds
public procedure check_free_list()
</eucode>

  detects corruption of the free list in a Euphoria database.

===== Comments:
This is a debug routine used by RDS to detect corruption of the free list.
Users do not normally call this.



=== Managing Databases


@[:eds:db_connect|]
==== db_connect
<eucode>
include std/eds.e
namespace eds
public function db_connect(sequence dbalias, sequence path = "", sequence dboptions = {})
</eucode>

  defines a symbolic name for a database and its default attributes.

===== Parameters:
# ##dbalias## : a sequence. This is the symbolic name that the database can
be referred to by.
# ##path## : a sequence, the path to the file that will contain the database.
# ##dboptions##: a sequence. Contains the set of attributes for the database.
The default is ##{}## meaning it will use the various EDS default values.

===== Returns:
An **integer**, status code, either ##DB_OK## if creation successful or anything else on an error.

===== Comments:

* This does not create or open a database. It only associates a symbolic name with
a database path. This name can then be used in the calls to ##db_create##, ##db_open##,
and ##db_select## instead of the physical database name.
* If the file in the path does not have an extention, ##".edb"## will be added automatically.
* The ##dboptions## can contain any of the options detailed below. These can be
given as a single string of the form ##"option=value, option=value, ..."## or as
as sequence containing option-value pairs, ##{ {option,value}, {option,value}, ... }##
//Note:// The options can be in any order.
* The options are~:
** ##LOCK_METHOD## : an integer specifying which type of access can be granted to the database.
This must be one of ##DB_LOCK_NO##, ##DB_LOCK_EXCLUSIVE##,
##DB_LOCK_SHARDED## or ##DB_LOCK_READ_ONLY##.
** ##INIT_TABLES## : an integer giving the initial number of tables to
reserve space for. The default is 5 and the minimum is 1.
** ##INIT_FREE## : an integer giving the initial amount of free space pointers to
reserve space for. The default is 5 and the minimum is 0.
* If a symbolic name has already been defined for a database, you can get it's
full path and options by calling this function with ##dboptions## set to ##CONNECTION##.
The returned value is a sequence of two elements. The first is the full path name
and the second is a list of the option values. These options are indexed by
##[CONNECT_LOCK]##, ##[CONNECT_TABLES]##, and ##[CONNECT_FREE]##.
* If a symbolic name has already been defined for a database, you remove the
symbolic name by calling this function with ##dboptions## set to ##DISCONNECT##.

===== Example 1:
<eucode>
db_connect("myDB", "/usr/data/myapp/customer.edb", {{LOCK_METHOD,DB_LOCK_NO},
                                                            {INIT_TABLES,1}})
db_open("myDB")
</eucode>

===== Example 2:
<eucode>
db_connect("myDB", "/usr/data/myapp/customer.edb", 
                          sprintf("init_tables=1,lock_method=%d",DB_LOCK_NO))
db_open("myDB")
</eucode>

===== Example 3:
<eucode>
db_connect("myDB", "/usr/data/myapp/customer.edb", 
                          sprintf("init_tables=1,lock_method=%d",DB_LOCK_NO))
db_connect("myDB",,CONNECTION) --> {"/usr/data/myapp/customer.edb", {0,1,1}}
db_connect("myDB",,DISCONNECT) -- The name 'myDB' is removed from EDS.
</eucode>

===== See Also:
[[:db_create]], [[:db_open]], [[:db_select]]


@[:eds:db_create|]
==== db_create
<eucode>
include std/eds.e
namespace eds
public function db_create(sequence path, integer lock_method = DB_LOCK_NO,
        integer init_tables = DEF_INIT_TABLES,
        integer init_free = DEF_INIT_FREE)
</eucode>

  creates a new database given a file path and a lock method.

===== Parameters:
# ##path## : a sequence, the path to the file that will contain the database.
# ##lock_method## : an integer specifying which type of access can be
granted to the database. The value of ##lock_method##
can be either ##DB_LOCK_NO## (no lock) or
##DB_LOCK_EXCLUSIVE## (exclusive lock).
# ##init_tables## : an integer giving the initial number of tables to
reserve space for. The default is ##5## and the minimum is ##1## .
# ##init_free## : an integer giving the initial amount of free space pointers to
reserve space for. The default is ##5## and the minimum is ##0## .

===== Returns:
An **integer**, status code, either ##DB_OK## if creation successful or anything else on an error.

===== Comments:

On success, the newly created database
becomes the **current database** to which
all other database operations will apply.

If the file in the path does not have an extention, ##.edb## will be added automatically.

A version number is stored in the database file so future
versions of the database software can recognize the format, and
possibly read it and deal with it in some way.

If the database already exists, it will not be overwritten.
##db_create## will return ##DB_EXISTS_ALREADY##.

===== Example 1:
<eucode>
if db_create("mydata", DB_LOCK_NO) != DB_OK then
    puts(2, "Couldn't create the database!\n")
    abort(1)
end if
</eucode>

===== See Also:
[[:db_open]], [[:db_select]]


@[:eds:db_open|]
==== db_open
<eucode>
include std/eds.e
namespace eds
public function db_open(sequence path, integer lock_method = DB_LOCK_NO)
</eucode>

  opens an existing Euphoria database.

===== Parameters:
# ##path## : a sequence, the path to the file containing the database
# ##lock_method## : an integer specifying which sort of access can
be granted to the database. The types of lock that you can use are:
## ##DB_LOCK_NO## : (no lock) ~-- The default
## ##DB_LOCK_SHARED## : (shared lock for read-only access)
## ##DB_LOCK_EXCLUSIVE## : (for read and write access).

===== Returns:
An **integer**, status code, either ##DB_OK## if creation successful or anything else on an error.

The return codes are~:

<eucode>
public constant
    DB_OK = 0          -- success
    DB_OPEN_FAIL = -1  -- could not open the file
    DB_LOCK_FAIL = -3  -- could not lock the file in the
                       -- manner requested
</eucode>

===== Comments:
##DB_LOCK_SHARED## is only supported on //Unix// platforms. It allows you to read the database,
but not write anything to it. If you request ##DB_LOCK_SHARED## on //Windows// it will be
treated as if you had asked for ##DB_LOCK_EXCLUSIVE##.

If the lock fails, your program should wait a few seconds and try again.
Another process might be currently accessing the database.

===== Example 1:
<eucode>
tries = 0
while 1 do
    err = db_open("mydata", DB_LOCK_SHARED)
    if err = DB_OK then
        exit
    elsif err = DB_LOCK_FAIL then
        tries += 1
        if tries > 10 then
            puts(2, "too many tries, giving up\n")
            abort(1)
        else
            sleep(5)
        end if
    else
        puts(2, "Couldn't open the database!\n")
        abort(1)
    end if
end while
</eucode>

===== See Also:
[[:db_create]], [[:db_select]]


@[:eds:db_select|]
==== db_select
<eucode>
include std/eds.e
namespace eds
public function db_select(sequence path, integer lock_method = - 1)
</eucode>

  chooses a new, already open, database to be the current database.

===== Parameters:
# ##path## : a sequence, the path to the database to be the new current database.
# ##lock_method## : an integer. Optional locking method.

===== Returns:
An **integer**, ##DB_OK## on success or an error code.

===== Comments:
* Subsequent database operations will apply to this database. ##path## is the
path of the database file as it was originally opened with ##db_open##
or ##db_create##.
* When you create (##db_create##) or open (##db_open##) a database, it automatically
becomes the current database. Use ##db_select## when you want to switch back
and forth between open databases, perhaps to copy records from one to the
other. After selecting a new database, you should select a table within
that database using ##db_select_table##.
* If the ##lock_method## is omitted and the database has not already been opened,
this function will fail. However, if ##lock_method## is a valid lock type for
[[:db_open]]  and the database is not open yet, this function will attempt to
open it. It may still fail if the database cannot be opened.

===== Example 1:
<eucode>
if db_select("employees") != DB_OK then
    puts(2, "Could not select employees database\n")
end if
</eucode>

===== Example 2:
<eucode>
if db_select("customer", DB_LOCK_SHARED) != DB_OK then
    puts(2, "Could not open or select Customer database\n")
end if
</eucode>

===== See Also:
[[:db_open]], [[:db_select]]


@[:eds:db_close|]
==== db_close
<eucode>
include std/eds.e
namespace eds
public procedure db_close()
</eucode>

  unlocks and closes the current database.

===== Comments:
Call this procedure when you are finished with the current database.
Any lock will be removed, allowing other processes to access the
database file. The current database becomes undefined.


=== Managing Tables


@[:eds:db_select_table|]
==== db_select_table
<eucode>
include std/eds.e
namespace eds
public function db_select_table(sequence name)
</eucode>

=====   Parameters:
# ##name## : a sequence which defines the name of the new current table.

On success, the table with name given by name becomes the current table.

===== Returns:
An **integer**, either ##DB_OK## on success or ##DB_OPEN_FAIL## otherwise.

===== Errors:
An error occurs if the current database is not defined.

===== Comments:
All record-level database operations apply automatically to the current table.

===== Example 1:
<eucode>
if db_select_table("salary") != DB_OK then
    puts(2, "Couldn't find salary table!\n")
    abort(1)
end if
</eucode>

===== See Also:
[[:db_table_list]]


@[:eds:db_current_table|]
==== db_current_table
<eucode>
include std/eds.e
namespace eds
public function db_current_table()
</eucode>

  gets the name of currently selected table.

===== Parameters:
# None.

===== Returns:
A **sequence**, the name of the current table. An empty string means
that no table is currently selected.

===== Example 1:
<eucode>
s = db_current_table()
</eucode>

===== See Also:
[[:db_select_table]], [[:db_table_list]]


@[:eds:db_create_table|]
==== db_create_table
<eucode>
include std/eds.e
namespace eds
public function db_create_table(sequence name, integer init_records = DEF_INIT_RECORDS)
</eucode>

  creates a new table within the current database.

===== Parameters:
# ##name## : a sequence, the name of the new table.
# ##init_records## : The number of records to initially reserve space for.
(Default is 50)

===== Returns:
An **integer**, either ##DB_OK## on success or ##DB_EXISTS_ALREADY## on failure.

===== Errors:
An error occurs if the current database is not defined.

===== Comments:
* The supplied name must not exist already on the current database.
* The table that you create will initially have zero records. However
it will reserve some space for a number of records, which will
improve the initial data load for the table.
* It becomes the current table.

===== Example 1:
<eucode>
if db_create_table("my_new_table") != DB_OK then
    puts(2, "Could not create my_new_table!\n")
end if
</eucode>

===== See Also:
[[:db_select_table]], [[:db_table_list]]


@[:eds:db_delete_table|]
==== db_delete_table
<eucode>
include std/eds.e
namespace eds
public procedure db_delete_table(sequence name)
</eucode>

  deletes a table in the current database.

===== Parameters:
# ##name## : a sequence, the name of the table to delete.

===== Errors:
An error occurs if the current database is not defined.

===== Comments:
If there is no table with the name given by name, then nothing happens.
On success, all records are deleted and all space used by the table
is freed up. If the table was the current table, the current table
becomes undefined.

===== See Also:
[[:db_table_list]], [[:db_select_table]], [[:db_clear_table]]


@[:eds:db_clear_table|]
==== db_clear_table
<eucode>
include std/eds.e
namespace eds
public procedure db_clear_table(sequence name, integer init_records = DEF_INIT_RECORDS)
</eucode>

  clears a table of all its records, in the current database.

===== Parameters:
# ##name## : a sequence, the name of the table to clear.

===== Errors:
An error occurs if the current database is not defined.

===== Comments:
If there is no table with the name given by name, then nothing happens.
On success, all records are deleted and all space used by the table
is freed up. If this is the current table, after this operation
it will still be the current table.

===== See Also:
[[:db_table_list]], [[:db_select_table]], [[:db_delete_table]]


@[:eds:db_rename_table|]
==== db_rename_table
<eucode>
include std/eds.e
namespace eds
public procedure db_rename_table(sequence name, sequence new_name)
</eucode>

  renames a table in the current database.

===== Parameters:
# ##name## : a sequence, the name of the table to rename
# ##new_name## : a sequence, the new name for the table

===== Errors:
* An error occurs if the current database is not defined.
* If ##name## does not exist on the current database,
or if ##new_name## does exist on the current database,
an error will occur.

===== Comments:
The table to be renamed can be the current table, or some other table
in the current database.

===== See Also:
[[:db_table_list]]


@[:eds:db_table_list|]
==== db_table_list
<eucode>
include std/eds.e
namespace eds
public function db_table_list()
</eucode>

  lists all tables in the current database.

===== Returns:
A **sequence**, of all the table names in the current database. Each element of this
sequence is a sequence, the name of a table.

===== Errors:
An error occurs if the current database is undefined.

===== Example 1:
<eucode>
sequence names = db_table_list()
for i = 1 to length(names) do
    puts(1, names[i] & '\n')
end for
</eucode>

===== See Also:
[[:db_select_table]], [[:db_create_table]]


=== Managing Records


@[:eds:db_find_key|]
==== db_find_key
<eucode>
include std/eds.e
namespace eds
public function db_find_key(object key, object table_name = current_table_name)
</eucode>

  finds the record in the current table with supplied key.

===== Parameters:
# ##key## : the identifier of the record to be looked up.
# ##table_name## : optional name of table to find key in

===== Returns:
An **integer**, either greater or less than zero:
* If above zero, the record identified by ##key## was found on the
current table, and the returned integer is its record number.
* If less than zero, the record was not found. The returned integer
is the opposite of what the record number would have been, had
the record been found.
* If equal to zero, an error occured.

===== Errors:
If the current table is not defined, it returns ##0## .

===== Comments:

A fast binary search is used to find the key in the current table.
The number of comparisons is proportional to the log of the number of
records in the table. The key is unique~--a table is more like a dictionary than like a spreadsheet.

You can select a range of records by searching
for the first and last key values in the range. If those key values don't
exist, you'll at least get a negative value showing ##io:where## they would be,
if they existed.

For example, suppose you want to know which records have keys
greater than ##"GGG"## and less than ##"MMM"##. If ##-5## is returned for key ##"GGG"##,
it means a record with ##"GGG"## as a key would be inserted as record number ##5## .
##-27## for ##"MMM"## means a record with ##"MMM"## as its key would be inserted as record
number ##27##. This quickly tells you that all records, ##>= 5## and ##< 27## qualify.

===== Example 1:
<eucode>
rec_num = db_find_key("Millennium")
if rec_num > 0 then
    ? db_record_key(rec_num)
    ? db_record_data(rec_num)
else
    puts(2, "Not found, but if you insert it,\n")

    printf(2, "it will be #%d\n", -rec_num)
end if
</eucode>

===== See Also:
[[:db_insert]], [[:db_replace_data]], [[:db_delete_record]], [[:db_get_recid]]


@[:eds:db_insert|]
==== db_insert
<eucode>
include std/eds.e
namespace eds
public function db_insert(object key, object data, object table_name = current_table_name)
</eucode>

  inserts a new record into the current table.

===== Parameters:
# ##key## : an object, the record key, which uniquely identifies it inside the current table
# ##data## : an object, associated to ##key##.
# ##table_name## : optional table name to insert record into

===== Returns:
An **integer**, either ##DB_OK## on success or an error code on failure.

===== Comments:
Within a table, all keys must be unique. ##db_insert## will fail with
##DB_EXISTS_ALREADY## if a record already exists on current table with the same key value.

Both key and data can be any Euphoria data objects, atoms or sequences.

===== Example 1:
<eucode>
if db_insert("Smith", {"Peter", 100, 34.5}) != DB_OK then
    puts(2, "insert failed!\n")
end if
</eucode>

===== See Also:
[[:db_replace_data]], [[:db_delete_record]]



@[:eds:db_delete_record|]
==== db_delete_record
<eucode>
include std/eds.e
namespace eds
public procedure db_delete_record(integer key_location, object table_name = current_table_name)
</eucode>

  deletes record number ##key_location## from the current table.

===== Parameters:
# ##key_location## : a positive integer, designating the record to delete.
# ##table_name## : optional table name to delete record from.

===== Errors:
If the current table is not defined, or ##key_location## is not a
valid record index, an error will occur. Valid record indexes are
between 1 and the number of records in the table.

===== Example 1:
<eucode>
db_delete_record(55)
</eucode>

===== See Also:
[[:db_find_key]]


@[:eds:db_replace_data|]
==== db_replace_data
<eucode>
include std/eds.e
namespace eds
public procedure db_replace_data(integer key_location, object data,
        object table_name = current_table_name)
</eucode>

  replaces, the current table, the data portion of a record  with new data.

===== Parameters:
# ##key_location##: an integer, the index of the record the data is to be altered.
# ##data##: an object , the new value associated to the key of the record.
# ##table_name##: optional table name of record to replace data in.

===== Comments:
##key_location## must be from ##1## to the number of records in the
current table.
##data## is an Euphoria object of any kind, atom or sequence.

===== Example 1:
<eucode>
db_replace_data(67, {"Peter", 150, 34.5})
</eucode>

===== See Also:
[[:db_find_key]]


@[:eds:db_table_size|]
==== db_table_size
<eucode>
include std/eds.e
namespace eds
public function db_table_size(object table_name = current_table_name)
</eucode>

  gets the size (number of records) of the default table.

===== Parameters:
# ##table_name## : optional table name to get the size of.

Returns
An **integer**, the current number of records in the current table.
If a value less than zero is returned, it means that an error occured.

===== Errors:
If the current table is undefined, an error will occur.

===== Example 1:
<eucode>
-- look at all records in the current table
for i = 1 to db_table_size() do
    if db_record_key(i) = 0 then
    	puts(1, "0 key found\n")
    	exit
    end if
end for
</eucode>

===== See Also:
[[:db_replace_data]]


@[:eds:db_record_data|]
==== db_record_data
<eucode>
include std/eds.e
namespace eds
public function db_record_data(integer key_location, object table_name = current_table_name)
</eucode>

  returns the data in a record queried by position.

===== Parameters:
# ##key_location## : the index of the record the data of which is being fetched.
# ##table_name## : optional table name to get record data from.

===== Returns:
An **object**, the data portion of requested record.

===== Note:
This function calls ##fatal## and returns a value of ##-1## if an error prevented
the correct data being returned.

===== Comments:
Each record in a Euphoria database consists of a key portion and a data
portion. Each of these can be any Euphoria atom or sequence.

===== Errors:
If the current table is not defined, or if the record index is invalid, an error will occur.

===== Example 1:
<eucode>
puts(1, "The 6th record has data value: ")
? db_record_data(6)
</eucode>

===== See Also:
[[:db_find_key]], [[:db_replace_data]]


@[:eds:db_fetch_record|]
==== db_fetch_record
<eucode>
include std/eds.e
namespace eds
public function db_fetch_record(object key, object table_name = current_table_name)
</eucode>

  returns the data for the record with supplied key.

===== Parameters:
# ##key## : the identifier of the record to be looked up.
# ##table_name## : optional name of table to find key in

===== Returns:
An **integer**,
* If less than zero, the record was not found. The returned integer
is the opposite of what the record number would have been, had
the record been found.
* If equal to zero, an error occured.
A sequence, the data for the record.

===== Errors:
If the current table is not defined, it returns 0.

===== Comments:
Each record in a Euphoria database consists of a key portion and a data
portion. Each of these can be any Euphoria atom or sequence.

===== Note:
This
function does not support records that data consists of a single non-sequence value.
In those cases you will need to use [[:db_find_key]] and [[:db_record_data]].

===== Example 1:
<eucode>
printf(1, "The record['%s'] has data value:\n", {"foo"})
? db_fetch_record("foo")
</eucode>

===== See Also:
[[:db_find_key]], [[:db_record_data]]


@[:eds:db_record_key|]
==== db_record_key
<eucode>
include std/eds.e
namespace eds
public function db_record_key(integer key_location, object table_name = current_table_name)
</eucode>

  returns the key of a record given an index.
===== Parameters:
# ##key_location## : an integer, the index of the record the key is being requested.
# ##table_name## : optional table name to get record key from.

Returns
An **object**, the key of the record being queried by index.

===== Note:
This function calls ##fatal## and returns a value of ##-1## if an error prevented
the correct data being returned.

===== Errors:
If the current table is not defined, or if the record index is invalid, an error will occur.

===== Comments:
Each record in a Euphoria database consists of a key portion and a
data portion. Each of these can be any Euphoria atom or sequence.

===== Example 1:
<eucode>
puts(1, "The 6th record has key value: ")
? db_record_key(6)
</eucode>

===== See Also:
[[:db_record_data]]


@[:eds:db_compress|]
==== db_compress
<eucode>
include std/eds.e
namespace eds
public function db_compress()
</eucode>

  compresses the current database.

===== Returns:
An **integer**, either DB_OK on success or an error code on failure.

===== Comments:
The current database is copied to a new
file such that any blocks of unused space are eliminated. If successful,
the return value will be set to ##DB_OK##, and the new compressed database
file will retain the same name. The current table will be undefined. As
a backup, the original, uncompressed file will be renamed with an extension
of ##.t0 (or .t1, .t2, ..., .t99)##. In the highly unusual case that the
compression is unsuccessful, the database will be left unchanged, and no
backup will be made.

When you delete items from a database, you create blocks of free space within
the database file. The system keeps track of these blocks and tries to use them
for storing new data that you insert. ##db_compress## will copy the current
database without copying these free areas. The size of the database file may
therefore be reduced. If the backup filenames reach ##.t99## you will have to
delete some of them.

===== Example 1:
<eucode>
if db_compress() != DB_OK then
    puts(2, "compress failed!\n")
end if
</eucode>


@[:eds:db_current|]
==== db_current
<eucode>
include std/eds.e
namespace eds
public function db_current()
</eucode>

  gets name of currently selected database.

===== Parameters:
# None.

===== Returns:
A **sequence**, the name of the current database. An empty string means
that no database is currently selected.

===== Comments:
The actual name returned is the //path// as supplied to the ##db_open## routine.

===== Example 1:
<eucode>
s = db_current_database()
</eucode>

===== See Also:
[[:db_select]]


@[:eds:db_cache_clear|]
==== db_cache_clear
<eucode>
include std/eds.e
namespace eds
public procedure db_cache_clear()
</eucode>

  forces the database index cache to be cleared.

===== Parameters:
# None

===== Comments:
* This is not normally required to the run. You might run it to set up a
predetermined state for performance timing, or to release some memory back to the
application.

===== Example 1:
<eucode>
db_cache_clear() -- Clear the cache.
</eucode>


@[:eds:db_set_caching|]
==== db_set_caching
<eucode>
include std/eds.e
namespace eds
public function db_set_caching(atom new_setting)
</eucode>

  sets the key cache behavior.

===== Parameters:
# ##integer## : ##0## will turn of caching, ##1## will turn it back on.

===== Returns:
An **integer**, the previous setting of the option.

===== Comments:
Initially, the cache option is turned on. This means that when possible, the
keys of a table are kept in RAM rather than read from disk each time
##db_select_table## is called. For most databases, this will improve performance
when you have more than one table in it.

When caching is turned off, the current cache contents is totally cleared.

===== Example 1:
<eucode>
x = db_set_caching(0) -- Turn off key caching.
</eucode>


@[:eds:db_replace_recid|]
==== db_replace_recid
<eucode>
include std/eds.e
namespace eds
public procedure db_replace_recid(integer recid, object data)
</eucode>

  replaces, in the current database, the data portion of a record with new data.

===== Parameters:
# ##recid## : an atom, the ##recid## of the record to be updated.
# ##data## : an object, the new value of the record.

===== Comments:
This can be used to quickly update records that have already been located
by calling [[:db_get_recid]]. This operation is faster than using
[[:db_replace_data]]

* ##recid## must be fetched using [[:db_get_recid]] first.
* ##data## is an Euphoria object of any kind, atom or sequence.
* The ##recid## does not have to be from the current table.
* This does no error checking. It assumes the database is open and valid.

===== Example 1:
<eucode>
rid = db_get_recid("Peter")
rec = db_record_recid(rid)
rec[2][3] *= 1.10
db_replace_recid(rid, rec[2])
</eucode>

===== See Also:
[[:db_replace_data]], [[:db_find_key]], [[:db_get_recid]]


@[:eds:db_record_recid|]
==== db_record_recid
<eucode>
include std/eds.e
namespace eds
public function db_record_recid(integer recid)
</eucode>

  returns the key and data in a record queried by ##recid##.

===== Parameters:
# ##recid## : the ##recid## of the required record, which has been
previously fetched using [[:db_get_recid]].

===== Returns:
An **sequence**, the first element is the key and the second element
is the data portion of requested record.

===== Comments:
* This is much faster than calling [[:db_record_key]] and [[:db_record_data]].
* This does no error checking. It assumes the database is open and valid.
* This function does not need the requested record to be from the current
table. The ##recid## can refer to a record in any table.

===== Example 1:
<eucode>
rid = db_get_recid("SomeKey")
? db_record_recid(rid)
</eucode>

===== See Also:
[[:db_get_recid]], [[:db_replace_recid]]


@[:eds:db_get_recid|]
==== db_get_recid
<eucode>
include std/eds.e
namespace eds
public function db_get_recid(object key, object table_name = current_table_name)
</eucode>

  returns the unique record identifier (##recid##) value for the record.

===== Parameters:
# ##key## : the identifier of the record to be looked up.
# ##table_name## : optional name of table to find key in

===== Returns:
An **atom**, either greater or equal to zero:
* If above zero, it is a ##recid##.
* If less than zero, the record wasn't found.
* If equal to zero, an error occured.

===== Errors:
If the table is not defined, an error is raised.

===== Comments:
A **##recid##** is a number that uniquely identifies a record in the database.
No two records in a database has the same ##recid## value. They can be used
instead of keys to //quickly// refetch a record, as they avoid the overhead of
looking for a matching record key. They can also be used without selecting
a table first, as the ##recid## is unique to the database and not just a table.
However, they only remain valid while a database is open and so long as it
does not get compressed. Compressing the database will give each record a
new ##recid## value.

Because it is faster to fetch a record with a ##recid## rather than with its key,
these are used when you know you have to //refetch// a record.

===== Example 1:
<eucode>
rec_num = db_get_recid("Millennium")
if rec_num > 0 then
    ? db_record_recid(rec_num) -- fetch key and data.
else
    puts(2, "Not found\n")
end if
</eucode>

===== See Also:
[[:db_insert]], [[:db_replace_data]], [[:db_delete_record]], [[:db_find_key]]



!!CONTEXT:../include/std/primes.e
!!namespace:primes
%%output = std_primes

== Prime Numbers

<<LEVELTOC level=2 depth=4>>


=== Routines



@[:primes:calc_primes|]
==== calc_primes
<eucode>
include std/primes.e
namespace primes
public function calc_primes(integer approx_limit, atom time_limit_p = 10)
</eucode>

  returns all the prime numbers below a threshold, with a cap on computation time.

===== Parameters:
# ##approx_limit## : an integer, This is not the upper limit but the last prime
returned is the //next// prime after or on this value.
# ##time_out_p## : an atom, the maximum number of seconds that this function can run for.
The default is 10 (ten) seconds.

===== Returns:
A **sequence**, made of prime numbers in increasing order. The last value is
the next prime number that falls on or //after// the value of ##approx_limit##.

===== Comments:
* The ##approx_limit## argument //does not// represent the largest value to return.
The largest value returned will be the next prime number on or after ##approx_limit#.
The [[:prime_list]] function will allow to specify a upper limit.
* The returned sequence contains all the prime numbers less than its last element.

* If the function times out, it may not hold all primes below ##approx_limit##,
but only the largest ones will be absent. If the last element returned is
less than ##approx_limit## then the function timed out.

* To disable the timeout, simply give it a negative value.

===== Example 1:
<eucode>
? calc_primes(1000, 5)
-- On a very slow computer, you may only get all primes up to say 719. 
-- On a faster computer, the last element printed out will be 1009. 
-- This call will never take longer than 5 seconds.
</eucode>

===== See Also:
[[:next_prime]] [[:prime_list]]


@[:primes:next_prime|]
==== next_prime
<eucode>
include std/primes.e
namespace primes
public function next_prime(integer n, object fail_signal_p = - 1, atom time_out_p = 1)
</eucode>

  returns the next prime number on or after the supplied number.

===== Parameters:
# ##n## : an integer, the starting point for the search
# ##fail_signal_p## : an integer, used to signal error. Defaults to -1.

===== Returns:
An **integer**, which is prime only if it took less than one second
to determine the next prime greater or equal to ##n##.

===== Comments:
The default value of -1 will alert you about an invalid returned value,
since a prime not less than ##n## is expected. However, you can pass
another value for this parameter.

===== Example 1:
<eucode>
? next_prime(997)
-- On a very slow computer, you might get -997, but 1009 is expected.
</eucode>

===== See Also:
[[:calc_primes]]


@[:primes:prime_list|]
==== prime_list
<eucode>
include std/primes.e
namespace primes
public function prime_list(integer top_prime_p = 0)
</eucode>

  returns a list of prime numbers.

===== Parameters:
# ##top_prime_p## : The list will end with the prime less than or equal
to this value. If ##top_prime_p## is zero, the current list of calculated primes
is returned.

===== Returns:
An **sequence**, a list of prime numbers from ##2## to ##<=## ##top_prime_p##

===== Example 1:
<eucode>
sequence pList = prime_list(1000)
-- pList will now contain all the primes from 2 up to the largest less than or
--    equal to 1000, which is 997.
</eucode>

===== See Also:
[[:calc_primes]], [[:next_prime]]




!!CONTEXT:../include/std/flags.e
!!namespace:flags
%%output = std_flags

== Flags

<<LEVELTOC level=2 depth=4>>



=== Routines



@[:flags:which_bit|]
==== which_bit
<eucode>
include std/flags.e
namespace flags
public function which_bit(object theValue)
</eucode>

  tests if the supplied value has only a single bit on in its representation.
===== Parameters:
# ##theValue## : an object to test.

===== Returns:
An **integer**, either 0 if it contains multiple bits, zero bits or is an invalid value,
otherwise the bit number set. The right-most bit is position 1 and the leftmost bit
is position 32.

===== Example 1:
<eucode>
? which_bit(2) --> 2
? which_bit(0) --> 0
? which_bit(3) --> 0
? which_bit(4)          --> 3
? which_bit(17)         --> 0
? which_bit(1.7)        --> 0
? which_bit(-2)         --> 0
? which_bit("one")      --> 0
? which_bit(0x80000000) --> 32
</eucode>


@[:flags:flags_to_string|]
==== flags_to_string
<eucode>
include std/flags.e
namespace flags
public function flags_to_string(object flag_bits, sequence flag_names,
        integer expand_flags = 0)
</eucode>

  returns a list of strings that represent the human-readable identities of
the supplied flag or flags.

===== Parameters:
# ##flag_bits## : Either a single 32-bit set of flags (a flag value),
or a list of such flag values. The function returns the names for these flag values.
# ##flag_names## : A sequence of two-element sub-sequences. Each sub-sequence
is contains ##{FlagValue, FlagName}##, where //FlagName// is a string and
//FlagValue// is the set of bits that set the flag on.
# ##expand_flags##: An integer. 0 (the default) means that the flag values in
##flag_bits## are not broken down to their single-bit values. For example: ###0c## returns
the name of ###0c## and not the names for ###08## and ###04##. When ##expand_flags## is
non-zero then each bit in the ##flag_bits## parameter is scanned for a
matching name.

===== Returns:
A sequence. This contains the name or names for each supplied flag value or values.

===== Comments:
* The number of strings in the returned value depends on ##expand_flags## is
non-zero and whether ##flags_bits## is an atom or sequence.
* When ##flag_bits## is an atom, you get returned a sequence of strings, one
for each matching name (according to ##expand_flags## option).
* When ##flag_bits## is a sequence, it is assumed to represent a list of
atomic flags. That is, ##{#1, #4}## is a set of two flags for which you want their
names. In this case, you get returned a sequence that contains one sequence
for each element in ##flag_bits##, which in turn contain the matching name or names.
* When a flag's name can not be found in ##flag_names##, this function returns
the //name// of "##?##".

===== Example 1:
<eucode>
include std/console.e
sequence s
s = {
	{#00000000, "WS_OVERLAPPED"},
	{#80000000, "WS_POPUP"},
	{#40000000, "WS_CHILD"},
	{#20000000, "WS_MINIMIZE"},
	{#10000000, "WS_VISIBLE"},
	{#08000000, "WS_DISABLED"},
	{#44000000, "WS_CLIPPINGCHILD"},
	{#04000000, "WS_CLIPSIBLINGS"},
	{#02000000, "WS_CLIPCHILDREN"},
	{#01000000, "WS_MAXIMIZE"},
	{#00C00000, "WS_CAPTION"},
	{#00800000, "WS_BORDER"},
	{#00400000, "WS_DLGFRAME"},
	{#00100000, "WS_HSCROLL"},
	{#00200000, "WS_VSCROLL"},
	{#00080000, "WS_SYSMENU"},
	{#00040000, "WS_THICKFRAME"},
	{#00020000, "WS_MINIMIZEBOX"},
	{#00010000, "WS_MAXIMIZEBOX"},
	{#00300000, "WS_SCROLLBARS"},
	{#00CF0000, "WS_OVERLAPPEDWINDOW"},
	$
}
display( flags_to_string( {#0C20000,2,9,0}, s,1))
--> {
-->     "WS_BORDER",
-->     "WS_DLGFRAME",
-->     "WS_MINIMIZEBOX"
-->   },
-->   {
-->     "?"
-->   },
-->   {
-->     "?"
-->   },
-->   {
-->     "WS_OVERLAPPED"
-->   }
--> }
display( flags_to_string( #80000000, s))
--> {
-->   "WS_POPUP"
--> }
display( flags_to_string( #00C00000, s))
--> {
-->   "WS_CAPTION"
--> }
display( flags_to_string( #44000000, s))
--> {
-->   "WS_CLIPPINGCHILD"
--> }
display( flags_to_string( #44000000, s, 1))
--> {
-->   "WS_CHILD",
-->   "WS_CLIPSIBLINGS"
--> }
display( flags_to_string( #00000000, s))
--> {
-->   "WS_OVERLAPPED"
--> }
display( flags_to_string( #00CF0000, s))
--> {
-->   "WS_OVERLAPPEDWINDOW"
--> }
display( flags_to_string( #00CF0000, s, 1))
--> {
-->   "WS_BORDER",
-->   "WS_DLGFRAME",
-->   "WS_SYSMENU",
-->   "WS_THICKFRAME",
-->   "WS_MINIMIZEBOX",
-->   "WS_MAXIMIZEBOX"
--> }
</eucode>



!!CONTEXT:../include/std/hash.e
!!namespace:stdhash
%%output = std_hash

== Hashing Algorithms

<<LEVELTOC level=2 depth=4>>



=== Type Constants



@[:stdhash:HSIEH30|]
==== HSIEH30
<eucode>
include std/hash.e
namespace stdhash
public enum HSIEH30
</eucode>





@[:stdhash:HSIEH32|]
==== HSIEH32
<eucode>
include std/hash.e
namespace stdhash
public enum HSIEH32
</eucode>





@[:stdhash:ADLER32|]
==== ADLER32
<eucode>
include std/hash.e
namespace stdhash
public enum ADLER32
</eucode>





@[:stdhash:FLETCHER32|]
==== FLETCHER32
<eucode>
include std/hash.e
namespace stdhash
public enum FLETCHER32
</eucode>





@[:stdhash:MD5|]
==== MD5
<eucode>
include std/hash.e
namespace stdhash
public enum MD5
</eucode>





@[:stdhash:SHA256|]
==== SHA256
<eucode>
include std/hash.e
namespace stdhash
public enum SHA256
</eucode>





=== Routines



@[:eu:hash|]
==== hash
<eucode>
<built-in> function hash(object source, atom algo)
</eucode>

calculates a hash value for a //key// using the algorithm ##algo##.

===== Parameters:
# ##source## : Any Euphoria object
# ##algo## : A code indicating which algorithm to use.
** ##HSIEH30## uses Hsieh. Returns a 30-bit (a Euphoria integer). Fast and good dispersion
** ##HSIEH32## uses Hsieh. Returns a 32-bit value. Fast and very good dispersion
** ##ADLER32## uses Adler. Very fast and reasonable dispersion, especially for small strings
** ##FLETCHER32## uses Fletcher. Very fast and good dispersion
** ##MD5## uses MD5 (not implemented yet) Slower but very good dispersion.
Suitable for signatures.
** ##SHA256## uses SHA256 (not implemented yet) Slow but excellent dispersion.
Suitable for signatures. More secure than MD5.
** 0 and above (integers and decimals) and non-integers less than zero use
the cyclic variant ##(hash = hash * algo + c)##.
This is a fast and good to excellent
dispersion depending on the value of //algo//. Decimals give better
dispersion but are slightly slower.

===== Returns:
An **atom**,
Except for the ##HSIEH30##, ##MD5## and ##SHA256## algorithms, this is a 32-bit integer.\\
An **integer**,
Except for the ##HSIEH30## algorithms, this is a 30-bit integer.\\
A **sequence**,
##MD5## returns a 4-element sequence of integers\\
##SHA256## returns a 8-element sequence of integers.

===== Comments:
* For ##algo## values from zero to less than one, that actual value used is ##(algo + 69096)##.

===== Example 1:
<eucode>
? hash("The quick brown fox jumps over the lazy dog", 0         ) --> 3071488335
? hash("The quick brown fox jumps over the lazy dog", 99        ) --> 4122557553
? hash("The quick brown fox jumps over the lazy dog", 99.94     ) -->   95918096
? hash("The quick brown fox jumps over the lazy dog", -99.94    ) --> 4175585990
? hash("The quick brown fox jumps over the lazy dog", HSIEH30   ) -->   96435427
? hash("The quick brown fox jumps over the lazy dog", HSIEH32   ) -->   96435427
? hash("The quick brown fox jumps over the lazy dog", ADLER32   ) --> 1541148634
? hash("The quick brown fox jumps over the lazy dog", FLETCHER32) --> 1730140417
? hash(123,                                           99        ) --> 1188623852
? hash(1.23,                                          99        ) --> 3808916725
? hash({1, {2,3, {4,5,6}, 7}, 8.9},                   99        ) -->  526266621
</eucode>



!!CONTEXT:../include/std/map.e
!!namespace:map
%%output = std_map

== Map (Hash Table)

<<LEVELTOC level=2 depth=4>>

A **map** is a special array, often called an associative array or dictionary;
in a map the data **values** (any Euphoria object) are indexed by **keys** (also any Euphoria object).

When programming think in terms of //key:value// pairs.
For example we can code things like this~:
<eucode>
   custrec = new() -- Create a new map
   put(custrec, "Name", "Joe Blow")
   put(custrec, "Address", "555 High Street")
   put(custrec, "Phone", 555675632)
</eucode>
This creates three elements in the map, and they are indexed by ##"Name"##,
##"Address"## and ##"Phone"##, meaning that to get the data associated with those
keys we can code~:
<eucode>
   object data = get(custrec, "Phone")
   -- data now set to 555675632
</eucode>

Note that //only one instance of a given key// can exist in a given map, meaning
for example, we could not have two separate ##"Name"## values in the above ##custrec##
map.

Maps automatically grow to accommodate all the elements placed into it.

Associative arrays can be implemented in many different ways, depending
on what efficiency trade-offs have been made. This implementation allows
you to specify how many items you expect the map to hold, or simply start
with the default size.

As the number of items in the map grows, the map may increase its size
to accommodate larger numbers of items.



=== Operation Codes for Put


@[:map:PUT|]
==== PUT
<eucode>
include std/map.e
namespace map
public enum PUT
</eucode>





@[:map:ADD|]
==== ADD
<eucode>
include std/map.e
namespace map
public enum ADD
</eucode>





@[:map:SUBTRACT|]
==== SUBTRACT
<eucode>
include std/map.e
namespace map
public enum SUBTRACT
</eucode>





@[:map:MULTIPLY|]
==== MULTIPLY
<eucode>
include std/map.e
namespace map
public enum MULTIPLY
</eucode>





@[:map:DIVIDE|]
==== DIVIDE
<eucode>
include std/map.e
namespace map
public enum DIVIDE
</eucode>





@[:map:APPEND|]
==== APPEND
<eucode>
include std/map.e
namespace map
public enum APPEND
</eucode>





@[:map:CONCAT|]
==== CONCAT
<eucode>
include std/map.e
namespace map
public enum CONCAT
</eucode>





@[:map:LEAVE|]
==== LEAVE
<eucode>
include std/map.e
namespace map
public enum LEAVE
</eucode>





=== Types



@[:map:map|]
==== map
<eucode>
include std/map.e
namespace map
public type map(object m)
</eucode>

  defines the datatype 'map'.

===== Comments:
Used when declaring a map variable.

===== Example 1:
<eucode>
map SymbolTable = new() -- Create a new map to hold the symbol table.
</eucode>


=== Routines



@[:map:calc_hash|]
==== calc_hash
<eucode>
include std/map.e
namespace map
public function calc_hash(object key_p, integer max_hash_p)
</eucode>

  calculates a Hashing value from the supplied data.

===== Parameters:
# ##key_p## : The data for which you want a hash value calculated.
# ##max_hash_p## :  The returned value will be no larger than this value.

===== Returns:
An **integer**, the value of which depends only on the supplied data.

===== Comments:
This is used whenever you need a single number to represent the data you supply.
It can calculate the number based on all the data you give it, which can be
an atom or sequence of any value.

===== Example 1:
<eucode>
integer h1
-- calculate a hash value and ensure it will be a value from 1 to 4097.
h1 = calc_hash( symbol_name, 4097 )
</eucode>



@[:map:threshold|]
==== threshold
<eucode>
include std/map.e
namespace map
public function threshold(integer new_value_p = 0)
</eucode>

  deprecated.

===== Parameters:
# ##new_value_p## : unused
value.

===== Returns:
Zero..



@[:map:type_of|]
==== type_of
<eucode>
include std/map.e
namespace map
public function type_of(map the_map_p)
</eucode>

  deprecated

===== Parameters:
# ##m## : A map

===== Returns:
Zero.



@[:map:rehash|]
==== rehash
<eucode>
include std/map.e
namespace map
public procedure rehash(map the_map_p, integer requested_size_p = 0)
</eucode>

  changes the width (that is the number of buckets) of a map.

===== Parameters:
# ##m## : the map to resize
# ##requested_size_p## : a lower limit for the new size.

===== Comments:
If ##requested_size_p## is not greater than zero, a new width is automatically derived from the current one.

===== See Also:
[[:statistics]], [[:optimize]]


@[:map:new|]
==== new
<eucode>
include std/map.e
namespace map
public function new(integer initial_size_p = DEFAULT_SIZE)
</eucode>

  creates a new map data structure.

===== Parameters:
# ##initial_size_p## : An estimate of how many initial elements will be stored
in the map.

===== Returns:
An empty **map**.

===== Comments:
A new object of type map is created.  The resources allocated for the map will
be automatically cleaned up if the reference count of the returned value drops
to zero, or if passed in a call to [[:delete]].

===== Example 1:
<eucode>
map m = new()  -- m is now an empty map
x = new()    -- the resources for the map previously stored in x are released automatically
delete( m )  -- the resources for the map are released
</eucode>


@[:map:new_extra|]
==== new_extra
<eucode>
include std/map.e
namespace map
public function new_extra(object the_map_p, integer initial_size_p = 8)
</eucode>

  returns either the supplied map or a new map.

===== Parameters:
# ##the_map_p## : An object, that could be an existing map
# ##initial_size_p## : An estimate of how many initial elements will be stored
in a new map.

===== Returns:
A **map**,
If ##m## is an existing map then it is returned otherwise this
returns a new empty **map**.

===== Comments:
This is used to return a new map if the supplied variable isn't already
a map.

===== Example 1:
<eucode>
map m = new_extra( foo() ) -- If foo() returns a map it is used, otherwise
                           --  a new map is created.
</eucode>



@[:map:compare|]
==== compare
<eucode>
include std/map.e
namespace map
public function compare(map map_1_p, map map_2_p, integer scope_p = 'd')
</eucode>

  compares two maps to test equality.

===== Parameters:
# ##map_1_p## : A map
# ##map_2_p## : A map
# ##scope_p## : An integer that specifies what to compare.
** 'k' or 'K' to only compare keys.
** 'v' or 'V' to only compare values.
** 'd' or 'D' to compare both keys and values. This is the default.

===== Returns:
An **integer**,
* -1 if they are not equal.
* 0 if they are literally the same map.
* 1 if they contain the same keys and/or values.

===== Example 1:
<eucode>
map map_1_p = foo()
map map_2_p = bar()
if compare(map_1_p, map_2_p, 'k') >= 0 then
     ... -- two maps have the same keys
</eucode>



@[:map:has|]
==== has
<eucode>
include std/map.e
namespace map
public function has(map the_map_p, object key)
</eucode>

  checks whether map has a given key.

===== Parameters:
# ##the_map_p## : the map to inspect
# ##the_key_p## : an object to be looked up

===== Returns:
An **integer**, 0 if not present, 1 if present.

===== Example 1:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, "name", "John")
? has(the_map_p, "name") -- 1
? has(the_map_p, "age")  -- 0
</eucode>

===== See Also:
[[:get]]



@[:map:get|]
==== get
<eucode>
include std/map.e
namespace map
public function get(map the_map_p, object key, object default = 0)
</eucode>

  retrieves the value associated to a key in a map.

===== Parameters:
# ##the_map_p## : the map to inspect
# ##the_key_p## : an object, the the_key_p being looked tp
# ##default_value_p## : an object, a default value returned if ##the_key_p## not found.
The default is 0.

===== Returns:
An **object**, the value that corresponds to ##the_key_p## in ##the_map_p##.
If ##the_key_p## is not in ##the_map_p##, ##default_value_p## is returned instead.

===== Example 1:
<eucode>
map ages
ages = new()
put(ages, "Andy", 12)
put(ages, "Budi", 13)

integer age
age = get(ages, "Budi", -1)
if age = -1 then
    puts(1, "Age unknown")
else
    printf(1, "The age is %d", age)
end if
</eucode>

===== See Also:
[[:has]]



@[:map:nested_get|]
==== nested_get
<eucode>
include std/map.e
namespace map
public function nested_get(map the_map_p, sequence the_keys_p, object default_value_p = 0)
</eucode>

  returns the value given a nested key.

===== Comments:
Returns the value that corresponds to the object ##the_keys_p## in the nested map
the_map_p.  ##the_keys_p## is a sequence of keys.  If any key is not in the map, the
object default_value_p is returned instead.



@[:map:put|]
==== put
<eucode>
include std/map.e
namespace map
public procedure put(map the_map_p, object key, object val, object op = PUT,
        object deprecated = 0)
</eucode>

  adds or updates an entry on a map.

===== Parameters:
# ##the_map_p## : the map where an entry is being added or updated
# ##the_key_p## : an object, the the_key_p to look up
# ##the_value_p## : an object, the value to add, or to use for updating.
# ##operation## : an integer, indicating what is to be done with ##the_value_p##. Defaults to PUT.
# ##trigger_p## : Deprecated. This parameter defaults to zero and is not used.

===== Comments:
* The operation parameter can be used to modify the existing value.  Valid operations are:

** ##PUT## ~--  This is the default, and it replaces any value in there already
** ##ADD## ~--  Equivalent to using the += operator
** ##SUBTRACT## ~--  Equivalent to using the -= operator
** ##MULTIPLY## ~--  Equivalent to using the *= operator
** ##DIVIDE## ~-- Equivalent to using the /= operator
** ##APPEND## ~-- Appends the value to the existing data
** ##CONCAT## ~-- Equivalent to using the &= operator
** ##LEAVE## ~--  If it already exists, the current value is left unchanged
otherwise the new value is added to the map.

===== Example 1:
<eucode>
map ages
ages = new()
put(ages, "Andy", 12)
put(ages, "Budi", 13)
put(ages, "Budi", 14)

-- ages now contains 2 entries: "Andy" => 12, "Budi" => 14
</eucode>

===== See Also:
[[:remove]], [[:has]],  [[:nested_put]]



@[:map:nested_put|]
==== nested_put
<eucode>
include std/map.e
namespace map
public procedure nested_put(map the_map_p, sequence the_keys_p, object the_value_p,
        integer operation_p = PUT, object deprecated_trigger_p = 0)
</eucode>

  adds or updates an entry on a map.

===== Parameters:
# ##the_map_p## : the map where an entry is being added or updated
# ##the_keys_p## : a sequence of keys for the nested maps
# ##the_value_p## : an object, the value to add, or to use for updating.
# ##operation_p## : an integer, indicating what is to be done with ##value##. Defaults to PUT.
# ##deprecated_trigger_p## : Deprecated. This parameter defaults to zero and is not used.


===== Comments:
Valid operations are~:

* ##PUT## ~--  This is the default, and it replaces any value in there already
* ##ADD## ~--  Equivalent to using the += operator
* ##SUBTRACT## ~--  Equivalent to using the -= operator
* ##MULTIPLY## ~--  Equivalent to using the *= operator
* ##DIVIDE## ~-- Equivalent to using the /= operator
* ##APPEND## ~-- Appends the value to the existing data
* ##CONCAT## ~-- Equivalent to using the &= operator

* If existing entry with the same key is already in the map, the value of the entry is updated.

===== Example 1:
<eucode>
map city_population
city_population = new()
nested_put(city_population, {"United States", "California", "Los Angeles"},
    3819951 )
nested_put(city_population, {"Canada",        "Ontario",    "Toronto"},     
    2503281 )
</eucode>

===== See Also:
[[:put]]



@[:map:remove|]
==== remove
<eucode>
include std/map.e
namespace map
public procedure remove(map the_map_p, object key)
</eucode>

  removes an entry with given key from a map.

===== Parameters:
# ##the_map_p## : the map to operate on
# ##key## : an object, the key to remove.

===== Comments:
* If ##key## is not on ##the_map_p##, the ##the_map_p## is returned unchanged.
* If you need to remove all entries, see [[:clear]]

===== Example 1:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, "Amy", 66.9)
remove(the_map_p, "Amy")
-- the_map_p is now an empty map again
</eucode>

===== See Also:
[[:clear]], [[:has]]


@[:map:clear|]
==== clear
<eucode>
include std/map.e
namespace map
public procedure clear(map the_map_p)
</eucode>

  removes all entries in a map.

===== Parameters:
# ##the_map_p## : the map to operate on

===== Comments:
* This is much faster than removing each entry individually.
* If you need to remove just one entry, see [[:remove]]

===== Example 1:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, "Amy", 66.9)
put(the_map_p, "Betty", 67.8)
put(the_map_p, "Claire", 64.1)
...
clear(the_map_p)
-- the_map_p is now an empty map again
</eucode>

===== See Also:
[[:remove]], [[:has]]



@[:map:size|]
==== size
<eucode>
include std/map.e
namespace map
public function size(map the_map_p)
</eucode>

  returns the number of entries in a map.

===== Parameters:
##the_map_p## : the map being queried

===== Returns:
An **integer**, the number of entries it has.

===== Comments:
For an empty map, size will be zero

===== Example 1:
<eucode>
map the_map_p
put(the_map_p, 1, "a")
put(the_map_p, 2, "b")
? size(the_map_p) -- outputs 2
</eucode>

===== See Also:
[[:statistics]]



@[:map:NUM_ENTRIES|]
==== NUM_ENTRIES
<eucode>
include std/map.e
namespace map
public enum NUM_ENTRIES
</eucode>





@[:map:NUM_IN_USE|]
==== NUM_IN_USE
<eucode>
include std/map.e
namespace map
public enum NUM_IN_USE
</eucode>





@[:map:NUM_BUCKETS|]
==== NUM_BUCKETS
<eucode>
include std/map.e
namespace map
public enum NUM_BUCKETS
</eucode>





@[:map:LARGEST_BUCKET|]
==== LARGEST_BUCKET
<eucode>
include std/map.e
namespace map
public enum LARGEST_BUCKET
</eucode>





@[:map:SMALLEST_BUCKET|]
==== SMALLEST_BUCKET
<eucode>
include std/map.e
namespace map
public enum SMALLEST_BUCKET
</eucode>





@[:map:AVERAGE_BUCKET|]
==== AVERAGE_BUCKET
<eucode>
include std/map.e
namespace map
public enum AVERAGE_BUCKET
</eucode>





@[:map:STDEV_BUCKET|]
==== STDEV_BUCKET
<eucode>
include std/map.e
namespace map
public enum STDEV_BUCKET
</eucode>





@[:map:statistics|]
==== statistics
<eucode>
include std/map.e
namespace map
public function statistics(map the_map_p)
</eucode>

  retrieves characteristics of a map.

===== Parameters:
# ##the_map_p## : the map being queried

===== Returns:
A  **sequence**, of 7 integers:
* ##NUM_ENTRIES## ~-- number of entries
* ##NUM_IN_USE## ~-- number of buckets in use
* ##NUM_BUCKETS## ~-- number of buckets
* ##LARGEST_BUCKET## ~-- size of largest bucket
* ##SMALLEST_BUCKET## ~-- size of smallest bucket
* ##AVERAGE_BUCKET## ~-- average size for a bucket
* ##STDEV_BUCKET## ~-- standard deviation for the bucket length series

===== Example 1:
<eucode>
sequence s = statistics(mymap)
printf(1, "The average size of the buckets is %d", s[AVERAGE_BUCKET])
</eucode>



@[:map:keys|]
==== keys
<eucode>
include std/map.e
namespace map
public function keys(map the_map_p, integer sorted_result = 0)
</eucode>

  returns all keys in a map.

===== Parameters:
# ##the_map_p##: the map being queried
# ##sorted_result##: optional integer. 0 [default] means do not sort the
output and 1 means to sort the output before returning.

===== Returns:
A **sequence** made of all the keys in the map.

===== Comments:
If ##sorted_result## is not used, the order of the keys returned is not predicable.

===== Example 1:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence keys
keys = keys(the_map_p) -- keys might be {20,40,10,30} or some other order
keys = keys(the_map_p, 1) -- keys will be {10,20,30,40}
</eucode>

===== See Also:
[[:has]], [[:values]], [[:pairs]]



@[:map:values|]
==== values
<eucode>
include std/map.e
namespace map
public function values(map the_map, object keys = 0, object default_values = 0)
</eucode>

  returns values, without their keys, from a map.

===== Parameters:
# ##the_map## : the map being queried
# ##keys## : optional, key list of values to return.
# ##default_values## : optional default values for keys list

===== Returns:
A **sequence**, of all values stored in ##the_map##.

===== Comments:
* The order of the values returned may not be the same as the putting order.
* Duplicate values are not removed.
* You use the ##keys## parameter to return a specific set of values from
the map. They are returned in the same order as the ##keys## parameter. If
no ##default_values## is given and one is needed, 0 will be used.
* If ##default_values## is an atom, it represents the default value for all
values in ##keys##.
* If ##default_values## is a sequence, and its length is less than ##keys##,
then the last item in ##default_values## is used for the rest of the ##keys##.

===== Example 1:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence values
values = values(the_map_p)
-- values might be {"twenty","forty","ten","thirty"}
-- or some other order
</eucode>

===== Example 2:
<eucode>
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence values
values = values(the_map_p, { 10, 50, 30, 9000 })
-- values WILL be { "ten", 0, "thirty", 0 }
values = values(the_map_p, { 10, 50, 30, 9000 }, {-1,-2,-3,-4})
-- values WILL be { "ten", -2, "thirty", -4 }
</eucode>

===== See Also:
[[:get]], [[:keys]], [[:pairs]]



@[:map:pairs|]
==== pairs
<eucode>
include std/map.e
namespace map
public function pairs(map the_map, integer sorted_result = 0)
</eucode>

  
returns all key:value pairs in a map.

===== Parameters:
# ##the_map_p## : the map to get the data from
# ##sorted_result## : optional integer. 0 [default] means do not sort the
output and 1 means to sort the output before returning.

===== Returns:
A **sequence**, of all key:value pairs stored in ##the_map_p##. Each pair is a
sub-sequence in the form ##{key, value}##

===== Comments:
If ##sorted_result## is not used, the order of the values returned is not predicable.

===== Example 1:
<eucode>
map the_map_p

the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence keyvals
keyvals = pairs(the_map_p) 
-- might be {{20,"twenty"},{40,"forty"},{10,"ten"},{30,"thirty"}}

keyvals = pairs(the_map_p, 1) 
-- will be {{10,"ten"},{20,"twenty"},{30,"thirty"},{40,"forty"}}
</eucode>

===== See Also:
[[:get]], [[:keys]], [[:values]]



@[:map:optimize|]
==== optimize
<eucode>
include std/map.e
namespace map
public procedure optimize(map the_map_p, integer deprecated_max_p = 0,
        atom deprecated_grow_p = 0)
</eucode>

  rehashes a map to increase performance. This procedure is deprecated in
favor of [[:rehash]].

===== Parameters:
# ##the_map_p## : the map being optimized
# ##deprecated_max_p## : unused
# ##deprecated_grow_p## : unused.

===== Comments:
This rehashes the map until either the maximum bucket size is less than
the desired maximum or the maximum bucket size is less than the largest
size statistically expected (mean + 3 standard deviations).

===== See Also:
[[:statistics]], [[:rehash]]



@[:map:load_map|]
==== load_map
<eucode>
include std/map.e
namespace map
public function load_map(object input_file_name)
</eucode>

  loads a map from a file.

===== Parameters:
# ##file_name_p## : The file to load from. This file may have been created
by the [[:save_map]] function. This can either be a
name of a file or an already opened file handle.

===== Returns:
Either a **map**, with all the entries found in ##file_name_p##, or **-1**
if the file failed to open, or **-2** if the file is incorrectly formatted.

===== Comments:
If ##file_name_p## is an already opened file handle, this routine will read
from that file and not close it. Otherwise, the named file will be opened and
closed by this routine.

The input file can be either one created by the [[:save_map]] function or
a manually created or edited text file. See [[:save_map]] for details about
the required layout of the text file.


===== Example 1:
<eucode>
include std/error.e

object loaded
map AppOptions
sequence SavedMap = "c:\\myapp\\options.txt"

loaded = load_map(SavedMap)
if equal(loaded, -1) then
    crash("Map '%s' failed to open", SavedMap)
end iF

-- By now we know that it was loaded and a new map created,
-- so we can assign it to a 'map' variable.
AppOptions = loaded
if get(AppOptions, "verbose", 1) = 3 then
    ShowIntructions()
end if
</eucode>

===== See Also:
[[:new]], [[:save_map]]



@[:map:SM_TEXT|]
==== SM_TEXT
<eucode>
include std/map.e
namespace map
public enum SM_TEXT
</eucode>





@[:map:SM_RAW|]
==== SM_RAW
<eucode>
include std/map.e
namespace map
public enum SM_RAW
</eucode>





@[:map:save_map|]
==== save_map
<eucode>
include std/map.e
namespace map
public function save_map(map the_map_, object file_name_p, integer type_ = SM_TEXT)
</eucode>

  saves a map to a file.

===== Parameters:
# ##m## : a map.
# ##file_name_p## : Either a sequence, the name of the file to save to,
or an open file handle as returned by [[:open]]().
# ##type## : an integer. SM_TEXT for a human-readable format (default),
SM_RAW for a smaller and faster format, but not human-readable.

===== Returns:
An **integer**, the number of keys saved to the file, or -1 if the
save failed.

===== Comments:
If ##file_name_p## is an already opened file handle, this routine will write
to that file and not close it. Otherwise, the named file will be created and
closed by this routine.

The SM_TEXT type saves the map keys and values in a text format which can
be read and edited by standard text editor. Each entry in the map is saved as
a KEY/VALUE pair in the form \\
{{{
key = value
}}}
Note that if the 'key' value is a normal string value, it can be enclosed in
double quotes. If it is not thus quoted, the first character of the key
determines its Euphoria value type. A dash or digit implies an atom, an left-brace
implies a sequence, an alphabetic character implies a text string that extends to the
next equal '=' symbol, and anything else is ignored.

Note that if a line contains a double-dash, then all text from the double-dash
to the end of the line will be ignored. This is so you can optionally add
comments to the saved map. Also, any blank lines are ignored too.

All text after the '=' symbol is assumed to be the map item's value data.

Because some map data can be rather long, it is possible to split the text into
multiple lines, which will be considered by [[:load_map]] as a single //logical//
line. If an line ends with a comma (,) or a dollar sign ($), then the next actual
line is appended to the end of it. After all these physical lines have been
joined into one logical line, all combinations of `",$"` and `,$` are removed.

For example~:
{{{
one = {"first",
"second",
"third",
$
}
second = "A long text ",$
"line that has been",$
" split into three lines"
third = {"first",
"second",
"third"}
}}}
is equivalent to
{{{
one = {"first","second","third"}
second = "A long text line that has been split into three lines"
third = {"first","second","third"}
}}}

The SM_RAW type saves the map in an efficient manner. It is generally smaller
than the text format and is faster to process, but it is not human readable and
standard text editors can not be used to edit it. In this format, the file will
contain three serialized sequences~:
# Header sequence: {integer:format version, string: date and time of save (YYMMDDhhmmss),
sequence: euphoria version {major, minor, revision, patch}}
# Keys. A list of all the keys
# Values. A list of the corresponding values for the keys.

===== Example 1:
<eucode>
include std/error.e

map AppOptions
if save_map(AppOptions, "c:\myapp\options.txt") = -1
    crash("Failed to save application options")
end if

if save_map(AppOptions, "c:\myapp\options.dat", SM_RAW) = -1
    crash("Failed to save application options")
end if
</eucode>

===== See Also:
[[:load_map]]



@[:map:copy|]
==== copy
<eucode>
include std/map.e
namespace map
public function copy(map source_map, object dest_map = 0, integer put_operation = PUT)
</eucode>

  duplicates a map.

===== Parameters:
# ##source_map## : map to copy from
# ##dest_map## : optional, map to copy to
# ##put_operation## : optional, operation to use when ##dest_map## is used.
The default is PUT.

===== Returns:
If ##dest_map##  was not provided, an exact duplicate of ##source_map## otherwise
##dest_map##, which does not have to be empty, is returned with the
new values copied from ##source_map##, according to the ##put_operation## value.

===== Example 1:
<eucode>
map m1 = new()
put(m1, 1, "one")
put(m1, 2, "two")

map m2 = copy(m1)
printf(1, "%s, %s\n", { get(m2, 1), get(m2, 2) })
-- one, two

put(m1, 1, "one hundred")
printf(1, "%s, %s\n", { get(m1, 1), get(m1, 2) })
-- one hundred, two

printf(1, "%s, %s\n", { get(m2, 1), get(m2, 2) })
-- one, two
</eucode>

===== Example 2:
<eucode>
map m1 = new()
map m2 = new()

put(m1, 1, "one")
put(m1, 2, "two")
put(m2, 3, "three")

copy(m1, m2)

? keys(m2)
-- { 1, 2, 3 }
</eucode>

===== Example 3:
<eucode>
map m1 = new()
map m2 = new()

put(m1, "XY", 1)
put(m1, "AB", 2)
put(m2, "XY", 3)

pairs(m1) --> { {"AB", 2}, {"XY", 1} }
pairs(m2) --> { {"XY", 3} }

-- Add same keys' values.
copy(m1, m2, ADD)

pairs(m2) --> { {"AB", 2}, {"XY", 4} }
</eucode>

===== See Also:
[[:put]]



@[:map:new_from_kvpairs|]
==== new_from_kvpairs
<eucode>
include std/map.e
namespace map
public function new_from_kvpairs(sequence kv_pairs)
</eucode>

  converts a set of key:value pairs to a map.

===== Parameters:
# ##kv_pairs## : A seqeuence containing any number of subsequences that
have the format {KEY, VALUE}. These are loaded into a
new map which is then returned by this function.

===== Returns:
A **map**, containing the data from ##kv_pairs##

===== Example 1:
<eucode>
map m1 = new_from_kvpairs( {
    { "application", "Euphoria" },
    { "version", "4.0" },
    { "genre", "programming language" },
    { "crc", 0x4F71AE10 }
})

v = map:get(m1, "application") --> "Euphoria"
</eucode>



@[:map:new_from_string|]
==== new_from_string
<eucode>
include std/map.e
namespace map
public function new_from_string(sequence kv_string)
</eucode>

  converts a set of key:value pairs contained in a string to a map.

===== Parameters:
# ##kv_string## : A string containing any number of lines that
have the format KEY=VALUE. These are loaded into a
new map which is then returned by this function.

===== Returns:
A **map**, containing the data from ##kv_string##

===== Comments:
This function actually calls ##[[:keyvalues]]## to convert the string to
key-value pairs, which are then used to create the map.

===== Example 1:
Given that a file called "xyz.config" contains the lines ...
{{{
application = Euphoria,
version     = 4.0,
genre       = "programming language",
crc         = 4F71AE10
}}}

<eucode>
map m1 = new_from_string( read_file("xyz.config", TEXT_MODE))

printf(1, "%s\n", {map:get(m1, "application")}) --> "Euphoria"
printf(1, "%s\n", {map:get(m1, "genre")})       --> "programming language"
printf(1, "%s\n", {map:get(m1, "version")})     --> "4.0"
printf(1, "%s\n", {map:get(m1, "crc")})         --> "4F71AE10"  
</eucode>



@[:map:for_each|]
==== for_each
<eucode>
include std/map.e
namespace map
public function for_each(map source_map, integer user_rid, object user_data = 0,
        integer in_sorted_order = 0, integer signal_boundary = 0)
</eucode>

  calls a user-defined routine for each of the items in a map.

===== Parameters:
# ##source_map## : The map containing the data to process
# ##user_rid##: The routine_id of a user defined processing function
# ##user_data##: An object. Optional. This is passed, unchanged to each call
of the user defined routine. By default, zero (0) is used.
# ##in_sorted_order##: An integer. Optional. If non-zero the items in the
map are processed in ascending key sequence otherwise
the order is undefined. By default they are not sorted.
# ##signal_boundary##: A integer; 0 (the default) means that the user
routine is not called if the map is empty and when the
last item is passed to the user routine, the Progress Code
is not negative.

===== Returns:
An integer: 0 means that all the items were processed, and anything else is whatever
was returned by the user routine to abort the ##for_each## process.

===== Comments:
* The user defined routine is a function that must accept four parameters.
## Object: an Item Key
## Object: an Item Value
## Object: The ##user_data## value. This is never used by ##for_each## itself,
merely passed to the user routine.
## Integer: Progress code.
*** The ##abs## value of the progress code is the ordinal call number. That
is 1 means the first call, 2 means the second call, etc ...
*** If the progress code is negative, it is also the last call to the routine.
*** If the progress code is zero, it means that the map is empty and thus the
item key and value cannot be used.
*** **note** that if ##signal_boundary## is zero, the Progress Code is never
less than 1.
* The user routine must return 0 to get the next map item. Anything else will
cause ##for_each## to stop running, and is returned to whatever called
##for_each##.
* Note that any changes that the user routine makes to the map do not affect the
order or number of times the routine is called. ##for_each## takes a copy of the
map keys and data before the first call to the user routine and uses the copied
data to call the user routine.

===== Example 1:
<eucode>
include std/map.e
include std/math.e
include std/io.e

function Process_A(object k, object v, object d, integer pc)
    writefln("[] = []", {k, v})
    return 0
end function

function Process_B(object k, object v, object d, integer pc)
    if pc = 0 then
      writefln("The map is empty")
    else
      integer c
      c = abs(pc)
      if c = 1 then
          writefln("---[]---", {d}) -- Write the report title.
      end if
      writefln("[]: [:15] = []", {c, k, v})
      if pc < 0 then
          writefln(repeat('-', length(d) + 6), {}) -- Write the report end.
      end if
    end if
    return 0
end function

map m1 = new()
map:put(m1, "application", "Euphoria")
map:put(m1, "version", "4.0")
map:put(m1, "genre", "programming language")
map:put(m1, "crc", "4F71AE10")

-- Unsorted 
map:for_each(m1, routine_id("Process_A"))
-- Sorted
map:for_each(m1, routine_id("Process_B"), "List of Items", 1)  
</eucode>

The output from the first call could be...
{{{
application = Euphoria
version = 4.0
genre = programming language
crc = 4F71AE10
}}}

The output from the second call should be...
{{{
---List of Items---
1: application     = Euphoria
2: crc             = 4F71AE10
3: genre           = programming language
4: version         = 4.0
-------------------
}}}




!!CONTEXT:../include/std/stack.e
!!namespace:stack
%%output = std_stack

== Stack

<<LEVELTOC level=2 depth=4>>


=== Constants



=== Stack types


@[:stack:FIFO|]
==== FIFO
<eucode>
include std/stack.e
namespace stack
public constant FIFO
</eucode>

  FIFO: like people standing in line: first item in is first item out



@[:stack:FILO|]
==== FILO
<eucode>
include std/stack.e
namespace stack
public constant FILO
</eucode>

  FILO: like for a stack of plates  : first item in is last item out



=== Types



@[:stack:stack|]
==== stack
<eucode>
include std/stack.e
namespace stack
public type stack(object obj_p)
</eucode>

  A stack is a sequence of objects with some internal data.


=== Routines



@[:stack:new|]
==== new
<eucode>
include std/stack.e
namespace stack
public function new(integer typ = FILO)
</eucode>

  creates a new stack.

===== Parameters:
# ##stack_type## : an integer, defining the semantics of the stack. The
default is ##FILO##.

===== Returns:
An empty **stack**, note that the variable storing the stack must
not be an integer.  The resources allocated for the stack will
be automatically cleaned up if the reference count of the returned value drops
to zero, or if passed in a call to [[:delete]].

===== Comments:
There are two sorts of stacks, designated by the types ##FIFO## and ##FILO##~:
* A ##FIFO## stack is one where the first item to be pushed is popped first.
People standing in queue form a ##FIFO## stack.
* A ##FILO## stack is one where the item pushed last is popped first.
A column of coins is of the ##FILO## kind.

===== See Also:
[[:is_empty]]


@[:stack:is_empty|]
==== is_empty
<eucode>
include std/stack.e
namespace stack
public function is_empty(stack sk)
</eucode>

  determines whether a stack is empty.

===== Parameters:
# ##sk## : the stack being queried.

===== Returns:
An **integer**, 1 if the stack is empty, else 0.

===== See Also:
[[:size]]


@[:stack:size|]
==== size
<eucode>
include std/stack.e
namespace stack
public function size(stack sk)
</eucode>

  returns how many elements a stack has.

===== Parameters:
# ##sk## : the stack being queried.

===== Returns:
An **integer**, the number of elements in ##sk##.


@[:stack:at|]
==== at
<eucode>
include std/stack.e
namespace stack
public function at(stack sk, integer idx = 1)
</eucode>

  fetches a value from the stack without removing it from the stack.

===== Parameters:
# ##sk## : the stack being queried
# ##idx## : an integer, the place to inspect. The default is 1 (top item).

===== Returns:
An **object**, the ##idx##-th item of the stack.

===== Errors:
If the supplied value of ##idx## does not correspond to an existing element,
an error occurs.

===== Comments:
* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

##idx## can be less than 1, in which case it refers relative to the end item.
Thus, 0 stands for the end element.

===== Example 1:
<eucode>
stack sk = new(FILO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)

at(sk, 0)  --> 5
at(sk, -1) --> "abc"
at(sk, 1)  --> 2.3
at(sk, 2)  --> "abc"
</eucode>

===== Example 2:
<eucode>
stack sk = new(FIFO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)
at(sk, 0)  --> 2.3
at(sk, -1) --> "abc"
at(sk, 1)  --> 5
at(sk, 2)  --> "abc"
</eucode>

===== See Also:
[[:size]], [[:top]], [[:peek_top]], [[:peek_end]]



@[:stack:push|]
==== push
<eucode>
include std/stack.e
namespace stack
public procedure push(stack sk, object value)
</eucode>

  adds something to a stack.

===== Parameters:
# ##sk## : the stack to augment
# ##value## : an object, the value to push.

===== Comments:
##value## appears at the end of ##FIFO## stacks and the top of ##FILO## stacks.
The size of the stack increases by one.

===== Example 1:
<eucode>
stack sk = new(FIFO)

push(sk,5)
push(sk,"abc")
push(sk, 2.3)
top(sk)  --> 5
last(sk) --> 2.3
</eucode>

===== Example 2:
<eucode>
stack sk = new(FILO)

push(sk,5)
push(sk,"abc")
push(sk, 2.3)
top(sk)  --> 2.3
last(sk) --> 5
</eucode>

===== See Also:
[[:pop]], [[:top]]



@[:stack:top|]
==== top
<eucode>
include std/stack.e
namespace stack
public function top(stack sk)
</eucode>

  retrieve the top element on a stack.

===== Parameters:
# ##sk## : the stack to inspect.

===== Returns:
An **object**, the top element on a stack.

===== Comments:
This call is equivalent to ##at(sk,1)##.

===== Example 1:
<eucode>
stack sk = new(FILO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)

top(sk) --> 2.3
</eucode>

===== Example 2:
<eucode>
stack sk = new(FIFO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)

top(sk) --> 5
</eucode>

===== See Also:
[[:at]], [[:pop]], [[:peek_top]], [[:last]]



@[:stack:last|]
==== last
<eucode>
include std/stack.e
namespace stack
public function last(stack sk)
</eucode>

  retrieves the end element on a stack.

===== Parameters:
# ##sk## : the stack to inspect.

===== Returns:
An **object**, the end element on a stack.

===== Comments:
This call is equivalent to ##at(sk,0)##.

===== Example 1:
<eucode>
stack sk = new(FILO)

push(sk,5)
push(sk,"abc")
push(sk, 2.3)

last(sk) --> 5
</eucode>

===== Example 2:
<eucode>
stack sk = new(FIFO)

push(sk,5)
push(sk,"abc")
push(sk, 2.3)

last(sk) --> 2.3
</eucode>

===== See Also:
[[:at]], [[:pop]], [[:peek_end]], [[:top]]


@[:stack:pop|]
==== pop
<eucode>
include std/stack.e
namespace stack
public function pop(stack sk, integer idx = 1)
</eucode>

  removes an object from a stack.

===== Parameters:
# ##sk## : the stack to pop
# ##idx## : integer. The n-th item to pick from the stack. The default is 1.

===== Returns:
An **item**, from the stack, which is also removed from the stack.

===== Errors:
* If the stack is empty, an error occurs.
* If the ##idx## is greater than the number of items in the stack, an error occurs.

===== Comments:
* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

When ##idx## is omitted the 'top' of the stack is removed and returned.
When ##idx## is supplied, it represents the n-th item from the top to be
removed and returned. Thus an ##idx## of ##2## returns the 2nd item from the
top, a value of ##3## returns the 3rd item from the top, and so on.

===== Example 1:
<eucode>
stack sk = new(FIFO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? size(sk) -- 3
? pop(sk) -- 1
? size(sk) -- 2
? pop(sk) -- 2
? size(sk) -- 1
? pop(sk) -- 3
? size(sk) -- 0
? pop(sk) -- *error*
</eucode>

===== Example 2:
<eucode>
stack sk = new(FILO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? size(sk) -- 3
? pop(sk) -- 3
? size(sk) -- 2
? pop(sk) -- 2
? size(sk) -- 1
? pop(sk) -- 1
? size(sk) -- 0
? pop(sk) -- *error*
</eucode>

===== Example 3:
<eucode>
stack sk = new(FILO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
push(sk, 4)
-- stack contains {1,2,3,4} (oldest to newest)
? size(sk) -- 4
? pop(sk, 2) -- Pluck out the 2nd newest item .. 3
? size(sk) -- 3 
-- stack now contains {1,2,4}
</eucode>

===== Example 4:
<eucode>
stack sk = new(FIFO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
push(sk, 4)
-- stack contains {1,2,3,4} (oldest to newest)
? size(sk) -- 4
? pop(sk, 2) -- Pluck out the 2nd oldest item .. 2
? size(sk) -- 3 
-- stack now contains {1,3,4}
</eucode>

===== See Also:
[[:push]], [[:top]], [[:is_empty]]


@[:stack:peek_top|]
==== peek_top
<eucode>
include std/stack.e
namespace stack
public function peek_top(stack sk, integer idx = 1)
</eucode>

  gets an object, relative to the top, from a stack.

===== Parameters:
# ##sk## : the stack to get from.
# ##idx## : integer. The n-th item to get from the stack. The default is 1.

===== Returns:
An **item**, from the stack, which is **not** removed from the stack.

===== Errors:
* If the stack is empty, an error occurs.
* If the ##idx## is greater than the number of items in the stack, an error occurs.

===== Comments:
This is identical to [[:pop]] except that it does not remove the item.

* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

When ##idx## is omitted the 'top' of the stack is returned.
When ##idx## is supplied, it represents the n-th item from the top to be
returned. Thus an ##idx## of ##2## returns the 2nd item from the
top, a value of ##3## returns the 3rd item from the top, and so on.

===== Example 1:
<eucode>
stack sk = new(FIFO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? peek_top(sk) -- 1
? peek_top(sk,2) -- 2
? peek_top(sk,3) -- 3
? peek_top(sk,4) -- *error*
? peek_top(sk, size(sk)) -- 3 (end item)
</eucode>

===== Example 2:
<eucode>
stack sk = new(FILO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? peek_top(sk) -- 3
? peek_top(sk,2) -- 2
? peek_top(sk,3) -- 1
? peek_top(sk,4) -- *error*
? peek_top(sk, size(sk)) -- 1 (end item)
</eucode>

===== See Also:
[[:pop]], [[:top]], [[:is_empty]], [[:size]], [[:peek_end]]


@[:stack:peek_end|]
==== peek_end
<eucode>
include std/stack.e
namespace stack
public function peek_end(stack sk, integer idx = 1)
</eucode>

  gets an object, relative to the end, from a stack.

===== Parameters:
# ##sk## : the stack to get from.
# ##idx## : integer. The n-th item from the end to get from the stack. The default is 1.

===== Returns:
An **item**, from the stack, which is **not** removed from the stack.

===== Errors:
* If the stack is empty, an error occurs.
* If the ##idx## is greater than the number of items in the stack, an error occurs.

===== Comments:
* For ##FIFO## stacks (queues), the end item is the newest item in the stack.
* For ##FILO## stacks, the end item is the oldest item in the stack.

When ##idx## is omitted the 'end' of the stack is returned.
When ##idx## is supplied, it represents the n-th item from the end to be
returned. Thus an ##idx## of ##2## returns the 2nd item from the
end, a value of ##3## returns the 3rd item from the end, and so on.

===== Example 1:
<eucode>
stack sk = new(FIFO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? peek_end(sk) -- 3
? peek_end(sk,2) -- 2
? peek_end(sk,3) -- 1
? peek_end(sk,4) -- *error*
? peek_end(sk, size(sk)) -- 3 (top item)
</eucode>

===== Example 2:
<eucode>
stack sk = new(FILO)
push(sk, 1)
push(sk, 2)
push(sk, 3)
? peek_end(sk) -- 1
? peek_end(sk,2) -- 2
? peek_end(sk,3) -- 3
? peek_end(sk,4) -- *error*
? peek_end(sk, size(sk)) -- 3 (top item)
</eucode>

===== See Also:
[[:pop]], [[:top]], [[:is_empty]], [[:size]], [[:peek_top]]


@[:stack:swap|]
==== swap
<eucode>
include std/stack.e
namespace stack
public procedure swap(stack sk)
</eucode>

  swaps the top two elements of a stack.

===== Parameters:
# ##sk## : the stack to swap.

===== Returns:
A **copy**, of the original **stack**, with the top two elements swapped.

===== Comments:
* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

===== Errors:
If the stack has less than two elements, an error occurs.

===== Example 1:
<eucode>
stack sk = new(FILO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)
push(sk, "")

? peek_top(sk, 1) --> ""
? peek_top(sk, 2) --> 2.3

swap(sk)

? peek_top(sk, 1) --> 2.3
? peek_top(sk, 2) --> ""
</eucode>

===== Example 2:
<eucode>
stack sk = new(FIFO)

push(sk, 5)
push(sk, "abc")
push(sk, 2.3)
push(sk, "")

peek_top(sk, 1) --> 5
peek_top(sk, 2) --> "abc"

swap(sk)

peek_top(sk, 1) --> "abc"
peek_top(sk, 2) --> 5
</eucode>



@[:stack:dup|]
==== dup
<eucode>
include std/stack.e
namespace stack
public procedure dup(stack sk)
</eucode>

  repeats the top element of a stack.

===== Parameters:
# ##sk## : the stack.


===== Comments:
* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

===== Side Effect:
The value of ##top## is pushed onto the stack, thus
the stack size grows by one.

===== Errors:
If the stack has no elements, an error occurs.

===== Example 1:
<eucode>
stack sk = new(FILO)

push(sk,5)
push(sk,"abc")
push(sk, "")

dup(sk)

peek_top(sk,1) --> ""
peek_top(sk,2) --> "abc"
size(sk)       --> 3

dup(sk)

peek_top(sk,1) --> ""
peek_top(sk,2) --> ""
peek_top(sk,3) --> "abc"
size(sk)       --> 4
</eucode>

===== Example 1:
<eucode>
stack sk = new(FIFO)

push(sk, 5)
push(sk, "abc")
push(sk, "")

dup(sk)

peek_top(sk, 1) --> 5
peek_top(sk, 2) --> "abc"
size(sk)        --> 3

dup(sk)

peek_top(sk, 1) --> 5
peek_top(sk, 2) --> 5
peek_top(sk, 3) --> "abc"
size(sk)        --> 4
</eucode>



@[:stack:set|]
==== set
<eucode>
include std/stack.e
namespace stack
public procedure set(stack sk, object val, integer idx = 1)
</eucode>

  updates a value on the stack.

===== Parameters:
# ##sk## : the stack being queried
# ##val## : an object, the value to place on the stack
# ##idx## : an integer, the place to inspect. The default is 1 (the top item)

===== Errors:
If the supplied value of ##idx## does not correspond to an existing element, an error occurs.

===== Comments:
* For ##FIFO## stacks (queues), the top item is the oldest item in the stack.
* For ##FILO## stacks, the top item is the newest item in the stack.

##idx## can be less than one, in which case it refers to an element relative
to the end of the stack. Thus  ##0## stands for the end element.

===== See Also:
[[:size]], [[:top]]



@[:stack:clear|]
==== clear
<eucode>
include std/stack.e
namespace stack
public procedure clear(stack sk)
</eucode>

  wipes out a stack.

===== Parameters:
# ##sk## : the stack to clear.

===== Side Effect:
The stack contents is emptied.

===== See Also:
[[:new]], [[:is_empty]]




!!CONTEXT:../include/std/scinot.e
%%output = std_scinot

== Scientific Notation Parsing

<<LEVELTOC level=2 depth=4>>

=== Parsing routines
The parsing functions require a sequence containing a correctly formed scientific notation
representation of a number.  The general pattern is an optional negative sign (-), a number,
usually with a decimal point, followed by an upper case or lower case 'e', then optionally
a plus (+) or a minus (-) sign, and an integer.  There should be no spaces or other characters.
The following are valid numbers~:
{{{
1e0
3.1415e-2
-9.0E+3
}}}
This library evaluates scientific notation to the highest level of precision possible using
Euphoria atoms.  An atom in 32-bit euphoria can have up to 16 digits of precision
(19 in 64-bit euphoria).  A number represented by scientific notation could contain up to 17
(or 20) digits.  The 17th (or 20th) supplied digit may have an effect upon the value of the
atom due to rounding errors in the calculations.

This does not mean that if the 17th (or 20th) digit is 5 or higher, you should include it.  The
calculations are much more complicated, because a decimal fraction has to be converted to a
binary fraction, and there is not really a one-to-one correspondence between the decimal
digits and the bits in the resulting atom.  The 18th or higher digit, however, will never
have an effect on the resulting atom.

The biggest and smallest (magnitude) atoms possible are~:
{{{
32-bit:
1.7976931348623157e+308
4.9406564584124654e-324
}}}


=== Floating Point Types


@[:NATIVE|]
==== NATIVE
<eucode>
include std/scinot.e
public enum NATIVE
</eucode>

NATIVE
Use whatever is the appropriate format based upon the version of
euphoria being used (DOUBLE for 32-bit, EXTENDED for 64-bit)




@[:DOUBLE|]
==== DOUBLE
<eucode>
include std/scinot.e
public enum DOUBLE
</eucode>

===== DOUBLE:
Description
IEEE 754 double (64-bit) floating point format.
The native 32-bit euphoria floating point representation.




@[:EXTENDED|]
==== EXTENDED
<eucode>
include std/scinot.e
public enum EXTENDED
</eucode>

 EXTENDED: 80-bit floating point format.The native 64-bit euphoria floating point reprepresentation.




@[:bits_to_bytes|]
==== bits_to_bytes
<eucode>
include std/scinot.e
public function bits_to_bytes(sequence bits)
</eucode>

Takes a sequence of bits (all elements either 0 or 1) and converts it
into a sequence of bytes.

===== Parameters:
# ##bits## : sequence of ones and zeroes

Returns a sequence of 8-bit integers


@[:bytes_to_bits|]
==== bytes_to_bits
<eucode>
include std/scinot.e
public function bytes_to_bits(sequence bytes)
</eucode>

Converts a sequence of bytes (all elements integers between 0 and 255) and
converts it into a sequence of bits.

===== Parameters:
# ##bytes## : sequence of values from 0-255

===== Returns:
Sequence of bits (ones and zeroes)


@[:scientific_to_float|]
==== scientific_to_float
<eucode>
include std/scinot.e
public function scientific_to_float(sequence s, floating_point fp = NATIVE)
</eucode>

Takes a string reprepresentation of a number in scientific notation and
the requested precision (DOUBLE or EXTENDED) and returns a sequence of
bytes in the raw format of an IEEE 754 double or extended
precision floating point number.  This value can be passed to the euphoria
library function, ##[[:float64_to_atom]]## or ##[[:float80_to_atom]]##, respectively.

===== Parameters:
# ##s## : string representation of a number, e.g., "1.23E4"
# ##fp## : the required precision for the ultimate representation
## ##DOUBLE## Use IEEE 754, the euphoria representation used in 32-bit euphoria
## ##EXTENDED## Use Extended Floating Point, the euphoria representation in 64-bit euphoria

===== Returns:
Sequence of bytes that represents the physical form of the converted floating point number.

===== Note:
Does not check if the string exceeds IEEE 754 double precision limits.



@[:scientific_to_atom|]
==== scientific_to_atom
<eucode>
include std/scinot.e
public function scientific_to_atom(sequence s, floating_point fp = NATIVE)
</eucode>

Takes a string reprepresentation of a number in scientific notation and returns
an atom.

===== Parameters:
# ##s## : string representation of a number (such as "1.23E4" ).
# ##fp## : the required precision for the ultimate representation.
## ##DOUBLE## Use IEEE 754, the euphoria representation used in 32-bit Euphoria.
## ##EXTENDED## Use Extended Floating Point, the euphoria representation in 64-bit Euphoria.

===== Returns:
Euphoria atom floating point number.



!!CONTEXT:../include/std/socket.e
!!namespace:sockets
%%output = std_socket

== Core Sockets

<<LEVELTOC level=2 depth=4>>



=== Error Information



@[:sockets:error_code|]
==== error_code
<eucode>
include std/socket.e
namespace sockets
public function error_code()
</eucode>

  gets the error code.

===== Returns:
Integer [[:OK]] on no error, otherwise any one of the ##ERR_## constants to
follow.



@[:sockets:OK|]
==== OK
<eucode>
include std/socket.e
namespace sockets
public constant OK
</eucode>

  No error occurred.


@[:sockets:ERR_ACCESS|]
==== ERR_ACCESS
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ACCESS
</eucode>

  Permission has been denied. This can happen when using a send_to call on a broadcast
address without setting the socket option SO_BROADCAST. Another, possibly more common,
reason is you have tried to bind an address that is already exclusively bound by
another application.

May occur on a Unix Domain Socket when the socket directory or file could not be
accessed due to security.


@[:sockets:ERR_ADDRINUSE|]
==== ERR_ADDRINUSE
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ADDRINUSE
</eucode>

  Address is already in use.


@[:sockets:ERR_ADDRNOTAVAIL|]
==== ERR_ADDRNOTAVAIL
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ADDRNOTAVAIL
</eucode>

  The specified address is not a valid local IP address on this computer.


@[:sockets:ERR_AFNOSUPPORT|]
==== ERR_AFNOSUPPORT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_AFNOSUPPORT
</eucode>

  Address family not supported by the protocol family.


@[:sockets:ERR_AGAIN|]
==== ERR_AGAIN
<eucode>
include std/socket.e
namespace sockets
public constant ERR_AGAIN
</eucode>

  Kernel resources to complete the request are temporarly unavailable.


@[:sockets:ERR_ALREADY|]
==== ERR_ALREADY
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ALREADY
</eucode>

  Operation is already in progress.


@[:sockets:ERR_CONNABORTED|]
==== ERR_CONNABORTED
<eucode>
include std/socket.e
namespace sockets
public constant ERR_CONNABORTED
</eucode>

  Software has caused a connection to be aborted.


@[:sockets:ERR_CONNREFUSED|]
==== ERR_CONNREFUSED
<eucode>
include std/socket.e
namespace sockets
public constant ERR_CONNREFUSED
</eucode>

  Connection was refused.


@[:sockets:ERR_CONNRESET|]
==== ERR_CONNRESET
<eucode>
include std/socket.e
namespace sockets
public constant ERR_CONNRESET
</eucode>

  An incomming connection was supplied however it was terminated by the remote peer.


@[:sockets:ERR_DESTADDRREQ|]
==== ERR_DESTADDRREQ
<eucode>
include std/socket.e
namespace sockets
public constant ERR_DESTADDRREQ
</eucode>

  Destination address required.


@[:sockets:ERR_FAULT|]
==== ERR_FAULT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_FAULT
</eucode>

  Address creation has failed internally.


@[:sockets:ERR_HOSTUNREACH|]
==== ERR_HOSTUNREACH
<eucode>
include std/socket.e
namespace sockets
public constant ERR_HOSTUNREACH
</eucode>

  No route to the host specified could be found.


@[:sockets:ERR_INPROGRESS|]
==== ERR_INPROGRESS
<eucode>
include std/socket.e
namespace sockets
public constant ERR_INPROGRESS
</eucode>

  A blocking call is inprogress.


@[:sockets:ERR_INTR|]
==== ERR_INTR
<eucode>
include std/socket.e
namespace sockets
public constant ERR_INTR
</eucode>

  A blocking call was cancelled or interrupted.


@[:sockets:ERR_INVAL|]
==== ERR_INVAL
<eucode>
include std/socket.e
namespace sockets
public constant ERR_INVAL
</eucode>

  An invalid sequence of command calls were made, for instance trying to ##accept##
before an actual ##listen## was called.


@[:sockets:ERR_IO|]
==== ERR_IO
<eucode>
include std/socket.e
namespace sockets
public constant ERR_IO
</eucode>

  An I/O error occurred while making the directory entry or allocating the
inode. (Unix Domain Socket).


@[:sockets:ERR_ISCONN|]
==== ERR_ISCONN
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ISCONN
</eucode>

  Socket is already connected.


@[:sockets:ERR_ISDIR|]
==== ERR_ISDIR
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ISDIR
</eucode>

  An empty pathname was specified. (Unix Domain Socket).


@[:sockets:ERR_LOOP|]
==== ERR_LOOP
<eucode>
include std/socket.e
namespace sockets
public constant ERR_LOOP
</eucode>

  Too many symbolic links were encountered. (Unix Domain Socket).


@[:sockets:ERR_MFILE|]
==== ERR_MFILE
<eucode>
include std/socket.e
namespace sockets
public constant ERR_MFILE
</eucode>

  The queue is not empty upon routine call.


@[:sockets:ERR_MSGSIZE|]
==== ERR_MSGSIZE
<eucode>
include std/socket.e
namespace sockets
public constant ERR_MSGSIZE
</eucode>

  Message is too long for buffer size. This would indicate an internal error to
Euphoria as Euphoria sets a dynamic buffer size.


@[:sockets:ERR_NAMETOOLONG|]
==== ERR_NAMETOOLONG
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NAMETOOLONG
</eucode>

  Component of the path name exceeded 255 characters or the entire path
exceeded 1023 characters. (Unix Domain Socket).


@[:sockets:ERR_NETDOWN|]
==== ERR_NETDOWN
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NETDOWN
</eucode>

  The network subsystem is down or has failed


@[:sockets:ERR_NETRESET|]
==== ERR_NETRESET
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NETRESET
</eucode>

  Network has dropped it's connection on reset.


@[:sockets:ERR_NETUNREACH|]
==== ERR_NETUNREACH
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NETUNREACH
</eucode>

  Network is unreachable.


@[:sockets:ERR_NFILE|]
==== ERR_NFILE
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NFILE
</eucode>

  Not a file. (Unix Domain Sockets).


@[:sockets:ERR_NOBUFS|]
==== ERR_NOBUFS
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOBUFS
</eucode>

  No buffer space is available.


@[:sockets:ERR_NOENT|]
==== ERR_NOENT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOENT
</eucode>

  Named socket does not exist. (Unix Domain Socket).


@[:sockets:ERR_NOTCONN|]
==== ERR_NOTCONN
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOTCONN
</eucode>

  Socket is not connected.


@[:sockets:ERR_NOTDIR|]
==== ERR_NOTDIR
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOTDIR
</eucode>

  Component of the path prefix is not a directory. (Unix Domain Socket).


@[:sockets:ERR_NOTINITIALISED|]
==== ERR_NOTINITIALISED
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOTINITIALISED
</eucode>

  Socket system is not initialized (Windows only)


@[:sockets:ERR_NOTSOCK|]
==== ERR_NOTSOCK
<eucode>
include std/socket.e
namespace sockets
public constant ERR_NOTSOCK
</eucode>

  The descriptor is not a socket.


@[:sockets:ERR_OPNOTSUPP|]
==== ERR_OPNOTSUPP
<eucode>
include std/socket.e
namespace sockets
public constant ERR_OPNOTSUPP
</eucode>

  Operation is not supported on this type of socket.


@[:sockets:ERR_PROTONOSUPPORT|]
==== ERR_PROTONOSUPPORT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_PROTONOSUPPORT
</eucode>

  Protocol not supported.


@[:sockets:ERR_PROTOTYPE|]
==== ERR_PROTOTYPE
<eucode>
include std/socket.e
namespace sockets
public constant ERR_PROTOTYPE
</eucode>

  Protocol is the wrong type for the socket.


@[:sockets:ERR_ROFS|]
==== ERR_ROFS
<eucode>
include std/socket.e
namespace sockets
public constant ERR_ROFS
</eucode>

  The name would reside on a read-only file system. (Unix Domain Socket).


@[:sockets:ERR_SHUTDOWN|]
==== ERR_SHUTDOWN
<eucode>
include std/socket.e
namespace sockets
public constant ERR_SHUTDOWN
</eucode>

  The socket has been shutdown. Possibly a send/receive call after a shutdown took
place.


@[:sockets:ERR_SOCKTNOSUPPORT|]
==== ERR_SOCKTNOSUPPORT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_SOCKTNOSUPPORT
</eucode>

  Socket type is not supported.


@[:sockets:ERR_TIMEDOUT|]
==== ERR_TIMEDOUT
<eucode>
include std/socket.e
namespace sockets
public constant ERR_TIMEDOUT
</eucode>

  Connection has timed out.


@[:sockets:ERR_WOULDBLOCK|]
==== ERR_WOULDBLOCK
<eucode>
include std/socket.e
namespace sockets
public constant ERR_WOULDBLOCK
</eucode>

  The operation would block on a socket marked as non-blocking.


=== Socket Backend Constants

These values are used by the Euphoria backend to pass information to this
library. The TYPE constants are used to identify to the [[:info]] function
which family of constants are being retrieved (AF protocols, socket types,
and socket options, respectively).



@[:sockets:ESOCK_UNDEFINED_VALUE|]
==== ESOCK_UNDEFINED_VALUE
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_UNDEFINED_VALUE
</eucode>

 when a particular constant was not defined by C,the backend returns this value




@[:sockets:ESOCK_UNKNOWN_FLAG|]
==== ESOCK_UNKNOWN_FLAG
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_UNKNOWN_FLAG
</eucode>

 if the backend doesn't recognize the flag in question



@[:sockets:ESOCK_TYPE_AF|]
==== ESOCK_TYPE_AF
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_TYPE_AF
</eucode>





@[:sockets:ESOCK_TYPE_TYPE|]
==== ESOCK_TYPE_TYPE
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_TYPE_TYPE
</eucode>





@[:sockets:ESOCK_TYPE_OPTION|]
==== ESOCK_TYPE_OPTION
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_TYPE_OPTION
</eucode>





=== Socket Type Euphoria Constants

These values are used to retrieve the known values for ##family## and
##sock_type## parameters of the [[:create]] function from the Euphoria
backend. (The reason for doing it this way is to retrieve the values defined
in C, instead of duplicating them here.) These constants are guarranteed
to never change, and to be the same value across platforms.



@[:sockets:EAF_UNSPEC|]
==== EAF_UNSPEC
<eucode>
include std/socket.e
namespace sockets
public constant EAF_UNSPEC
</eucode>

Address family is unspecified




@[:sockets:EAF_UNIX|]
==== EAF_UNIX
<eucode>
include std/socket.e
namespace sockets
public constant EAF_UNIX
</eucode>

Local communications




@[:sockets:EAF_INET|]
==== EAF_INET
<eucode>
include std/socket.e
namespace sockets
public constant EAF_INET
</eucode>

IPv4 Internet protocols




@[:sockets:EAF_INET6|]
==== EAF_INET6
<eucode>
include std/socket.e
namespace sockets
public constant EAF_INET6
</eucode>

IPv6 Internet protocols




@[:sockets:EAF_APPLETALK|]
==== EAF_APPLETALK
<eucode>
include std/socket.e
namespace sockets
public constant EAF_APPLETALK
</eucode>

Appletalk




@[:sockets:EAF_BTH|]
==== EAF_BTH
<eucode>
include std/socket.e
namespace sockets
public constant EAF_BTH
</eucode>

Bluetooth (currently Windows-only)




@[:sockets:ESOCK_STREAM|]
==== ESOCK_STREAM
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_STREAM
</eucode>

Provides sequenced, reliable, two-way, connection-based byte streams.
An out-of-band data transmission mechanism may be supported.




@[:sockets:ESOCK_DGRAM|]
==== ESOCK_DGRAM
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_DGRAM
</eucode>

Supports datagrams (connectionless, unreliable messages of a
fixed maximum length).




@[:sockets:ESOCK_RAW|]
==== ESOCK_RAW
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_RAW
</eucode>

Provides raw network protocol access.




@[:sockets:ESOCK_RDM|]
==== ESOCK_RDM
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_RDM
</eucode>

Provides a reliable datagram layer that does not guarantee ordering.




@[:sockets:ESOCK_SEQPACKET|]
==== ESOCK_SEQPACKET
<eucode>
include std/socket.e
namespace sockets
public constant ESOCK_SEQPACKET
</eucode>

Obsolete and should not be used in new programs




=== Socket Type Constants

These values are passed as the ##family## and ##sock_type## parameters of
the [[:create]] function. They are OS-dependent.



@[:sockets:AF_UNSPEC|]
==== AF_UNSPEC
<eucode>
include std/socket.e
namespace sockets
public constant AF_UNSPEC
</eucode>

Address family is unspecified




@[:sockets:AF_UNIX|]
==== AF_UNIX
<eucode>
include std/socket.e
namespace sockets
public constant AF_UNIX
</eucode>

Local communications




@[:sockets:AF_INET|]
==== AF_INET
<eucode>
include std/socket.e
namespace sockets
public constant AF_INET
</eucode>

IPv4 Internet protocols




@[:sockets:AF_INET6|]
==== AF_INET6
<eucode>
include std/socket.e
namespace sockets
public constant AF_INET6
</eucode>

IPv6 Internet protocols




@[:sockets:AF_APPLETALK|]
==== AF_APPLETALK
<eucode>
include std/socket.e
namespace sockets
public constant AF_APPLETALK
</eucode>

Appletalk




@[:sockets:AF_BTH|]
==== AF_BTH
<eucode>
include std/socket.e
namespace sockets
public constant AF_BTH
</eucode>

Bluetooth (currently Windows-only)




@[:sockets:SOCK_STREAM|]
==== SOCK_STREAM
<eucode>
include std/socket.e
namespace sockets
public constant SOCK_STREAM
</eucode>

Provides sequenced, reliable, two-way, connection-based byte streams.
An out-of-band data transmission mechanism may be supported.




@[:sockets:SOCK_DGRAM|]
==== SOCK_DGRAM
<eucode>
include std/socket.e
namespace sockets
public constant SOCK_DGRAM
</eucode>

Supports datagrams (connectionless, unreliable messages of a
fixed maximum length).




@[:sockets:SOCK_RAW|]
==== SOCK_RAW
<eucode>
include std/socket.e
namespace sockets
public constant SOCK_RAW
</eucode>

Provides raw network protocol access.




@[:sockets:SOCK_RDM|]
==== SOCK_RDM
<eucode>
include std/socket.e
namespace sockets
public constant SOCK_RDM
</eucode>

Provides a reliable datagram layer that does not guarantee ordering.




@[:sockets:SOCK_SEQPACKET|]
==== SOCK_SEQPACKET
<eucode>
include std/socket.e
namespace sockets
public constant SOCK_SEQPACKET
</eucode>

Obsolete and should not be used in new programs




=== Select Accessor Constants

Use with the result of [[:select]].



@[:sockets:SELECT_SOCKET|]
==== SELECT_SOCKET
<eucode>
include std/socket.e
namespace sockets
public enum SELECT_SOCKET
</eucode>

The socket




@[:sockets:SELECT_IS_READABLE|]
==== SELECT_IS_READABLE
<eucode>
include std/socket.e
namespace sockets
public enum SELECT_IS_READABLE
</eucode>

Boolean (1/0) value indicating the readability.




@[:sockets:SELECT_IS_WRITABLE|]
==== SELECT_IS_WRITABLE
<eucode>
include std/socket.e
namespace sockets
public enum SELECT_IS_WRITABLE
</eucode>

Boolean (1/0) value indicating the writeability.




@[:sockets:SELECT_IS_ERROR|]
==== SELECT_IS_ERROR
<eucode>
include std/socket.e
namespace sockets
public enum SELECT_IS_ERROR
</eucode>

Boolean (1/0) value indicating the error state.




=== Shutdown Options

Pass one of the following to the ##method## parameter of [[:shutdown]].



@[:sockets:SD_SEND|]
==== SD_SEND
<eucode>
include std/socket.e
namespace sockets
public constant SD_SEND
</eucode>

Shutdown the send operations.




@[:sockets:SD_RECEIVE|]
==== SD_RECEIVE
<eucode>
include std/socket.e
namespace sockets
public constant SD_RECEIVE
</eucode>

Shutdown the receive operations.




@[:sockets:SD_BOTH|]
==== SD_BOTH
<eucode>
include std/socket.e
namespace sockets
public constant SD_BOTH
</eucode>

Shutdown both send and receive operations.




=== Socket Options

Pass to the ##optname## parameter of the functions [[:get_option]]
and [[:set_option]].

These options are highly OS specific and are normally not needed for most
socket communication. They are provided here for your convenience. If you should
need to set socket options, please refer to your OS reference material.

There may be other values that your OS defines and some defined here are not
supported on all operating systems.


====  Socket Options In Common


@[:sockets:SOL_SOCKET|]
==== SOL_SOCKET
<eucode>
include std/socket.e
namespace sockets
public constant SOL_SOCKET
</eucode>





@[:sockets:SO_DEBUG|]
==== SO_DEBUG
<eucode>
include std/socket.e
namespace sockets
public constant SO_DEBUG
</eucode>





@[:sockets:SO_ACCEPTCONN|]
==== SO_ACCEPTCONN
<eucode>
include std/socket.e
namespace sockets
public constant SO_ACCEPTCONN
</eucode>





@[:sockets:SO_REUSEADDR|]
==== SO_REUSEADDR
<eucode>
include std/socket.e
namespace sockets
public constant SO_REUSEADDR
</eucode>





@[:sockets:SO_KEEPALIVE|]
==== SO_KEEPALIVE
<eucode>
include std/socket.e
namespace sockets
public constant SO_KEEPALIVE
</eucode>





@[:sockets:SO_DONTROUTE|]
==== SO_DONTROUTE
<eucode>
include std/socket.e
namespace sockets
public constant SO_DONTROUTE
</eucode>





@[:sockets:SO_BROADCAST|]
==== SO_BROADCAST
<eucode>
include std/socket.e
namespace sockets
public constant SO_BROADCAST
</eucode>





@[:sockets:SO_LINGER|]
==== SO_LINGER
<eucode>
include std/socket.e
namespace sockets
public constant SO_LINGER
</eucode>





@[:sockets:SO_SNDBUF|]
==== SO_SNDBUF
<eucode>
include std/socket.e
namespace sockets
public constant SO_SNDBUF
</eucode>





@[:sockets:SO_RCVBUF|]
==== SO_RCVBUF
<eucode>
include std/socket.e
namespace sockets
public constant SO_RCVBUF
</eucode>





@[:sockets:SO_SNDLOWAT|]
==== SO_SNDLOWAT
<eucode>
include std/socket.e
namespace sockets
public constant SO_SNDLOWAT
</eucode>





@[:sockets:SO_RCVLOWAT|]
==== SO_RCVLOWAT
<eucode>
include std/socket.e
namespace sockets
public constant SO_RCVLOWAT
</eucode>





@[:sockets:SO_SNDTIMEO|]
==== SO_SNDTIMEO
<eucode>
include std/socket.e
namespace sockets
public constant SO_SNDTIMEO
</eucode>





@[:sockets:SO_RCVTIMEO|]
==== SO_RCVTIMEO
<eucode>
include std/socket.e
namespace sockets
public constant SO_RCVTIMEO
</eucode>





@[:sockets:SO_ERROR|]
==== SO_ERROR
<eucode>
include std/socket.e
namespace sockets
public constant SO_ERROR
</eucode>





@[:sockets:SO_TYPE|]
==== SO_TYPE
<eucode>
include std/socket.e
namespace sockets
public constant SO_TYPE
</eucode>





@[:sockets:SO_OOBINLINE|]
==== SO_OOBINLINE
<eucode>
include std/socket.e
namespace sockets
public constant SO_OOBINLINE
</eucode>





====  Windows Socket Options


@[:sockets:SO_USELOOPBACK|]
==== SO_USELOOPBACK
<eucode>
include std/socket.e
namespace sockets
public constant SO_USELOOPBACK
</eucode>





@[:sockets:SO_DONTLINGER|]
==== SO_DONTLINGER
<eucode>
include std/socket.e
namespace sockets
public constant SO_DONTLINGER
</eucode>





@[:sockets:SO_REUSEPORT|]
==== SO_REUSEPORT
<eucode>
include std/socket.e
namespace sockets
public constant SO_REUSEPORT
</eucode>





@[:sockets:SO_CONNDATA|]
==== SO_CONNDATA
<eucode>
include std/socket.e
namespace sockets
public constant SO_CONNDATA
</eucode>





@[:sockets:SO_CONNOPT|]
==== SO_CONNOPT
<eucode>
include std/socket.e
namespace sockets
public constant SO_CONNOPT
</eucode>





@[:sockets:SO_DISCDATA|]
==== SO_DISCDATA
<eucode>
include std/socket.e
namespace sockets
public constant SO_DISCDATA
</eucode>





@[:sockets:SO_DISCOPT|]
==== SO_DISCOPT
<eucode>
include std/socket.e
namespace sockets
public constant SO_DISCOPT
</eucode>





@[:sockets:SO_CONNDATALEN|]
==== SO_CONNDATALEN
<eucode>
include std/socket.e
namespace sockets
public constant SO_CONNDATALEN
</eucode>





@[:sockets:SO_CONNOPTLEN|]
==== SO_CONNOPTLEN
<eucode>
include std/socket.e
namespace sockets
public constant SO_CONNOPTLEN
</eucode>





@[:sockets:SO_DISCDATALEN|]
==== SO_DISCDATALEN
<eucode>
include std/socket.e
namespace sockets
public constant SO_DISCDATALEN
</eucode>





@[:sockets:SO_DISCOPTLEN|]
==== SO_DISCOPTLEN
<eucode>
include std/socket.e
namespace sockets
public constant SO_DISCOPTLEN
</eucode>





@[:sockets:SO_OPENTYPE|]
==== SO_OPENTYPE
<eucode>
include std/socket.e
namespace sockets
public constant SO_OPENTYPE
</eucode>





@[:sockets:SO_MAXDG|]
==== SO_MAXDG
<eucode>
include std/socket.e
namespace sockets
public constant SO_MAXDG
</eucode>





@[:sockets:SO_MAXPATHDG|]
==== SO_MAXPATHDG
<eucode>
include std/socket.e
namespace sockets
public constant SO_MAXPATHDG
</eucode>





@[:sockets:SO_SYNCHRONOUS_ALTERT|]
==== SO_SYNCHRONOUS_ALTERT
<eucode>
include std/socket.e
namespace sockets
public constant SO_SYNCHRONOUS_ALTERT
</eucode>





@[:sockets:SO_SYNCHRONOUS_NONALERT|]
==== SO_SYNCHRONOUS_NONALERT
<eucode>
include std/socket.e
namespace sockets
public constant SO_SYNCHRONOUS_NONALERT
</eucode>





====  LINUX Socket Options


@[:sockets:SO_SNDBUFFORCE|]
==== SO_SNDBUFFORCE
<eucode>
include std/socket.e
namespace sockets
public constant SO_SNDBUFFORCE
</eucode>





@[:sockets:SO_RCVBUFFORCE|]
==== SO_RCVBUFFORCE
<eucode>
include std/socket.e
namespace sockets
public constant SO_RCVBUFFORCE
</eucode>





@[:sockets:SO_NO_CHECK|]
==== SO_NO_CHECK
<eucode>
include std/socket.e
namespace sockets
public constant SO_NO_CHECK
</eucode>





@[:sockets:SO_PRIORITY|]
==== SO_PRIORITY
<eucode>
include std/socket.e
namespace sockets
public constant SO_PRIORITY
</eucode>





@[:sockets:SO_BSDCOMPAT|]
==== SO_BSDCOMPAT
<eucode>
include std/socket.e
namespace sockets
public constant SO_BSDCOMPAT
</eucode>





@[:sockets:SO_PASSCRED|]
==== SO_PASSCRED
<eucode>
include std/socket.e
namespace sockets
public constant SO_PASSCRED
</eucode>





@[:sockets:SO_PEERCRED|]
==== SO_PEERCRED
<eucode>
include std/socket.e
namespace sockets
public constant SO_PEERCRED
</eucode>





====  - Security levels - as per NRL IPv6 - do not actually do anything


@[:sockets:SO_SECURITY_AUTHENTICATION|]
==== SO_SECURITY_AUTHENTICATION
<eucode>
include std/socket.e
namespace sockets
public constant SO_SECURITY_AUTHENTICATION
</eucode>





@[:sockets:SO_SECURITY_ENCRYPTION_TRANSPORT|]
==== SO_SECURITY_ENCRYPTION_TRANSPORT
<eucode>
include std/socket.e
namespace sockets
public constant SO_SECURITY_ENCRYPTION_TRANSPORT
</eucode>





@[:sockets:SO_SECURITY_ENCRYPTION_NETWORK|]
==== SO_SECURITY_ENCRYPTION_NETWORK
<eucode>
include std/socket.e
namespace sockets
public constant SO_SECURITY_ENCRYPTION_NETWORK
</eucode>





@[:sockets:SO_BINDTODEVICE|]
==== SO_BINDTODEVICE
<eucode>
include std/socket.e
namespace sockets
public constant SO_BINDTODEVICE
</eucode>





====  LINUX Socket Filtering Options


@[:sockets:SO_ATTACH_FILTER|]
==== SO_ATTACH_FILTER
<eucode>
include std/socket.e
namespace sockets
public constant SO_ATTACH_FILTER
</eucode>





@[:sockets:SO_DETACH_FILTER|]
==== SO_DETACH_FILTER
<eucode>
include std/socket.e
namespace sockets
public constant SO_DETACH_FILTER
</eucode>





@[:sockets:SO_PEERNAME|]
==== SO_PEERNAME
<eucode>
include std/socket.e
namespace sockets
public constant SO_PEERNAME
</eucode>





@[:sockets:SO_TIMESTAMP|]
==== SO_TIMESTAMP
<eucode>
include std/socket.e
namespace sockets
public constant SO_TIMESTAMP
</eucode>





@[:sockets:SCM_TIMESTAMP|]
==== SCM_TIMESTAMP
<eucode>
include std/socket.e
namespace sockets
public constant SCM_TIMESTAMP
</eucode>





@[:sockets:SO_PEERSEC|]
==== SO_PEERSEC
<eucode>
include std/socket.e
namespace sockets
public constant SO_PEERSEC
</eucode>





@[:sockets:SO_PASSSEC|]
==== SO_PASSSEC
<eucode>
include std/socket.e
namespace sockets
public constant SO_PASSSEC
</eucode>





@[:sockets:SO_TIMESTAMPNS|]
==== SO_TIMESTAMPNS
<eucode>
include std/socket.e
namespace sockets
public constant SO_TIMESTAMPNS
</eucode>





@[:sockets:SCM_TIMESTAMPNS|]
==== SCM_TIMESTAMPNS
<eucode>
include std/socket.e
namespace sockets
public constant SCM_TIMESTAMPNS
</eucode>





@[:sockets:SO_MARK|]
==== SO_MARK
<eucode>
include std/socket.e
namespace sockets
public constant SO_MARK
</eucode>





@[:sockets:SO_TIMESTAMPING|]
==== SO_TIMESTAMPING
<eucode>
include std/socket.e
namespace sockets
public constant SO_TIMESTAMPING
</eucode>





@[:sockets:SCM_TIMESTAMPING|]
==== SCM_TIMESTAMPING
<eucode>
include std/socket.e
namespace sockets
public constant SCM_TIMESTAMPING
</eucode>





@[:sockets:SO_PROTOCOL|]
==== SO_PROTOCOL
<eucode>
include std/socket.e
namespace sockets
public constant SO_PROTOCOL
</eucode>





@[:sockets:SO_DOMAIN|]
==== SO_DOMAIN
<eucode>
include std/socket.e
namespace sockets
public constant SO_DOMAIN
</eucode>





@[:sockets:SO_RXQ_OVFL|]
==== SO_RXQ_OVFL
<eucode>
include std/socket.e
namespace sockets
public constant SO_RXQ_OVFL
</eucode>





=== Send Flags

Pass to the ##flags## parameter of [[:send]] and [[:receive]]



@[:sockets:MSG_OOB|]
==== MSG_OOB
<eucode>
include std/socket.e
namespace sockets
public constant MSG_OOB
</eucode>

Sends out-of-band data on sockets that support this notion (e.g., of
type [[:SOCK_STREAM]]); the underlying protocol must also support
out-of-band data.




@[:sockets:MSG_PEEK|]
==== MSG_PEEK
<eucode>
include std/socket.e
namespace sockets
public constant MSG_PEEK
</eucode>

This flag causes the receive operation to return data from the
beginning of the receive queue without removing that data from the
queue.  Thus, a subsequent receive call will return the same data.




@[:sockets:MSG_DONTROUTE|]
==== MSG_DONTROUTE
<eucode>
include std/socket.e
namespace sockets
public constant MSG_DONTROUTE
</eucode>

Do not use a gateway to send out the packet, only send to hosts on
directly connected networks.  This is usually used only by diagnostic
or routing programs.  This is only defined for protocol families that
route; packet sockets do not.




@[:sockets:MSG_TRYHARD|]
==== MSG_TRYHARD
<eucode>
include std/socket.e
namespace sockets
public constant MSG_TRYHARD
</eucode>





@[:sockets:MSG_CTRUNC|]
==== MSG_CTRUNC
<eucode>
include std/socket.e
namespace sockets
public constant MSG_CTRUNC
</eucode>

Indicates that some control data were discarded due to lack of space in
the buffer for ancillary data.




@[:sockets:MSG_PROXY|]
==== MSG_PROXY
<eucode>
include std/socket.e
namespace sockets
public constant MSG_PROXY
</eucode>





@[:sockets:MSG_TRUNC|]
==== MSG_TRUNC
<eucode>
include std/socket.e
namespace sockets
public constant MSG_TRUNC
</eucode>

Indicates that the trailing portion of a datagram was discarded because
the datagram was larger than the buffer supplied.




@[:sockets:MSG_DONTWAIT|]
==== MSG_DONTWAIT
<eucode>
include std/socket.e
namespace sockets
public constant MSG_DONTWAIT
</eucode>

Enables non-blocking operation; if the operation would block, EAGAIN
or EWOULDBLOCK is returned.




@[:sockets:MSG_EOR|]
==== MSG_EOR
<eucode>
include std/socket.e
namespace sockets
public constant MSG_EOR
</eucode>

Terminates a record (when this notion is supported, as for sockets of
type [[:SOCK_SEQPACKET]]).




@[:sockets:MSG_WAITALL|]
==== MSG_WAITALL
<eucode>
include std/socket.e
namespace sockets
public constant MSG_WAITALL
</eucode>

This flag requests that the operation block until the full request is
satisfied.  However, the call may still return less data than requested
if a signal is caught, an error or disconnect occurs, or the next data
to be received is of a different type than that returned.




@[:sockets:MSG_FIN|]
==== MSG_FIN
<eucode>
include std/socket.e
namespace sockets
public constant MSG_FIN
</eucode>





@[:sockets:MSG_SYN|]
==== MSG_SYN
<eucode>
include std/socket.e
namespace sockets
public constant MSG_SYN
</eucode>





@[:sockets:MSG_CONFIRM|]
==== MSG_CONFIRM
<eucode>
include std/socket.e
namespace sockets
public constant MSG_CONFIRM
</eucode>

Tell the link layer that forward progress happened: you got a
successful reply from the other side.  If the link layer doesn't get
this it will regularly reprobe the neighbor (e.g., via a unicast ARP).
Only valid on [[:SOCK_DGRAM]] and [[:SOCK_RAW]] sockets and currently only
implemented for IPv4 and IPv6.




@[:sockets:MSG_RST|]
==== MSG_RST
<eucode>
include std/socket.e
namespace sockets
public constant MSG_RST
</eucode>





@[:sockets:MSG_ERRQUEUE|]
==== MSG_ERRQUEUE
<eucode>
include std/socket.e
namespace sockets
public constant MSG_ERRQUEUE
</eucode>

Indicates that no data was received but an extended error from the
socket error queue.




@[:sockets:MSG_NOSIGNAL|]
==== MSG_NOSIGNAL
<eucode>
include std/socket.e
namespace sockets
public constant MSG_NOSIGNAL
</eucode>

Requests not to send SIGPIPE on errors on stream oriented sockets when
the other end breaks the connection. The EPIPE error is still
returned.




@[:sockets:MSG_MORE|]
==== MSG_MORE
<eucode>
include std/socket.e
namespace sockets
public constant MSG_MORE
</eucode>

The caller has more data to send. This flag is used with TCP sockets
to obtain the same effect as the TCP_CORK socket option, with the
difference that this flag can be set on a per-call basis.




=== Server and Client Sides



@[:sockets:SOCKET_SOCKET|]
==== SOCKET_SOCKET
<eucode>
include std/socket.e
namespace sockets
export enum SOCKET_SOCKET
</eucode>

Accessor index for socket handle of a socket type




@[:sockets:SOCKET_SOCKADDR_IN|]
==== SOCKET_SOCKADDR_IN
<eucode>
include std/socket.e
namespace sockets
export enum SOCKET_SOCKADDR_IN
</eucode>

Accessor index for the sockaddr_in pointer of a socket type




@[:sockets:socket|]
==== socket
<eucode>
include std/socket.e
namespace sockets
public type socket(object o)
</eucode>

  Socket type



@[:sockets:create|]
==== create
<eucode>
include std/socket.e
namespace sockets
public function create(integer family, integer sock_type, integer protocol)
</eucode>

  creates a new socket.

===== Parameters:
# ##family##: an integer
# ##sock_type##: an integer, the type of socket to create
# ##protocol##: an integer, the communication protocol being used

##family## options~:
* [[:AF_UNIX]]
* [[:AF_INET]]
* [[:AF_INET6]]
* [[:AF_APPLETALK]]
* [[:AF_BTH]]

##sock_type## options~:
* [[:SOCK_STREAM]]
* [[:SOCK_DGRAM]]
* [[:SOCK_RAW]]
* [[:SOCK_RDM]]
* [[:SOCK_SEQPACKET]]

===== Returns:
An **object**, an atom, representing an integer code on failure, else a sequence representing a valid socket id.

===== Comments:
On //Windows// you must have Windows Sockets version 2.2 or greater installed.  This means at
least Windows 2000 Professional or Windows 2000 Server.

===== Example 1:
<eucode>
socket = create(AF_INET, SOCK_STREAM, 0)
</eucode>


@[:sockets:close|]
==== close
<eucode>
include std/socket.e
namespace sockets
public function close(socket sock)
</eucode>

  closes a socket.

===== Parameters:
# ##sock##: the socket to close

===== Returns:
An **integer**, 0 on success and -1 on error.

===== Comments:
It may take several minutes for the OS to declare the socket as closed.



@[:sockets:shutdown|]
==== shutdown
<eucode>
include std/socket.e
namespace sockets
public function shutdown(socket sock, atom method = SD_BOTH)
</eucode>

  partially or fully close a socket.

===== Parameters:
# ##sock## : the socket to shutdown
# ##method## : the way used to close the socket

===== Returns:
An **integer**, 0 on success and -1 on error.

===== Comments:
Three constants are defined that can be sent to ##method##:
* [[:SD_SEND]] ~-- shutdown the send operations.
* [[:SD_RECEIVE]] ~-- shutdown the receive operations.
* [[:SD_BOTH]] ~-- shutdown both send and receive operations.

It may take several minutes for the OS to declare the socket as closed.



@[:sockets:select|]
==== select
<eucode>
include std/socket.e
namespace sockets
public function select(object sockets_read, object sockets_write, object sockets_err,
        integer timeout = 0, integer timeout_micro = 0)
</eucode>

  determines the read, write and error status of one or more sockets.

===== Parameters:
# ##sockets_read## : either one socket or a sequence of sockets to check for reading.
# ##sockets_write## : either one socket or a sequence of sockets to check for writing.
# ##sockets_err## : either one socket or a sequence of sockets to check for errors.
# ##timeout## : maximum time to wait to determine a sockets status, seconds part
# ##timeout_micro## : maximum time to wait to determine a sockets status, microsecond part

===== Returns:
A **sequence**, of the same size of all unique sockets containing
##{ socket, read_status, write_status, error_status }## for each socket passed
2 to the function.
Note that the sockets returned are not guaranteed to be in any particular order.

===== Comments:
Using select, you can check to see if a socket has data waiting and
is read to be read, if a socket can be written to and if a socket has
an error status.

##select## allows for fine-grained control over your sockets; it allows you
to specify that a given socket only be checked for reading or for only
reading and writing, etc.



@[:sockets:send|]
==== send
<eucode>
include std/socket.e
namespace sockets
public function send(socket sock, sequence data, atom flags = 0)
</eucode>

  sends TCP data to a socket connected remotely.

===== Parameters:
# ##sock## : the socket to send data to
# ##data## : a sequence of atoms, what to send
# ##flags## : flags (see [[:Send Flags]])

===== Returns:
An **integer**, the number of characters sent, or -1 for an error.



@[:sockets:receive|]
==== receive
<eucode>
include std/socket.e
namespace sockets
public function receive(socket sock, atom flags = 0)
</eucode>

  receives data from a bound socket.

===== Parameters:
# ##sock## : the socket to get data from
# ##flags## : flags (see [[:Send Flags]])

===== Returns:
A **sequence**, either a full string of data on success, or an atom indicating
the error code.

===== Comments:
This function will not return until data is actually received on the socket,
unless the flags parameter contains [[:MSG_DONTWAIT]].

[[:MSG_DONTWAIT]] only works on Linux kernels 2.4 and above. To be cross-platform
you should use [[:select]] to determine if a socket is readable, i.e. has data
waiting.



@[:sockets:get_option|]
==== get_option
<eucode>
include std/socket.e
namespace sockets
public function get_option(socket sock, integer level, integer optname)
</eucode>

  gets options for a socket.

===== Parameters:
# ##sock## : the socket
# ##level## : an integer, the option level
# ##optname## : requested option (See [[:Socket Options]])

===== Returns:
An **object**, either:
* On error, {"ERROR",error_code}.
* On success, either an atom or a sequence containing the option value, depending on the option.

===== Comments:
Primarily for use in multicast or more advanced socket
applications.  ##Level## is the option level, and ##option_name## is the
option for which values are being sought. ##Level## is usually
[[:SOL_SOCKET]].

===== Returns:
An **atom**, On error, an atom indicating the error code.\\
A **sequence** or **atom**,   On success, either an atom or
a sequence containing the option value.

===== See Also:
[[:get_option]]



@[:sockets:set_option|]
==== set_option
<eucode>
include std/socket.e
namespace sockets
public function set_option(socket sock, integer level, integer optname, object val)
</eucode>

  sets options for a socket.

===== Parameters:
# ##sock## : an atom, the socket id
# ##level## : an integer, the option level
# ##optname## : requested option (See [[:Socket Options]])
# ##val## : an object, the new value for the option

===== Returns:
An **integer**, 0 on success, -1 on error.

===== Comments:
Primarily for use in multicast or more advanced socket
applications.  ##Level## is the option level, and ##option_name## is the
option for which values are being set.  ##Level## is usually
[[:SOL_SOCKET]].

===== See Also:
[[:get_option]]


=== Client Side Only


@[:sockets:connect|]
==== connect
<eucode>
include std/socket.e
namespace sockets
public function connect(socket sock, sequence address, integer port = - 1)
</eucode>

  establishes an outgoing connection to a remote computer. Only works with TCP sockets.

===== Parameters:
# ##sock## : the socket
# ##address## : ip address to connect, optionally with :PORT at the end
# ##port## : port number

===== Returns:
An **integer**, 0 for success and non-zero on failure.  See the ##ERR_*## constants
for supported values.

===== Comments:
##address## can contain a port number. If it does not, it has to be supplied
to the ##port## parameter.

===== Example 1:
<eucode>
success = connect(sock, "11.1.1.1") -- uses default port 80
success = connect(sock, "11.1.1.1:110") -- uses port 110
success = connect(sock, "11.1.1.1", 345) -- uses port 345
</eucode>


=== Server Side Only


@[:sockets:bind|]
==== bind
<eucode>
include std/socket.e
namespace sockets
public function bind(socket sock, sequence address, integer port = - 1)
</eucode>

  joins a socket to a specific local internet address and port so
later calls only need to provide the socket.

===== Parameters:
# ##sock## : the socket
# ##address## : the address to bind the socket to
# ##port## : optional, if not specified you must include :PORT in
the address parameter.

===== Returns:
An **integer**, 0 on success and -1 on failure.

===== Example 1:
<eucode>
-- Bind to all interfaces on the default port 80.
success = bind(socket, "0.0.0.0")
-- Bind to all interfaces on port 8080.
success = bind(socket, "0.0.0.0:8080")
-- Bind only to the 243.17.33.19 interface on port 345.
success = bind(socket, "243.17.33.19", 345)
</eucode>


@[:sockets:listen|]
==== listen
<eucode>
include std/socket.e
namespace sockets
public function listen(socket sock, integer backlog)
</eucode>

  starts monitoring a connection. Only works with TCP sockets.

===== Parameters:
# ##sock## : the socket
# ##backlog## : the number of connection requests that
can be kept waiting before the OS refuses to hear any more.

===== Returns:
An **integer**, 0 on success and an error code on failure.

===== Comments:
Once the socket is created and bound, this will indicate to the
operating system that you are ready to being listening for connections.

The value of ##backlog## is strongly dependent on both the hardware
and the amount of time it takes the program to process each
connection request.

This function must be executed after [[:bind]].



@[:sockets:accept|]
==== accept
<eucode>
include std/socket.e
namespace sockets
public function accept(socket sock)
</eucode>

  produces a new socket for an incoming connection.

===== Parameters:
# ##sock##: the server socket

===== Returns:
An **atom**, on error\\
A **sequence**,
##{socket client, sequence client_ip_address}##
on success.

===== Comments:
Using this function allows communication to occur on a
"side channel" while the main server socket remains available
for new connections.

##accept## must be called after ##bind## and ##listen##.



=== UDP Only



@[:sockets:send_to|]
==== send_to
<eucode>
include std/socket.e
namespace sockets
public function send_to(socket sock, sequence data, sequence address, integer port = - 1,
        atom flags = 0)
</eucode>

  sends a UDP packet to a given socket.

===== Parameters:
# ##sock##: the server socket
# ##data##: the data to be sent
# ##ip##: the ip where the data is to be sent to (ip:port)
is acceptable
# ##port##: the port where the data is to be sent on (if not supplied with the ip)
# ##flags## : flags (see [[:Send Flags]])

===== Returns:
An ##integer## status code.

===== See Also:
[[:receive_from]]



@[:sockets:receive_from|]
==== receive_from
<eucode>
include std/socket.e
namespace sockets
public function receive_from(socket sock, atom flags = 0)
</eucode>

  receives a UDP packet from a given socket.

===== Parameters:
# ##sock##: the server socket
# ##flags## : flags (see [[:Send Flags]])

===== Returns:
A ##sequence## containing { client_ip, client_port, data } or an ##atom## error code.

===== See Also:
[[:send_to]]



=== Information


@[:sockets:service_by_name|]
==== service_by_name
<eucode>
include std/socket.e
namespace sockets
public function service_by_name(sequence name, object protocol = 0)
</eucode>

  gets service information by name.

===== Parameters:
# ##name## : service name.
# ##protocol## : protocol. Default is not to search by protocol.

===== Returns:
A **sequence**, containing ##{ official protocol name, protocol, port number }## or
an atom indicating the error code.

===== Example 1:
<eucode>
object result = getservbyname("http")
-- result = { "http", "tcp", 80 }
</eucode>

===== See Also:
[[:service_by_port]]


@[:sockets:service_by_port|]
==== service_by_port
<eucode>
include std/socket.e
namespace sockets
public function service_by_port(integer port, object protocol = 0)
</eucode>

  gets service information by port number.

===== Parameters:
# ##port## : port number.
# ##protocol## : protocol. Default is not to search by protocol.

===== Returns:
A **sequence**, containing ##{ official protocol name, protocol, port number }## or
an atom indicating the error code.

===== Example 1:
<eucode>
object result = getservbyport(80)
-- result = { "http", "tcp", 80 }
</eucode>

===== See Also:
[[:service_by_name]]


@[:sockets:info|]
==== info
<eucode>
include std/socket.e
namespace sockets
public function info(integer Type)
</eucode>

  gets constant definitions from the backend.

===== Parameters:
# ##type## : The type of information requested.

===== Returns:
A **sequence**, containing the list of definitions from the backend.
The resulting list can be indexed into using the Euphoria constants.
Or an atom indicating an error.

===== Example 1:
<eucode>
object result = info(ESOCK_TYPE_AF)
-- result = { AF_UNIX, AF_INET, AF_INET6, AF_APPLETALK, AF_BTH, AF_UNSPEC }
</eucode>

===== See Also:
[[:Socket Options]], [[:Socket Backend Constants]],
[[:Socket Type Euphoria Constants]]



!!CONTEXT:../include/std/net/common.e
!!namespace:common
%%output = std_net_common

== Common Internet Routines

<<LEVELTOC level=2 depth=4>>



=== IP Address Handling


@[:common:is_inetaddr|]
==== is_inetaddr
<eucode>
include std/net/common.e
namespace common
public function is_inetaddr(sequence address)
</eucode>

  Checks if x is an IP address in the form (#.#.#.#[:#])

===== Parameters:
# ##address## : the address to check

===== Returns:
An **integer**, 1 if x is an inetaddr, 0 if it is not

===== Comments:
Some ip validation algorithms do not allow 0.0.0.0. We do here because
many times you will want to bind to 0.0.0.0. However, you cannot connect
to 0.0.0.0 of course.

With sockets, normally binding to 0.0.0.0 means bind to all interfaces
that the computer has.



@[:common:parse_ip_address|]
==== parse_ip_address
<eucode>
include std/net/common.e
namespace common
public function parse_ip_address(sequence address, integer port = - 1)
</eucode>

  Converts a text "address:port" into {"address", port} format.

===== Parameters:
# ##address## : ip address to connect, optionally with :PORT at the end
# ##port## : optional, if not specified you may include :PORT in
the address parameter otherwise the default port 80 is used.

===== Comments:
If ##port## is supplied, it overrides any ":PORT" value in the input
address.

===== Returns:
A **sequence**, of two elements: "address" and integer port number.

===== Example 1:
<eucode>
addr = parse_ip_address("11.1.1.1") --> {"11.1.1.1", 80} -- default port
addr = parse_ip_address("11.1.1.1:110") --> {"11.1.1.1", 110}
addr = parse_ip_address("11.1.1.1", 345) --> {"11.1.1.1", 345}
</eucode>


=== URL Parsing



@[:common:URL_ENTIRE|]
==== URL_ENTIRE
<eucode>
include std/net/common.e
namespace common
public constant URL_ENTIRE
</eucode>





@[:common:URL_PROTOCOL|]
==== URL_PROTOCOL
<eucode>
include std/net/common.e
namespace common
public constant URL_PROTOCOL
</eucode>





@[:common:URL_HTTP_DOMAIN|]
==== URL_HTTP_DOMAIN
<eucode>
include std/net/common.e
namespace common
public constant URL_HTTP_DOMAIN
</eucode>





@[:common:URL_HTTP_PATH|]
==== URL_HTTP_PATH
<eucode>
include std/net/common.e
namespace common
public constant URL_HTTP_PATH
</eucode>





@[:common:URL_HTTP_QUERY|]
==== URL_HTTP_QUERY
<eucode>
include std/net/common.e
namespace common
public constant URL_HTTP_QUERY
</eucode>





@[:common:URL_MAIL_ADDRESS|]
==== URL_MAIL_ADDRESS
<eucode>
include std/net/common.e
namespace common
public constant URL_MAIL_ADDRESS
</eucode>





@[:common:URL_MAIL_USER|]
==== URL_MAIL_USER
<eucode>
include std/net/common.e
namespace common
public constant URL_MAIL_USER
</eucode>





@[:common:URL_MAIL_DOMAIN|]
==== URL_MAIL_DOMAIN
<eucode>
include std/net/common.e
namespace common
public constant URL_MAIL_DOMAIN
</eucode>





@[:common:URL_MAIL_QUERY|]
==== URL_MAIL_QUERY
<eucode>
include std/net/common.e
namespace common
public constant URL_MAIL_QUERY
</eucode>





@[:common:parse_url|]
==== parse_url
<eucode>
include std/net/common.e
namespace common
public function parse_url(sequence url)
</eucode>

  Parse a common URL. Currently supported URLs are http(s), ftp(s), gopher(s) and mailto.

===== Parameters:
# ##url## : url to be parsed

===== Returns:
A **sequence**, containing the URL details. You should use the ##URL_## constants
to access the values of the returned sequence. You should first check the
protocol ([[:URL_PROTOCOL]]) that was returned as the data contained in the
return value can be of different lengths.

On a parse error, -1 will be returned.

===== Example 1:
<eucode>
object url_data = parse_url("http://john.com/index.html?name=jeff")
-- url_data = {
--     "http://john.com/index.html?name=jeff", -- URL_ENTIRE
--     "http",          -- URL_PROTOCOL
--     "john.com",      -- URL_DOMAIN
--     "/index.html",   -- URL_PATH
--     "?name=jeff"     -- URL_QUERY
-- }

url_data = parse_url("mailto:john@mail.doe.com?subject=Hello%20John%20Doe")
-- url_data = {
--   "mailto:john@mail.doe.com?subject=Hello%20John%20Doe",
--   "mailto",
--   "john@mail.doe.com",
--   "john",
--   "mail.doe.com",
--   "?subject=Hello%20John%20Doe"
-- }
</eucode>




!!CONTEXT:../include/std/net/dns.e
!!namespace:dns
%%output = std_net_dns

== DNS

<<LEVELTOC level=2 depth=4>>



===  Constants


@[:dns:ADDR_FLAGS|]
==== ADDR_FLAGS
<eucode>
include std/net/dns.e
namespace dns
public enum ADDR_FLAGS
</eucode>





@[:dns:ADDR_FAMILY|]
==== ADDR_FAMILY
<eucode>
include std/net/dns.e
namespace dns
public enum ADDR_FAMILY
</eucode>





@[:dns:ADDR_TYPE|]
==== ADDR_TYPE
<eucode>
include std/net/dns.e
namespace dns
public enum ADDR_TYPE
</eucode>





@[:dns:ADDR_PROTOCOL|]
==== ADDR_PROTOCOL
<eucode>
include std/net/dns.e
namespace dns
public enum ADDR_PROTOCOL
</eucode>





@[:dns:ADDR_ADDRESS|]
==== ADDR_ADDRESS
<eucode>
include std/net/dns.e
namespace dns
public enum ADDR_ADDRESS
</eucode>





@[:dns:HOST_OFFICIAL_NAME|]
==== HOST_OFFICIAL_NAME
<eucode>
include std/net/dns.e
namespace dns
public enum HOST_OFFICIAL_NAME
</eucode>





@[:dns:HOST_ALIASES|]
==== HOST_ALIASES
<eucode>
include std/net/dns.e
namespace dns
public enum HOST_ALIASES
</eucode>





@[:dns:HOST_IPS|]
==== HOST_IPS
<eucode>
include std/net/dns.e
namespace dns
public enum HOST_IPS
</eucode>





@[:dns:HOST_TYPE|]
==== HOST_TYPE
<eucode>
include std/net/dns.e
namespace dns
public enum HOST_TYPE
</eucode>





@[:dns:DNS_QUERY_STANDARD|]
==== DNS_QUERY_STANDARD
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_STANDARD
</eucode>





@[:dns:DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE|]
==== DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE
</eucode>





@[:dns:DNS_QUERY_USE_TCP_ONLY|]
==== DNS_QUERY_USE_TCP_ONLY
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_USE_TCP_ONLY
</eucode>





@[:dns:DNS_QUERY_NO_RECURSION|]
==== DNS_QUERY_NO_RECURSION
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_NO_RECURSION
</eucode>





@[:dns:DNS_QUERY_BYPASS_CACHE|]
==== DNS_QUERY_BYPASS_CACHE
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_BYPASS_CACHE
</eucode>





@[:dns:DNS_QUERY_NO_WIRE_QUERY|]
==== DNS_QUERY_NO_WIRE_QUERY
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_NO_WIRE_QUERY
</eucode>





@[:dns:DNS_QUERY_NO_LOCAL_NAME|]
==== DNS_QUERY_NO_LOCAL_NAME
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_NO_LOCAL_NAME
</eucode>





@[:dns:DNS_QUERY_NO_HOSTS_FILE|]
==== DNS_QUERY_NO_HOSTS_FILE
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_NO_HOSTS_FILE
</eucode>





@[:dns:DNS_QUERY_NO_NETBT|]
==== DNS_QUERY_NO_NETBT
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_NO_NETBT
</eucode>





@[:dns:DNS_QUERY_WIRE_ONLY|]
==== DNS_QUERY_WIRE_ONLY
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_WIRE_ONLY
</eucode>





@[:dns:DNS_QUERY_RETURN_MESSAGE|]
==== DNS_QUERY_RETURN_MESSAGE
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_RETURN_MESSAGE
</eucode>





@[:dns:DNS_QUERY_TREAT_AS_FQDN|]
==== DNS_QUERY_TREAT_AS_FQDN
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_TREAT_AS_FQDN
</eucode>





@[:dns:DNS_QUERY_DONT_RESET_TTL_VALUES|]
==== DNS_QUERY_DONT_RESET_TTL_VALUES
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_DONT_RESET_TTL_VALUES
</eucode>





@[:dns:DNS_QUERY_RESERVED|]
==== DNS_QUERY_RESERVED
<eucode>
include std/net/dns.e
namespace dns
public constant DNS_QUERY_RESERVED
</eucode>





@[:dns:NS_C_IN|]
==== NS_C_IN
<eucode>
include std/net/dns.e
namespace dns
public constant NS_C_IN
</eucode>





@[:dns:NS_C_ANY|]
==== NS_C_ANY
<eucode>
include std/net/dns.e
namespace dns
public constant NS_C_ANY
</eucode>





@[:dns:NS_KT_RSA|]
==== NS_KT_RSA
<eucode>
include std/net/dns.e
namespace dns
public constant NS_KT_RSA
</eucode>





@[:dns:NS_KT_DH|]
==== NS_KT_DH
<eucode>
include std/net/dns.e
namespace dns
public constant NS_KT_DH
</eucode>





@[:dns:NS_KT_DSA|]
==== NS_KT_DSA
<eucode>
include std/net/dns.e
namespace dns
public constant NS_KT_DSA
</eucode>





@[:dns:NS_KT_PRIVATE|]
==== NS_KT_PRIVATE
<eucode>
include std/net/dns.e
namespace dns
public constant NS_KT_PRIVATE
</eucode>





@[:dns:NS_T_A|]
==== NS_T_A
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_A
</eucode>





@[:dns:NS_T_NS|]
==== NS_T_NS
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_NS
</eucode>





@[:dns:NS_T_PTR|]
==== NS_T_PTR
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_PTR
</eucode>





@[:dns:NS_T_MX|]
==== NS_T_MX
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_MX
</eucode>





@[:dns:NS_T_AAAA|]
==== NS_T_AAAA
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_AAAA
</eucode>





@[:dns:NS_T_A6|]
==== NS_T_A6
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_A6
</eucode>





@[:dns:NS_T_ANY|]
==== NS_T_ANY
<eucode>
include std/net/dns.e
namespace dns
public constant NS_T_ANY
</eucode>





=== General Routines


@[:dns:host_by_name|]
==== host_by_name
<eucode>
include std/net/dns.e
namespace dns
public function host_by_name(sequence name)
</eucode>

  Get the host information by name.

===== Parameters:
# ##name## : host name

===== Returns:
A ##sequence##, containing
<eucode>
{
  official name,
  { alias1, alias2, ... },
  { ip1, ip2, ... },
  address_type
}
</eucode>

===== Example 1:
<eucode>
object data = host_by_name("www.google.com")
-- data = {
--   "www.l.google.com",
--   {
--     "www.google.com"
--   },
--   {
--     "74.125.93.104",
--     "74.125.93.147",
--     ...
--   },
--   2
-- }
</eucode>



@[:dns:host_by_addr|]
==== host_by_addr
<eucode>
include std/net/dns.e
namespace dns
public function host_by_addr(sequence address)
</eucode>

  Get the host information by address.

===== Parameters:
# ##address## : host address

===== Returns:
A ##sequence##, containing
<eucode>
{
  official name,
  { alias1, alias2, ... },
  { ip1, ip2, ... },
  address_type
}
</eucode>

===== Example 1:
<eucode>
object data = host_by_addr("74.125.93.147")
-- data = {
--   "www.l.google.com",
--   {
--     "www.google.com"
--   },
--   {
--     "74.125.93.104",
--     "74.125.93.147",
--     ...
--   },
--   2
-- }
</eucode>




!!CONTEXT:../include/std/net/http.e
!!namespace:http
%%output = std_net_http

== HTTP Client

<<LEVELTOC level=2 depth=4>>



=== Error Codes



@[:http:ERR_MALFORMED_URL|]
==== ERR_MALFORMED_URL
<eucode>
include std/net/http.e
namespace http
public enum ERR_MALFORMED_URL
</eucode>





@[:http:ERR_INVALID_PROTOCOL|]
==== ERR_INVALID_PROTOCOL
<eucode>
include std/net/http.e
namespace http
public enum ERR_INVALID_PROTOCOL
</eucode>





@[:http:ERR_INVALID_DATA|]
==== ERR_INVALID_DATA
<eucode>
include std/net/http.e
namespace http
public enum ERR_INVALID_DATA
</eucode>





@[:http:ERR_INVALID_DATA_ENCODING|]
==== ERR_INVALID_DATA_ENCODING
<eucode>
include std/net/http.e
namespace http
public enum ERR_INVALID_DATA_ENCODING
</eucode>





@[:http:ERR_HOST_LOOKUP_FAILED|]
==== ERR_HOST_LOOKUP_FAILED
<eucode>
include std/net/http.e
namespace http
public enum ERR_HOST_LOOKUP_FAILED
</eucode>





@[:http:ERR_CONNECT_FAILED|]
==== ERR_CONNECT_FAILED
<eucode>
include std/net/http.e
namespace http
public enum ERR_CONNECT_FAILED
</eucode>





@[:http:ERR_SEND_FAILED|]
==== ERR_SEND_FAILED
<eucode>
include std/net/http.e
namespace http
public enum ERR_SEND_FAILED
</eucode>





@[:http:ERR_RECEIVE_FAILED|]
==== ERR_RECEIVE_FAILED
<eucode>
include std/net/http.e
namespace http
public enum ERR_RECEIVE_FAILED
</eucode>





=== Constants


@[:http:FORM_URLENCODED|]
==== FORM_URLENCODED
<eucode>
include std/net/http.e
namespace http
public enum FORM_URLENCODED
</eucode>





@[:http:MULTIPART_FORM_DATA|]
==== MULTIPART_FORM_DATA
<eucode>
include std/net/http.e
namespace http
public enum MULTIPART_FORM_DATA
</eucode>





@[:http:ENCODE_NONE|]
==== ENCODE_NONE
<eucode>
include std/net/http.e
namespace http
public enum ENCODE_NONE
</eucode>

No encoding is necessary




@[:http:ENCODE_BASE64|]
==== ENCODE_BASE64
<eucode>
include std/net/http.e
namespace http
public enum ENCODE_BASE64
</eucode>

Use Base64 encoding




=== Configuration Routines


@[:http:set_proxy_server|]
==== set_proxy_server
<eucode>
include std/net/http.e
namespace http
public procedure set_proxy_server(sequence ip, integer port)
</eucode>

  Configure http client to use a proxy server

===== Parameters:
* ##proxy_ip## - IP address of the proxy server
* ##proxy_port## - Port of the proxy server



=== Get/Post Routines


@[:http:http_post|]
==== http_post
<eucode>
include std/net/http.e
namespace http
public function http_post(sequence url, object data, object headers = 0,
        natural follow_redirects = 10, natural timeout = 15)
</eucode>

  Post data to a HTTP resource.

===== Parameters:
* ##url##     - URL to send post request to
* ##data##    - Form data (described later)
* ##headers## - Additional headers added to request
* ##follow_redirects## - Maximum redirects to follow
* ##timeout## - Maximum number of seconds to wait for a response

===== Returns:
An integer error code or a 2 element sequence. Element 1 is a sequence
of key/value pairs representing the result header information. element
2 is the body of the result.

If result is a negative integer, that represents a local error condition.

If result is a positive integer, that represents a HTTP error value from
the server.

===== Data Sequence:
This sequence should contain key value pairs representing the expected form
elements of the called URL. For a simple url-encoded form:

<eucode>
{ {"name", "John Doe"}, {"age", "22"}, {"city", "Small Town"}}
</eucode>

All Keys and Values should be a sequence.

If the post requires multipart form encoding then the sequence is a little
different. The first element of the data sequence must be [[:MULTIPART_FORM_DATA]].
All subsequent field values should be key/value pairs as described above **except**
for a field representing a file upload. In that case the sequence should be:

##{ FIELD-NAME, FILE-VALUE, FILE-NAME, MIME-TYPE, ENCODING-TYPE }##

Encoding type can be
* [[:ENCODE_NONE]]
* [[:ENCODE_BASE64]]

An example for a multipart form encoded post request data sequence

<eucode>
{ 
  { "name", "John Doe" }, 
  { "avatar", file_content, "me.png", "image/png", ENCODE_BASE64 },
  { "city", "Small Town" }
}
</eucode>

===== See Also:
[[:http_get]]



@[:http:http_get|]
==== http_get
<eucode>
include std/net/http.e
namespace http
public function http_get(sequence url, object headers = 0, natural follow_redirects = 10,
        natural timeout = 15)
</eucode>

  Get a HTTP resource.

===== Returns:
An integer error code or a 2 element sequence. Element 1 is a sequence
of key/value pairs representing the result header information. Element
2 is the body of the result.

If result is a negative integer, that represents a local error condition.

If result is a positive integer, that represents a HTTP error value from
the server.

===== Example:

<eucode>
include std/console.e -- for display()
include std/net/http.e

object result = http_get("http://example.com") 
if atom(result) then 
   printf(1, "Web error: %d\n", result) 
    abort(1) 
end if 

display(result[1]) -- header key/value pairs
printf(1, "Content: %s\n", { result[2] }) 
</eucode>

===== See Also:
[[:http_post]]




!!CONTEXT:../include/std/net/url.e
!!namespace:url
%%output = std_net_url

== URL handling

<<LEVELTOC level=2 depth=4>>



=== Parsing



@[:url:parse_querystring|]
==== parse_querystring
<eucode>
include std/net/url.e
namespace url
public function parse_querystring(object query_string)
</eucode>

  Parse a query string into a map

===== Parameters:
# ##query_string##: Query string to parse

===== Returns:
[[:map]] containing the key/value pairs

===== Example 1:
<eucode>
map qs = parse_querystring("name=John&age=18")
printf(1, "%s is %s years old\n", { map:get(qs, "name"), map:get(qs, "age) })
</eucode>



=== URL Parse Accessor Constants

Use with the result of [[:parse]].

===== Notes:
If the host name, port, path, username, password or query string are not part of the
URL they will be returned as an integer value of zero.



@[:url:URL_PROTOCOL|]
==== URL_PROTOCOL
<eucode>
include std/net/url.e
namespace url
public enum URL_PROTOCOL
</eucode>

The protocol of the URL




@[:url:URL_HOSTNAME|]
==== URL_HOSTNAME
<eucode>
include std/net/url.e
namespace url
public enum URL_HOSTNAME
</eucode>

The hostname of the URL




@[:url:URL_PORT|]
==== URL_PORT
<eucode>
include std/net/url.e
namespace url
public enum URL_PORT
</eucode>

The TCP port that the URL will connect to




@[:url:URL_PATH|]
==== URL_PATH
<eucode>
include std/net/url.e
namespace url
public enum URL_PATH
</eucode>

The protocol-specific pathname of the URL




@[:url:URL_USER|]
==== URL_USER
<eucode>
include std/net/url.e
namespace url
public enum URL_USER
</eucode>

The username of the URL




@[:url:URL_PASSWORD|]
==== URL_PASSWORD
<eucode>
include std/net/url.e
namespace url
public enum URL_PASSWORD
</eucode>

The password the URL




@[:url:URL_QUERY_STRING|]
==== URL_QUERY_STRING
<eucode>
include std/net/url.e
namespace url
public enum URL_QUERY_STRING
</eucode>

The HTTP query string




@[:url:parse|]
==== parse
<eucode>
include std/net/url.e
namespace url
public function parse(sequence url, integer querystring_also = 0)
</eucode>

  Parse a URL returning its various elements.

===== Parameters:
# ##url##: URL to parse
# ##querystring_also##: Parse the query string into a map also?

===== Returns:
A multi-element sequence containing:
# protocol
# host name
# port
# path
# user name
# password
# query string

Or, zero if the URL could not be parsed.

===== Notes:
If the host name, port, path, username, password or query string are not part of the
URL they will be returned as an integer value of zero.

===== Example 1:
<eucode>
sequence parsed = 
      parse("http://user:pass@www.debian.org:80/index.html?name=John&age=39")
-- parsed is
-- { 
--     "http",
--     "www.debian.org",
--     80,
--     "/index.html",
--     "user",
--     "pass",
--     "name=John&age=39"
-- }
</eucode>



=== URL encoding and decoding



@[:url:encode|]
==== encode
<eucode>
include std/net/url.e
namespace url
public function encode(sequence what, sequence spacecode = "+")
</eucode>

  Converts all non-alphanumeric characters in a string to their
percent-sign hexadecimal representation, or plus sign for
spaces.

===== Parameters:
# ##what## : the string to encode
# ##spacecode## : what to insert in place of a space

===== Returns:
A **sequence**, the encoded string.

===== Comments:
##spacecode## defaults to ##+## as it is more correct, however, some sites
want ##%20## as the space encoding.

===== Example 1:
<eucode>
puts(1, encode("Fred & Ethel"))
-- Prints "Fred+%26+Ethel"
</eucode>

===== See Also:
[[:decode]]



@[:url:decode|]
==== decode
<eucode>
include std/net/url.e
namespace url
public function decode(sequence what)
</eucode>

  Convert all encoded entities to their decoded counter parts

===== Parameters:
# ##what##: what value to decode

===== Returns:
A decoded sequence

===== Example 1:
<eucode>
puts(1, decode("Fred+%26+Ethel"))
-- Prints "Fred & Ethel"
</eucode>

===== See Also:
[[:encode]]




!!CONTEXT:../include/std/dll.e
!!namespace:dll
%%output = std_dll

== Dynamic Linking to External Code

<<LEVELTOC level=2 depth=4>>



=== C Type Constants
These C type constants are used when defining external C functions in a shared
library file.

===== Example 1:
See [[:define_c_proc]]

===== See Also:
[[:define_c_proc]], [[:define_c_func]], [[:define_c_var]]


@[:dll:C_CHAR|]
==== C_CHAR
<eucode>
include std/dll.e
namespace dll
public constant C_CHAR
</eucode>

 char  8-bits



@[:dll:C_BYTE|]
==== C_BYTE
<eucode>
include std/dll.e
namespace dll
public constant C_BYTE
</eucode>

 byte  8-bits



@[:dll:C_UCHAR|]
==== C_UCHAR
<eucode>
include std/dll.e
namespace dll
public constant C_UCHAR
</eucode>

 unsigned char 8-bits



@[:dll:C_UBYTE|]
==== C_UBYTE
<eucode>
include std/dll.e
namespace dll
public constant C_UBYTE
</eucode>

 ubyte 8-bits



@[:dll:C_SHORT|]
==== C_SHORT
<eucode>
include std/dll.e
namespace dll
public constant C_SHORT
</eucode>

 short 16-bits



@[:dll:C_WORD|]
==== C_WORD
<eucode>
include std/dll.e
namespace dll
public constant C_WORD
</eucode>

 word 16-bits



@[:dll:C_USHORT|]
==== C_USHORT
<eucode>
include std/dll.e
namespace dll
public constant C_USHORT
</eucode>

 unsigned short 16-bits



@[:dll:C_INT|]
==== C_INT
<eucode>
include std/dll.e
namespace dll
public constant C_INT
</eucode>

 int 32-bits



@[:dll:C_BOOL|]
==== C_BOOL
<eucode>
include std/dll.e
namespace dll
public constant C_BOOL
</eucode>

 bool 32-bits



@[:dll:C_UINT|]
==== C_UINT
<eucode>
include std/dll.e
namespace dll
public constant C_UINT
</eucode>

 unsigned int 32-bits



@[:dll:C_LONG|]
==== C_LONG
<eucode>
include std/dll.e
namespace dll
public constant C_LONG
</eucode>

 long 32-bits except on 64-bit //Unix//, where it is 64-bits



@[:dll:C_ULONG|]
==== C_ULONG
<eucode>
include std/dll.e
namespace dll
public constant C_ULONG
</eucode>

 unsigned long 32-bits except on 64-bit //Unix//, where it is 64-bits



@[:dll:C_SIZE_T|]
==== C_SIZE_T
<eucode>
include std/dll.e
namespace dll
public constant C_SIZE_T
</eucode>

 size_t unsigned long 32-bits except on 64-bit //Unix//, where it is 64-bits



@[:dll:C_POINTER|]
==== C_POINTER
<eucode>
include std/dll.e
namespace dll
public constant C_POINTER
</eucode>

 any valid pointer



@[:dll:C_LONGLONG|]
==== C_LONGLONG
<eucode>
include std/dll.e
namespace dll
public constant C_LONGLONG
</eucode>

 longlong 64-bits



@[:dll:C_LONG_PTR|]
==== C_LONG_PTR
<eucode>
include std/dll.e
namespace dll
public constant C_LONG_PTR
</eucode>

 signed integer sizeof pointer





@[:dll:C_HANDLE|]
==== C_HANDLE
<eucode>
include std/dll.e
namespace dll
public constant C_HANDLE
</eucode>

 handle sizeof pointer



@[:dll:C_HWND|]
==== C_HWND
<eucode>
include std/dll.e
namespace dll
public constant C_HWND
</eucode>

 hwnd sizeof pointer



@[:dll:C_DWORD|]
==== C_DWORD
<eucode>
include std/dll.e
namespace dll
public constant C_DWORD
</eucode>

 dword 32-bits



@[:dll:C_WPARAM|]
==== C_WPARAM
<eucode>
include std/dll.e
namespace dll
public constant C_WPARAM
</eucode>

 wparam sizeof pointer



@[:dll:C_LPARAM|]
==== C_LPARAM
<eucode>
include std/dll.e
namespace dll
public constant C_LPARAM
</eucode>

 lparam sizeof pointer



@[:dll:C_HRESULT|]
==== C_HRESULT
<eucode>
include std/dll.e
namespace dll
public constant C_HRESULT
</eucode>

 hresult 32-bits



@[:dll:C_FLOAT|]
==== C_FLOAT
<eucode>
include std/dll.e
namespace dll
public constant C_FLOAT
</eucode>

 float 32-bits



@[:dll:C_DOUBLE|]
==== C_DOUBLE
<eucode>
include std/dll.e
namespace dll
public constant C_DOUBLE
</eucode>

 double 64-bits



@[:dll:C_DWORDLONG|]
==== C_DWORDLONG
<eucode>
include std/dll.e
namespace dll
public constant C_DWORDLONG
</eucode>

 dwordlong 64-bits



=== External Euphoria Type Constants
These are used for arguments to and the return value from a Euphoria shared
library file (##.dll##, ##.so##, or ##.dylib##).


@[:dll:E_INTEGER|]
==== E_INTEGER
<eucode>
include std/dll.e
namespace dll
public constant E_INTEGER
</eucode>

 integer



@[:dll:E_ATOM|]
==== E_ATOM
<eucode>
include std/dll.e
namespace dll
public constant E_ATOM
</eucode>

 atom



@[:dll:E_SEQUENCE|]
==== E_SEQUENCE
<eucode>
include std/dll.e
namespace dll
public constant E_SEQUENCE
</eucode>

 sequence



@[:dll:E_OBJECT|]
==== E_OBJECT
<eucode>
include std/dll.e
namespace dll
public constant E_OBJECT
</eucode>

 object



@[:eu:sizeof|]
==== sizeof
<eucode>
<built-in> function sizeof( atom data_type )
</eucode>

===== Parameters:
# ##data_type## A C data type constant

Returns the size, in bytes of the specified data type.


=== Constants


@[:dll:NULL|]
==== NULL
<eucode>
include std/dll.e
namespace dll
public constant NULL
</eucode>

  C's NULL pointer


=== Routines



@[:dll:open_dll|]
==== open_dll
<eucode>
include std/dll.e
namespace dll
public function open_dll(sequence file_name)
</eucode>

  opens a //Windows// dynamic link library (##.dll##) file, or a //Unix// shared library
(##.so##) file.

===== Parameters:
# ##file_name## : a sequence, the name of the shared library to open or a sequence of filename's
to try to open.

===== Returns:
An **atom**, actually a 32-bit address. 0 is returned if the ##.dll## can not be found.

===== Errors:
The length of ##file_name## (or any filename contained therein) should not exceed
1_024 characters.

===== Comments:
##file_name## can be a relative or an absolute file name. Most operating systems will use
the normal search path for locating non-relative files.

##file_name## can be a list of file names to try. On different Linux platforms especially,
the filename will not always be the same. For instance, you may wish to try opening
##libmylib.so, libmylib.so.1, libmylib.so.1.0, libmylib.so.1.0.0.## If given a sequence of
file names to try, the first successful library loaded will be returned. If no library
could be loaded then zero will be returned after exhausting the entire list of file names.

The value returned by ##open_dll## can be passed to ##define_c_proc##, ##define_c_func##,
or ##define_c_var##.

You can open the same ##.dll## or ##.so## file multiple times. No extra memory is used and you will
get the same number returned each time.

Euphoria will close the ##.dll## or ##.so## for you automatically at the end of execution.

===== Example 1:
<eucode>
atom user32
user32 = open_dll("user32.dll")
if user32 = 0 then
   puts(1, "Couldn't open user32.dll!\n")
end if
</eucode>

===== Example 2:
<eucode>
atom mysql_lib
mysql_lib = open_dll({"libmysqlclient.so", "libmysqlclient.so.15", 
                     "libmysqlclient.so.15.0"})
if mysql_lib = 0 then
  puts(1, "Couldn't find the mysql client library\n")
end if
</eucode>

===== See Also:
[[:define_c_func]], [[:define_c_proc]], [[:define_c_var]], [[:c_func]], [[:c_proc]]


@[:dll:define_c_var|]
==== define_c_var
<eucode>
include std/dll.e
namespace dll
public function define_c_var(atom lib, sequence variable_name)
</eucode>

  gets the address of a symbol in a shared library or in RAM.

===== Parameters:
# ##lib## : an atom, the address of a //Unix// ##.so## or //Windows// ##.dll##, as returned by ##open_dll##.
# ##variable_name## : a sequence, the name of a public C variable defined within the library.

===== Returns:
An **atom**, the memory address of ##variable_name##.

===== Comments:
Once you have the address of a C variable, and you know its type, you can use ##peek##
and ##poke## to read or write the value of the variable. You can in the same way obtain
the address of a C function and pass it to any external routine that requires a callback address.

===== Example 1:
see ##.../euphoria/demo/linux/mylib.ex##

===== See Also:
[[:c_proc]], [[:define_c_func]], [[:c_func]], [[:open_dll]]


@[:dll:define_c_proc|]
==== define_c_proc
<eucode>
include std/dll.e
namespace dll
public function define_c_proc(object lib, object routine_name, sequence arg_types)
</eucode>

  defines the characteristics of either a C function, or a machine-code routine that you
wish to call as a procedure from your Euphoria program.

===== Parameters:
# ##lib## : an object, either an entry point returned as an atom by [[:open_dll]], or ##""## to denote a routine the RAM address is known.
# ##routine_name## : an object, either the name of a procedure in a shared object or the machine address of the procedure.
# ##argtypes## : a sequence of type constants.

===== Returns:
A small **integer**, known as a routine id, will be returned.

===== Errors:
The length of ##name## should not exceed 1_024 characters.

===== Comments:
Use the returned routine id as the first argument to [[:c_proc]] when
you wish to call the routine from Euphoria.

A returned value of ##-1## indicates that the procedure could not be found or linked to.

On //Windows// you can add
a ##'+'## character as a prefix to the procedure name. This tells Euphoria that the function
uses the cdecl calling convention. By default, Euphoria assumes that C routines accept
the stdcall convention.

When defining a machine code routine, ##lib## must be the empty sequence, ##""## or ##{}##, and ##routine_name##
indicates the address of the machine code routine. You can poke the bytes of machine code
into a block of memory reserved using ##allocate##. On //Windows// the machine code routine is
normally expected to follow the stdcall calling convention, but if you wish to use the
cdecl convention instead you can code ##{'+', address}## instead of address.

##argtypes## is made of type constants, which describe the C types of arguments to the procedure. They may be used to define machine code parameters as well.

The C function that you define could be one created by the Euphoria To C Translator, in
which case you can pass Euphoria data to it, and receive Euphoria data back. A list of
Euphoria types is shown above.

You can pass any C integer type or pointer type. You can also pass a Euphoria atom as
a C double or float.

Parameter types which use 4 bytes or less are all passed the same way, so it is not
necessary to be exact.

Currently, there is no way to pass a C structure by value. You can only pass a pointer
to a structure. However, you can pass a 64 bit integer by pretending to pass two C_LONG instead.
When calling the routine, pass low doubleword first, then high doubleword.

The C function can return a value but it will be ignored. If you want to use the value
returned by the C function, you must instead define it with [[:define_c_func]] and call it
with [[:c_func]].

===== Example 1:
<eucode>
atom user32
integer ShowWindow

-- open user32.dll - it contains the ShowWindow C function
user32 = open_dll("user32.dll")

-- It has 2 parameters that are both C int.
ShowWindow = define_c_proc(user32, "ShowWindow", {C_INT, C_INT})
-- If ShowWindow used the cdecl convention, 
-- we would have coded "+ShowWindow" here

if ShowWindow = -1 then
    puts(1, "ShowWindow not found!\n")
end if
</eucode>

===== See Also:
[[:c_proc]], [[:define_c_func]], [[:c_func]], [[:open_dll]]


@[:dll:define_c_func|]
==== define_c_func
<eucode>
include std/dll.e
namespace dll
public function define_c_func(object lib, object routine_name, sequence arg_types,
        atom return_type)
</eucode>

  defines the characteristics of either a C function, or a machine-code routine that returns
a value.

===== Parameters:
# ##lib## : an object, either an entry point returned as an atom by [[:open_dll]], or ##""## to denote a routine the RAM address is known.
# ##routine_name## : an object, either the name of a procedure in a shared object or the machine address of the procedure.
# ##argtypes## : a sequence of type constants.
# ##return_type## : an atom, indicating what type the function will return.

===== Returns:
A small **integer**, known as a routine id, will be returned.

===== Errors:
The length of ##name## should not exceed 1_024 characters.

===== Comments:
Use the returned routine id as the first argument to [[:c_proc]] when
you wish to call the routine from Euphoria.

A returned value of ##-1## indicates that the procedure could not be found or linked to.

On //Windows// you can add a
##'+'## character as a prefix to the function name. This indicates to Euphoria that the
function uses the cdecl calling convention. By default, Euphoria assumes that C routines
accept the stdcall convention.

When defining a machine code routine, ##x1## must be the empty sequence ( ##""## or ##{}##), and ##x2##
indicates the address of the machine code routine. You can poke the bytes of machine code
into a block of memory reserved using ##allocate##. On //Windows// the machine code routine is
normally expected to follow the stdcall calling convention, but if you wish to use the
cdecl convention instead, you can code ##{'+', address}## instead of address for ##x2##.

The C function that you define could be one created by the Euphoria To C Translator, in
which case you can pass Euphoria data to it, and receive Euphoria data back. A list of
Euphoria types is contained in ##dll.e##:

* E_INTEGER = #06000004
* E_ATOM    = #07000004
* E_SEQUENCE= #08000004
* E_OBJECT  = #09000004

You can pass or return any C integer type or pointer type. You can also pass a Euphoria
atom as a C double or float, and get a C double or float returned to you as a Euphoria atom.

Parameter types which use 4 bytes or less are all passed the same way, so it is not
necessary to be exact when choosing a 4-byte parameter type. However the distinction
between signed and unsigned may be important when you specify the return type of a function.

Currently, there is no way to pass a C structure by value or get a C structure as a return
result. You can only pass a pointer to a structure and get a pointer to a structure as a
result. However, you can pass a 64 bit integer as two ##C_LONG## instead. On calling the routine, pass low doubleword first, then high doubleword.

If you are not interested in using the value returned by the C function, you should
instead define it with [[:define_c_proc]] and call it with [[:c_proc]].

If you use euiw to call a cdecl C routine that returns a floating-point value, it might not
work. This is because the Watcom C compiler (used to build ##euiw##) has a non-standard way of
handling cdecl floating-point return values.

Passing floating-point values to a machine code routine will be faster if you use
##c_func## rather than ##call## to call the routine, since you will not have to use
##atom_to_float64## and ##poke## to get the floating-point values into memory.

===== Example 1:
<eucode>
atom user32
integer LoadIcon

-- open user32.dll - it contains the LoadIconA C function
user32 = open_dll("user32.dll")

-- It takes a C pointer and a C int as parameters.
-- It returns a C int as a result.
LoadIcon = define_c_func(user32, "LoadIconA",
                         {C_POINTER, C_INT}, C_INT)
-- We use "LoadIconA" here because we know that LoadIconA
-- needs the stdcall convention, as do
-- all standard .dll routines in the WINDOWS API. 
-- To specify the cdecl convention, we would have used "+LoadIconA".

if LoadIcon = -1 then
    puts(1, "LoadIconA could not be found!\n")
end if
</eucode>

===== See Also:
##demo\callmach.ex##, [[:c_func]], [[:define_c_proc]], [[:c_proc]], [[:open_dll]]


@[:eu:c_func|]
==== c_func
<eucode>
<built-in> function c_func(integer rid, sequence args={})
</eucode>

calls a C function, machine code function, translated Euphoria function, or compiled Euphoria function by routine id.

===== Parameters:
# ##rid## : an integer, the routine_id of the external function being called.
# ##args## : a sequence, the list of parameters to pass to the function

===== Returns:
An **object**, whose type and meaning was defined on calling [[:define_c_func]].

===== Errors:
If ##rid## is not a valid routine id, or the arguments do not match the prototype of
the routine being called, an error occurs.

===== Comments:
##rid## must have been returned by [[:define_c_func]], **not** by [[:routine_id]]. The
type checks are different, and you would get a machine level exception in the best case.

If the function does not take any arguments then ##args## should be ##{}##.

If you pass an argument value which contains a fractional part, where the C function expects
a C integer type, the argument will be rounded towards zero. For example: ##5.9## will be passed as ##5## and ##-5.9## will be passed as ##-5##.

The function could be part of a ##.dll## or ##.so## created by the Euphoria To C Translator. In this case,
a Euphoria atom or sequence could be returned. C and machine code functions can only return
integers, or more generally, atoms (IEEE floating-point numbers).

===== Example 1:
<eucode>
 atom user32, hwnd, ps, hdc
integer BeginPaint

-- open user32.dll - it contains the BeginPaint C function
user32 = open_dll("user32.dll")

-- the C function BeginPaint takes a C int argument and
-- a C pointer, and returns a C int as a result:
BeginPaint = define_c_func(user32, "BeginPaint",
                           {C_INT, C_POINTER}, C_INT)

-- call BeginPaint, passing hwnd and ps as the arguments,
-- hdc is assigned the result:
hdc = c_func(BeginPaint, {hwnd, ps})
</eucode>

===== See Also:

[[:c_proc]], [[:define_c_proc]], [[:open_dll]], [[:Platform-Specific Issues]]



@[:eu:c_proc|]
==== c_proc
<eucode>
<built-in> procedure c_proc(integer rid, sequence args={})
</eucode>

calls a C void function, machine code function, translated Euphoria procedure, or compiled Euphoria procedure by routine id.

===== Parameters:
# ##rid## : an integer, the routine_id of the external function being called.
# ##args## : a sequence, the list of parameters to pass to the function

===== Errors:
If ##rid## is not a valid routine id, or the arguments do not match the prototype of
the routine being called, an error occurs.

===== Comments:
##rid## must have been returned by [[:define_c_proc]], **not** by [[:routine_id]]. The
type checks are different, and you would get a machine level exception in the best case.

If the procedure does not take any arguments then ##args## should be ##{}##.

If you pass an argument value which contains a fractional part, where the C void function expects
a C integer type, the argument will be rounded towards zero. For example: ##5.9## will be passed as ##5## and ##-5.9## will be passed as ##-5##.

===== Example 1:
<eucode>
atom user32, hwnd, rect
integer GetClientRect

-- open user32.dll - it contains the GetClientRect C function
user32 = open_dll("user32.dll")

-- GetClientRect is a VOID C function that takes a C int
-- and a C pointer as its arguments:
GetClientRect = define_c_proc(user32, "GetClientRect",
                              {C_INT, C_POINTER})

-- pass hwnd and rect as the arguments
c_proc(GetClientRect, {hwnd, rect})
</eucode>

===== See Also:
[[:c_func]], [[:define_c_func]], [[:open_dll]], [[:Platform-Specific Issues]]



@[:dll:call_back|]
==== call_back
<eucode>
include std/dll.e
namespace dll
public function call_back(object id)
</eucode>

  gets a machine address for an Euphoria procedure.

===== Parameters:
# ##id## : an object, either the id returned by [[:routine_id]] (for the function or procedure), or a pair ##{'+', id}##.

===== Returns:
An **atom**, the address of the machine code of the routine. It can be
used by //Windows//, an external C routine in a //Windows// ##.dll##,  or //Unix//
shared library (##.so##), as a 32-bit "call-back" address for calling your
Euphoria routine.

===== Errors:
The length of ##name## should not exceed 1_024 characters.

===== Comments:
By default, your routine will work with the stdcall convention. On
//Windows// you can specify its id as ##{'+', id}##, in which case it will
work with the cdecl calling convention instead. On //Unix//
platforms, you should only use simple IDs, as there is just one standard
cdecl calling convention.

You can set up as many call-back functions as you like, but they must all be Euphoria
functions (or types) with ##0## to ##9## arguments. If your routine has nothing to return
(it should really be a procedure), just return ##0## (say), and the calling C routine can
ignore the result.

When your routine is called, the argument values will all be 32-bit unsigned (positive)
values. You should declare each parameter of your routine as atom, unless you want to
impose tighter checking. Your routine must return a 32-bit integer value.

You can also use a call-back address to specify a Euphoria routine as an exception
handler in the Linux or FreeBSD ##signal## function. For example, you might want to catch
the SIGTERM signal, and do a graceful shutdown. Some Web hosts send a SIGTERM to a CGI
process that has used too much CPU time.

A call-back routine that uses the cdecl convention and returns a floating-point result,
might not work with euiw. This is because the Watcom C compiler (used to build ##euiw##) has
a non-standard way of handling cdecl floating-point return values.

===== Example 1:
See~: ##.../euphoria/demo/win32/window.exw##

===== Example 2:
See~: ##.../euphoria/demo/linux/qsort.ex##

===== See Also:
[[:routine_id]]



!!CONTEXT:../include/std/error.e
!!namespace:error
%%output = std_error

== Errors and Warnings

<<LEVELTOC level=2 depth=4>>

=== Routines


@[:error:crash|]
==== crash
<eucode>
include std/error.e
namespace error
public procedure crash(sequence fmt, object data = {})
</eucode>

  crashes the running program and displays a formatted error message.

===== Parameters:
# ##fmt## : a sequence representing the message text. It may have format specifiers in it
# ##data## : an object, defaulted to ##{}##.

===== Comments:
Formatting is the same as with ##printf##.

The actual message being shown, both on standard error and in ##ex.err## (or whatever
file last passed to [[:crash_file]]), is ##sprintf(fmt, data)##.
The program terminates as for any runtime error.

===== Example 1:
<eucode>
if PI = 3 then
    crash("The structure of universe just changed -- reload solar_system.ex")
end if
</eucode>

===== Example 2:
<eucode>
if token = end_of_file then
    crash("Test file #%d is bad, text read so far is %s\n", 
                                                  {file_number, read_so_far})
end if
</eucode>

===== See Also:
[[:crash_file]], [[:crash_message]], [[:printf]]


@[:error:crash_message|]
==== crash_message
<eucode>
include std/error.e
namespace error
public procedure crash_message(sequence msg)
</eucode>

  specifies a final message to be displayed to your user, in the event
that Euphoria has to shut down your program due to an error.

===== Parameters:
# ##msg## : a sequence to display. It must only contain printable characters.

===== Comments:
There can be as many calls to ##crash_message## as needed in a program. Whatever was defined
last will be used in case of a runtime error.

===== Example 1:
<eucode>
crash_message("The password you entered must have at least 8 characters.")
pwd_key = input_text[1..8]
-- if ##input_text## is too short, 
-- user will get a more meaningful message than 
-- "index out of bounds".
</eucode>

===== See Also:
[[:crash]], [[:crash_file]]


@[:error:crash_file|]
==== crash_file
<eucode>
include std/error.e
namespace error
public procedure crash_file(sequence file_path)
</eucode>

  specifies a file path name in place of ##"ex.err"## where you want
any diagnostic information to be written.

===== Parameters:
# ##file_path## : a sequence, the new error and traceback file path.

===== Comments:
There can be as many calls to ##crash_file## as needed. Whatever was defined last will be used
in case of an error at runtime, whether it was triggered by [[:crash]] or not.

===== See Also:
[[:crash]], [[:crash_message]]


@[:eu:abort|]
==== abort
<eucode>
<built-in> procedure abort(atom error)
</eucode>

aborts execution of the program.

===== Parameters:
# ##error## : an integer, the exit code to return.

===== Comments:
##error## is expected to lie in the ##0..255## range. Zero is usually interpreted as the sign of a successful completion.

Other values can indicate various kinds of errors. //Windows// batch (##.bat##) programs can read
this value using the errorlevel feature. Non integer values are rounded down.
A Euphoria program can read this value using [[:system_exec]].

##abort## is useful when a program is many levels deep in subroutine calls, and execution must end immediately,
perhaps due to a severe error that has been detected.

If you do not use ##abort## then the interpreter will normally return an exit status code of zero.
If your program fails with a Euphoria-detected compile-time or run-time error then a code of one is returned.

===== Example 1:
<eucode>
if x = 0 then
    puts(ERR, "can't divide by 0 !!!\n")
    abort(1)
else
    z = y / x
end if
</eucode>

===== See Also:
[[:crash_message]], [[:system_exec]]


@[:error:warning_file|]
==== warning_file
<eucode>
include std/error.e
namespace error
public procedure warning_file(object file_path)
</eucode>

  specifies a file path where to output warnings.

===== Parameters:
# ##file_path## : an object indicating where to dump any warning that were produced.

===== Comments:
By default, warnings are displayed on the standard error, and require pressing the
Enter key to keep going. Redirecting to a file enables skipping the latter step and having
a console window open, while retaining ability to inspect the warnings in case any was issued.

Any atom ##>= 0## causes standard error to be used, thus reverting to default behaviour.

Any atom ##< 0## suppresses both warning generation and output. Use this latter in extreme cases
only.

On an error, some output to the console is performed anyway, so that whatever warning file
was specified is ignored then.

===== Example 1:
<eucode>
warning_file("warnings.lst")
-- some code
warning_file(0)
-- changed opinion: warnings will go to standard error as usual
</eucode>

===== See Also:
[[:On/off options|without warning]], [[:warning]]


@[:eu:warning|]
==== warning
<eucode>
<built-in> procedure warning(sequence message)
</eucode>

causes the specified warning message to be displayed as a regular warning.

===== Parameters:
# ##message## : a double quoted literal string, the text to display.

===== Comments:

Writing a library has specific requirements, since the code you write will be mainly used
inside code you did not write. It may be desirable then to influence, from inside the library,
that code you did not write.

This is what ##warning##, in a limited way, does. It enables to generate custom warnings in
code that will include yours. Of course, you can also generate warnings in your own code, for
instance as a kind of memo. The [[:On/off options|without warning]] top level statement disables such warnings.

The warning is issued with the ##custom_warning## level. This level is enabled by default,
but can be turned off any time.

Using any kind of expression in ##message## will result in a blank warning text.

===== Example 1:

<eucode>
-- mylib.e
procedure foo(integer n)
    warning("The foo() procedure is obsolete, use bar() instead.")
    ? n
end procedure

-- some_app.exw
include mylib.e
foo(123)
</eucode>

will result, when ##some_app.exw## is run ##with warning##, in the following text being
displayed in the console (terminal) window
{{{
123
Warning: ( custom_warning ):
The foo() procedure is obsolete, use bar() instead.

Press Enter...
}}}

===== See Also:
[[:warning_file]] [[:On/off options|without warning]]


@[:error:crash_routine|]
==== crash_routine
<eucode>
include std/error.e
namespace error
public procedure crash_routine(integer func)
</eucode>

  specifies a function to be called when an error takes place at run time.

===== Parameters:
# ##func## : an integer, the routine_id of the function to link in.

===== Comments:
The supplied function must have only one argument, which should be integer or more general.
Defaulted parameters in crash routines are not supported yet.

Euphoria maintains a linked list of routines to execute upon a crash. ##crash_routine## adds
a new function to the list. The routines defined first are executed last. You cannot unlink
a routine once it is linked, nor inspect the crash routine chain.

Currently, the crash routines are pass zero. Future versions may attempt to convey more
information to them. If a crash routine returns anything else than zero, the remaining
routines in the chain are skipped.

Crash routines are not fully fledged exception handlers, and they cannot resume execution at
current or next statement. However, they can read the generated crash file, and might
perform any action, including restarting the program.

===== Example 1:
<eucode>
function report_error(integer dummy)
  mylib:email("maintainer@remote_site.org", "ex.err")
   return 0 and dummy
end function
crash_routine(routine_id("report_error"))
</eucode>

===== See Also:
[[:crash_file]], [[:routine_id]], [[:Debugging and Profiling]]



!!CONTEXT:../include/std/eumem.e
!!namespace:eumem
%%output = std_eumem

== Pseudo Memory


One use is to emulate PBR, such as Euphoria's map and stack types.

<<LEVELTOC level=2 depth=4>>


@[:eumem:ram_space|]
==== ram_space
<eucode>
include std/eumem.e
namespace eumem
export sequence ram_space
</eucode>

  The (pseudo) RAM heap space. Use [[:malloc]] to gain ownership to a heap location
and [[:free]] to release it back to the system.


@[:eumem:malloc|]
==== malloc
<eucode>
include std/eumem.e
namespace eumem
export function malloc(object mem_struct_p = 1, integer cleanup_p = 1)
</eucode>

  allocates a block of (pseudo) memory.

===== Parameters:
# ##mem_struct_p## : The initial structure (sequence) to occupy the allocated
block. If this is an integer, a sequence of zero this long is used. The default
is the number one, meaning that the default initial structure is ##{0}##
# ##cleanup_p## : Identifies whether the memory should be released automatically
when the reference count for the handle for the allocated block drops to
zero, or when passed to ##delete##.  If zero, then the block must be freed
using the [[:free]] procedure.

===== Returns:
A **handle**, to the acquired block. Once you acquire the handle you can use it as needed.
Note that if ##cleanup_p## is one, then the variable holding the
handle must be capable of storing an atom (do not use an integer) as a double floating point value.

===== Example 1:
<eucode>
 my_spot = malloc()
 ram_space[my_spot] = my_data
</eucode>


@[:eumem:free|]
==== free
<eucode>
include std/eumem.e
namespace eumem
export procedure free(atom mem_p)
</eucode>

  deallocates a block of (pseudo) memory.

===== Parameters:
# ##mem_p## : The handle to a previously acquired [[:ram_space]] location.

===== Comments:
This allows the location to be used by other parts of your application. You
should no longer access this location again because it could be acquired by
some other process in your application.  This routine should only be called
if you passed zero as ##cleanup_p## to [[:malloc]].

===== Example 1:
<eucode>
 my_spot = malloc(1,0)
 ram_space[my_spot] = my_data
     -- . . . do some processing  . . . 
 free(my_spot)
</eucode>


@[:eumem:valid|]
==== valid
<eucode>
include std/eumem.e
namespace eumem
export function valid(object mem_p, object mem_struct_p = 1)
</eucode>

  validates a block of (pseudo) memory.

===== Parameters:
# ##mem_p## : The handle to a previously acquired [[:ram_space]] location.
# ##mem_struct_p## : If an integer, this is the length of the sequence that
should be occupying the ##ram_space## location pointed to by ##mem_p##.

===== Returns:
An **integer**,\\
0 if either the ##mem_p## is invalid or if the sequence at that location is
the wrong length.\\
1 if the handle and contents are okay.

===== Comments:
This can only check the length of the contents at the location. Nothing else
is checked at that location.

===== Example 1:
<eucode>
 my_spot = malloc()
 ram_space[my_spot] = my_data
 . . . do some processing  . . 
 if valid(my_spot, length(my_data)) then
     free(my_spot)
 end if
</eucode>



!!CONTEXT:../include/std/machine.e
!!namespace:machine
%%output = std_machine

== Machine Level Access

<<LEVELTOC level=2 depth=4>>
==== Marchine Level Access Summary
Warning: Some of these routines require a knowledge of
machine-level programming. You could crash your system!

These routines, along with [[:peek]], [[:poke]] and [[:call]], let you access all
of the features of your computer.  You can read and write to any allowed memory
location, and you can create and execute machine code subroutines.

If you are manipulating 32-bit addresses or values, remember to use
variables declared as atom. The integer type only goes up to 31 bits.

If you choose to call ##machine_proc## or ##machine_func## directly (to save
a bit of overhead) you *must* pass valid arguments or Euphoria could crash.

===== Some example programs to look at:
* ##demo/callmach.ex##      ~-- calling a machine language routine



@[:machine:peek_longs|]
==== peek_longs
<eucode>
include std/machine.e
namespace machine
public function peek_longs(object x)
</eucode>

  @nodoc


@[:machine:MAP_ANONYMOUS|]
==== MAP_ANONYMOUS
<eucode>
include std/machine.e
namespace machine
export constant MAP_ANONYMOUS
</eucode>





@[:machine:MAP_FAILED|]
==== MAP_FAILED
<eucode>
include std/machine.e
namespace machine
export constant MAP_FAILED
</eucode>





=== Safe Mode


==== Safe Mode Summary

During the development of your application, you can define the word ##SAFE## to cause
##machine.e## to use alternative memory functions. These functions are slower but
help in the debugging stages. In general, ##SAFE## mode should not be enabled during
production phases but only for development phases.

To define the word ##SAFE## run your application with the ##-D SAFE## command line
option, or add to the top of your main file~:

<eucode>
with define safe
</eucode>
before the first appearance of
##include std/machine.e##

The implementation of the Machine Level Access routines used are controled
with the define word ##SAFE##.
The use of ##SAFE## switches the routines included here to use debugging versions
which will allow you to catch all kinds of bugs that might otherwise may not
always crash your program where in the line your program is written.
There may be bugs that are invisible until you port the program they are in to
another platform.  There has been no bench marking for how much of a speed penalty
there is using ##SAFE##.


You can take advantage of ##SAFE## debugging by:

*  If necessary, call [[:register_block]](address, length, memory_protection) to add additional
"external" blocks of memory to the safe_address_list. These are blocks
of memory that are safe to use but which you did not acquire
through Euphoria's [[:allocate]], [[:allocate_data]], [[:allocate_code]] or [[:allocate_protect]],
[[:allocate_string]], [[:allocate_wstring]]. Call
[[:unregister_block]](address) when you want to prevent further access to
an external block.  When ##SAFE## is not enabled these functions will do nothing
and will be converted into nothing by the inline code in the front-end.

*  You will be notified if memory that you haven't allocated is accessed,
or if memory is freed twice, or if memory is used in the wrong way.  Your
application will can be ready for D.E.P. enabled systems even if the system you
test on doesn't have D.E.P..

*  If a bug is caught, you will hear some "beep" sounds.
Press Enter to clear the screen and see the error message.
There will be a descriptive crash message and a traceback in ex.err
so you can find the statement that is making the illegal memory access.




==== check_calls
Define block checking policy.
<eucode>
include std/machine.e
public integer check_calls
</eucode>

===== Comments:

If this integer is 1, (the default), check all blocks for edge corruption after each
[[:Executable Memory]], [[:call]], [[:c_proc]] or [[:c_func]].
To save time, your program can turn off this checking by setting check_calls to 0.


==== edges_only
<eucode>
include std/machine.e
public integer edges_only
</eucode>
Determine whether to flag accesses to remote memory areas.

===== Comments:

If this integer is 1 (the default under //Windows//), only check for references to the
leader or trailer areas just outside each registered block, and don't complain about
addresses that are far out of bounds (it's probably a legitimate block from another source)

For a stronger check, set this to 0 if your program will never read/write an
unregistered block of memory.

On //Windows// people often use unregistered blocks.  Please do not be one of them.


==== check_all_blocks
<eucode>
include std/machine.e
check_all_blocks()
</eucode>

Scans the list of registered blocks for any corruption.

===== Comments:

safe.e maintains a list of acquired memory blocks. Those gained through
##allocate## are automatically included. Any other block,
for debugging purposes, must be registered by [[:register_block]]
and unregistered by [[:unregister_block]].

The list is scanned and, if any block shows signs of corruption, it is
displayed on the screen and the program terminates. Otherwise, nothing
happens.

Unless ##SAFE## is defined, this routine does nothing. It is there to make switching
between debugged and normal version of your program easier.

===== See Also:
[[:register_block]], [[:unregister_block]]


==== register_block
<eucode>
include std/machine.e
procedure register_block(machine_addr block_addr, positive_int block_len, 
            valid_memory_protection_constant memory_protection = PAGE_READ_WRITE )
</eucode>
Adds a block of memory to the list of safe blocks maintained
by safe.e (the debug version of memory.e). The block starts at address a.
The length of the block is i bytes.

===== Parameters:
# ##block_addr## : an atom, the start address of the block
# ##block_len## : an integer, the size of the block.
# ##protection## : a constant integer, of the memory
protection constants found in machine.e, that describes
what access we have to the memory.

===== Comments:

In memory.e, this procedure does nothing. It is there to simplify
switching between the normal and debug version of the library.

This routine is only meant to be used for debugging purposes. safe.e
tracks the blocks of memory that your program is allowed to
[[:peek]], [[:poke]], [[:mem_copy]] etc. These are normally just the
blocks that you have allocated using Euphoria's [[:allocate]]
routine, and which you have not yet freed using
Euphoria's [[:free]]. In some cases, you may acquire
additional, external, blocks of memory, perhaps as a result of calling a
C routine.

If you are debugging your program using ##safe.e##, you must register these
external blocks of memory or ##safe.e## will prevent you from accessing them.
When you are finished using an external block you can unregister it using
##unregister_block##.

===== Example 1:
<eucode>
 atom addr

addr = c_func(x, {})
register_block(addr, 5)
poke(addr, "ABCDE")
unregister_block(addr)
</eucode>

===== See Also:
[[:unregister_block]], [[:Safe Mode]]


==== unregister_block
<eucode>
include std/machine.e
public procedure unregister_block(machine_addr block_addr)
</eucode>
removes a block of memory from the list of safe blocks maintained by safe.e
(the debug version of memory.e).

===== Parameters:
# ##block_addr## : an atom, the start address of the block

===== Comments:

In memory.e, this procedure does nothing. It is there to simplify
switching between the normal and debug version of the library.

This routine is only meant to be used for debugging purposes. Use it to
unregister blocks of memory that you have previously registered using
[[:register_block]]. By unregistering a block, you remove it from the
list of safe blocks maintained by safe.e. This prevents your program from
performing any further reads or writes of memory within the block.

See [[:register_block]] for further comments and an example.

===== See Also:
[[:register_block]], [[:Safe Mode]]


=== Data Execute Mode and Data Execute Protection

##Data Execute Mode## makes data that will be returned from [[:allocate]] executable.  On some
systems you will not be allowed to run code in memory returned from [[:allocate]] unless this mode has been enabled.   This restriction is called Data Execute Protection or D.E.P..  When writing software you should use [[:allocate_code]] or [[:allocate_protect]] to get memory for execution.  This is more efficient and more secure than using ##Data Execute mode##.  Because many hacker exploits of software use data buffers and then trick software into running this data, Data Execute Protection stops an entire class of exploits.

If you get a Data Execute Protection Exception from running software, it means that D.E.P. could have thwarted an attack!  Your application crashes and your computer wasn't infected.  However, many people will decide that they want to disable D.E.P. because they know that they call memory returned by [[:allocate]] or perhaps they are simply careless.


=== Type Sorted Function List



==== Executable Memory
Executable Memory is the way to run code on the stack in a completly portable way.

===== Use the following Routines:
Use [[:allocate_code]] to allocate some executable machine-code,
[[:call]] to call the code,
and [[:free_code]] to free the machine-code.



====Using Data Bytes
In C, bytes are called 'char' or 'BOOL' or 'boolean'.  They sometimes are used for very small numbers but mostly, they are used in C-strings.
See [[:Using Strings]].

Use [[:allocate_data]] to allocate data and return an address.
Use [[:poke]] to save atoms or sequences to at an address.
Use [[:peeks]] or [[:peek]] to read from an address.
Use [[:mem_set]] and [[:mem_copy]] to set and copy sections of memory.
Use [[:free]] to free or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].


==== Using Data Words
Words are 16-bit integers and are big enough to hold most integers in common use as far as whole numbers go.  So they often are used to hold numbers.  In C, they are declared as WORD or short.

Use [[:allocate_data]] to allocate data and return its address.
Use [[:poke2]] to write to the data at an address.
Use [[:peek2]] or [[:peek2s]] to read from an address.
Use [[:free]] to free or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].


==== Using Data Double Words

Double words are 32-bit integers.  In C, they are typically declared as int, or long
(on Windows and other 32-bit architectures), or DWORD.  They
are big enough to hold pointers to other values in memory on 32-bit architectures.

Use [[:allocate_data]] to allocate data and return its address.
Use [[:poke4]] to write to the data at an address.
Use [[:peek4]] or [[:peek4s]] to read from an address.
Use [[:free]] to free or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].


==== Using Data Quad Words

Quad words are 64-bit integers.  In C, they are typically declared as long long int,
or long int (on 64-bit architectures other than Windows).  They
are big enough to hold pointers to other values in memory on 64-bit architectures.

Use [[:allocate_data]] to allocate data and return its address.
Use [[:poke8]] to write to the data at an address.
Use [[:peek8u]] or [[:peek8s]] to read from an address.
Use [[:free]] to free or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].



==== Using Pointers

A Euphoria atom should be used to store pointer values.  On 32-bit architectures,
pointers may be larger than a Euphoria integer.  On 64-bit architectures, a
Euphoria integer is large enough to hold pointer values, since current 64-bit
architectures use only a 48-bit memory space

To portably peek and poke pointers, you should use [[:peek_pointer]] and
[[:poke_pointer]].  These routines automatically detect the architecture
and use the correct size for a pointer.


==== Using Long Integers

When interfacing with C code, some data will be defined as ##long## or ##long int##.
This data type can be tricky to use in a portable manner, due to the way that different
architectures and operating systems define it.

On all 32-bit architectures on which Euphoria runs, a ##long int## is defined as 32-bits.
On 64-bit Windows, a ##long int## is also 32-bits.  However, on other 64-bit operating
systems, a ##long int## is defined as 64-bits.

To portably peek and poke ##long int## data, you should use [[:peek_longs]], [[:peek_longu]]
and [[:poke_long]].  You can also use ##sizeof( C_LONG )## to determine the size (in bytes)
of a native ##long int##.


====  Using Strings

You can create legal ANSI and 16-bit UNICODE Strings with these routines.  In C, strings are often declared
as some pointer to a character:  char * or wchar *.

Microsoft Windows uses 8-bit ANSI and 16-bit UNICODE in its routines.

Use [[:allocate_string]] or [[:allocate_wstring]] to allocate a string pointer.
Use [[:peek_string]], [[:peek_wstring]], [[:peek4]], to read from memory byte strings, word strings and double word strings repsectively.
Use [[:poke]], [[:poke2]], or [[:poke4]] to write to memory byte strings, word strings and double word strings.
Use [[:free]] to free or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].


====  Using Pointer Arrays

Use [[:allocate_string_pointer_array]] to allocate a string array from a sequence of strings.  Use [[:allocate_pointer_array]] to allocate and then write to an array for pointers .
Use [[:free_pointer_array]] to deallocate or use [[:delete]] if you enabled ##cleanup## in [[:allocate_data]].


=== Memory Allocation



@[:machine:allocate|]
==== allocate
<eucode>
include std/machine.e
namespace machine
public function allocate(memory :positive_int n, types :boolean cleanup = 0)
</eucode>

  This does the same as [[:allocate_data]] but allows the DATA_EXECUTE defined word
to cause it to return executable memory.

===== See Also:
[[:allocate_data]], [[:allocate_code]], [[:free]]


@[:machine:allocate_data|]
==== allocate_data
<eucode>
include std/machine.e
namespace machine
public function allocate_data(memory :positive_int n, types :boolean cleanup = 0)
</eucode>

  Allocate a contiguous block of data memory.

===== Parameters:
# ##n## : a positive integer, the size of the requested block.
# ##cleanup## : an integer, if non-zero, then the returned pointer will be
automatically freed when its reference count drops to zero, or
when passed as a parameter to [[:delete]].

===== Returns:
An **atom**, the address of the allocated memory or 0 if the memory
can't be allocated. **NOTE** you must use either an atom or object to
receive the returned value as sometimes the returned memory address is
too larger for an integer to hold.

===== Comments:
* Since ##allocate## acquires memory from the system, it is your responsiblity to
return that memory when your application is done with it. There are two ways to
do that - automatically or manually.
** //Automatically// - If the ##cleanup## parameter is non-zero, then the memory
is returned when the variable that receives the address goes out of scope **and**
is not referenced by anything else. Alternatively you can force it be released by
calling the [[:delete]] function.
** //Manually// - If the ##cleanup## parameter is zero, then you must call the
[[:free]] function at some point in your program to release the memory back to the system.
* When your program terminates, the operating system will reclaim
all memory that your applicaiton acquired anyway.
* An address returned by this function shouldn't be passed to ##[[:call]]##.
For that purpose you should use ##[[:allocate_code]]## instead.
* The address returned will be at least 8-byte aligned.

===== Example 1:
<eucode>
buffer = allocate(100)
for i = 0 to 99 do
    poke(buffer+i, 0)
end for
</eucode>

===== See Also:
[[:Using Data Bytes]], [[:Using Data Words]], [[:Using Data Double Words]], [[:Using Strings]], [[:allocate_code]], [[:free]]


@[:machine:allocate_pointer_array|]
==== allocate_pointer_array
<eucode>
include std/machine.e
namespace machine
public function allocate_pointer_array(sequence pointers, types :boolean cleanup = 0)
</eucode>

  Allocate a NULL terminated pointer array.

===== Parameters:
# ##pointers## : a sequence of pointers to add to the pointer array.
# ##cleanup## : an integer, if non-zero, then the returned pointer will be
automatically freed when its reference count drops to zero, or
when passed as a parameter to [[:delete]]

===== Comments:
This function adds the NULL terminator.

===== Example 1:
<eucode>
atom pa
pa = allocate_pointer_array({ allocate_string("1"), allocate_string("2") })
</eucode>

===== See Also:
[[:Using Pointer Arrays]], [[:allocate_string_pointer_array]], [[:free_pointer_array]]


@[:machine:free_pointer_array|]
==== free_pointer_array
<eucode>
include std/machine.e
namespace machine
public procedure free_pointer_array(atom pointers_array)
</eucode>

  Free a NULL terminated pointers array.

===== Parameters:
# ##pointers_array## : memory address of where the NULL terminated array exists at.

===== Comments:
This is for NULL terminated lists, such as allocated by [[:allocate_pointer_array]].
Do not call ##free_pointer_array## for a pointer that was allocated to be cleaned
up automatically.  Instead, use [[:delete]].

===== See Also:
[[:allocate_pointer_array]], [[:allocate_string_pointer_array]]


@[:machine:allocate_string_pointer_array|]
==== allocate_string_pointer_array
<eucode>
include std/machine.e
namespace machine
public function allocate_string_pointer_array(object string_list, types :boolean cleanup = 0)
</eucode>

  Allocate a C-style null-terminated array of strings in memory

===== Parameters:
# ##string_list## : sequence of strings to store in RAM.
# ##cleanup## : an integer, if non-zero, then the returned pointer will be
automatically freed when its reference count drops to zero, or
when passed as a parameter to [[:delete]]

===== Returns:
An **atom**, the address of the memory block where the string pointer
array was stored.

===== Example 1:
<eucode>
atom p = allocate_string_pointer_array({ "One", "Two", "Three" })
-- Same as C: char *p = { "One", "Two", "Three", NULL };
</eucode>

===== See Also:
[[:Using Pointer Arrays]], [[:free_pointer_array]]


@[:machine:allocate_wstring|]
==== allocate_wstring
<eucode>
include std/machine.e
namespace machine
public function allocate_wstring(sequence s, types :boolean cleanup = 0)
</eucode>

  Create a C-style null-terminated wchar_t string in memory

===== Parameters:
# ##s## : a unicode (utf16) string

===== Returns:
An **atom**, the address of the allocated string, or 0 on failure.

===== See Also:
[[:Using Strings]], [[:allocate_string]]



=== Reading from Memory


@[:eu:peek|]
==== peek
<eucode>
<built-in> function peek(object addr_n_length)
</eucode>

fetches a byte, or some bytes, from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one byte at ##addr##, or
** a pair {##addr,len}## ~-- to fetch ##len## bytes at ##addr##

===== Returns:
An **object**, either an integer if the input was a single address,
or a sequence of integers if a sequence was passed. In both cases,
integers returned are bytes, in the range 0..255.

===== Errors:

[[:peek | Peeking]] in memory you don't own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error.

When supplying a {address, count} sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several bytes at once using the second form of ##peek##
than it is to read one byte at a time in a loop. The returned sequence has
the length you asked for on input.

Remember that ##peek## takes just one argument, which in the second form
is actually a 2-element sequence.

===== Example 1:
<eucode>
-- The following are equivalent:
-- first way
s = {peek(100), peek(101), peek(102), peek(103)}

-- second way
s = peek({100, 4})
</eucode>

===== See Also:
[[:Using Data Bytes]], [[:poke]], [[:peeks]], [[:peek4u]], [[:allocate]], [[:free]],
[[:peek2u]]



@[:eu:peeks|]
==== peeks
<eucode>
<built-in> function peeks(object addr_n_length)
</eucode>

fetches a byte, or some bytes, from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## : to fetch one byte at ##addr##, or
** a pair {##addr,len}## : to fetch ##len## bytes at ##addr##

===== Returns:

An **object**, either an integer if the input was a single address,
or a sequence of integers if a sequence was passed. In both cases,
integers returned are bytes, in the range -128..127.

===== Errors:

[[:peek | Peeking]] in memory you do not own may be blocked by the OS, and cause
a machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a {address, count} sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several bytes at once using the second form of ##peek##
than it is to read one byte at a time in a loop. The returned sequence has
the length you asked for on input.

Remember that ##peeks## takes just one argument, which in the second
form is actually a 2-element sequence.

===== Example 1:

<eucode>
-- The following are equivalent:
-- first way
s = {peeks(100), peek(101), peek(102), peek(103)}

-- second way
s = peeks({100, 4})
</eucode>

===== See Also:

[[:Using Data Bytes]], [[:poke]], [[:peek4s]], [[:allocate]], [[:free]],
[[:peek2s]], [[:peek]]



@[:eu:peek2s|]
==== peek2s
<eucode>
<built-in> function peek2s(object addr_n_length)
</eucode>

Fetches a //signed// word, or some //signed// words  , from an address
in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one word at ##addr##, or
** a pair ##{ addr, len}##, to fetch ##len## words at ##addr##

===== Returns:
An **object**, either an integer if the input was a single address,
or a sequence of integers if a sequence was passed. In both cases,
integers returned are double words, in the range -32768..32767.

===== Errors:
Peeking in memory you don't own may be blocked by the OS, and cause
a machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:
Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several words at once using the second form of ##peek##
than it is to read one word at a time in a loop. The returned sequence has
the length you asked for on input.

Remember that ##peek2s## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek2s## and ##peek2u## is how words
with the highest bit set are returned. ##peek2s## assumes them to be
negative, while ##peek2u## just assumes them to be large and positive.

===== Example 1:

<eucode>
-- The following are equivalent:
-- first way
s = {peek2s(100), peek2s(102), peek2s(104), peek2s(106)}

-- second way
s = peek2s({100, 4})
</eucode>

===== See Also:

[[:Using Data Words]], [[:poke2]], [[:peeks]], [[:peek4s]], [[:allocate]], [[:free]]
[[:peek2u]]



@[:eu:peek2u|]
==== peek2u
<eucode>
<built-in> function peek2u(object addr_n_length)
</eucode>

fetches an //unsigned// word, or some //unsigned// words, from an address
in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr##

===== Returns:
An **object**, either an integer if the input was a single address,
or a sequence of integers if a sequence was passed. In both cases,
integers returned are words, in the range 0..65535.

===== Errors:
Peeking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several words at once using the second form of ##peek##
than it is to read one word at a time in a loop. The returned sequence has
the length you asked for on input.

Remember that ##peek2u## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek2s## and ##peek2u## is how words
with the highest bit set are returned. ##peek2s## assumes them to be
negative, while ##peek2u## just assumes them to be large and positive.

===== Example 1:
<eucode>
-- The following are equivalent:
-- first way
Get 4 2-byte numbers starting address 100.
s = {peek2u(100), peek2u(102), peek2u(104), peek2u(106)}

-- second way
Get 4 2-byte numbers starting address 100.
s = peek2u({100, 4})
</eucode>

===== See Also:
[[:Using Data Words]], [[:poke2]], [[:peek]], [[:peek2s]], [[:allocate]], [[:free]]
[[:peek4u]]



@[:eu:peek4s|]
==== peek4s
<eucode>
<built-in> function peek4s(object addr_n_length)
</eucode>

fetches a //signed// double words, or some //signed// double words,
from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair ##{ addr, len }## ~-- to fetch ##len## double words at ##addr##

===== Returns:
An **object**, either an atom if the input was a single address, or a
sequence of atoms if a sequence was passed. In both cases, atoms returned
are double words, in the range -(2^^31^^)..2^^31^^-1.

===== Errors:
Peeking in memory you don't own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several double words at once using the second form
of ##peek## than it is to read one double word at a time in a loop. The
returned sequence has the length you asked for on input.

Remember that ##peek4s## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek4s## and [[:peek4u]] is how double
words with the highest bit set are returned. ##peek4s## assumes them to
be negative, while [[:peek4u]] just assumes them to be large and positive.

===== Example 1:
<eucode>
-- The following are equivalent:
-- first way
s = {peek4s(100), peek4s(104), peek4s(108), peek4s(112)}

-- second way
s = peek4s({100, 4})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:poke4]], [[:peeks]], [[:peek4u]], [[:allocate]], [[:free]],
[[:peek2s]]



@[:eu:peek8s|]
==== peek8s
<eucode>
<built-in> function peek8s(object addr_n_length)
</eucode>

fetches a //signed// quad words, or some //signed// quad words,
from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair ##{ addr, len }## ~-- to fetch ##len## quad words at ##addr##

===== Returns:
An **object**, either an atom if the input was a single address, or a
sequence of atoms if a sequence was passed. In both cases, atoms returned
are quad words, in the range -power(2,63)..power(2,63)-1.

===== Errors:
Peeking in memory you don't own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several quad words at once using the second form
of ##peek## than it is to read one quad word at a time in a loop. The
returned sequence has the length you asked for on input.

Remember that ##peek8s## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek8s## and [[:peek8u]] is how quad
words with the highest bit set are returned. ##peek4s## assumes them to
be negative, while [[:peek4u]] just assumes them to be large and positive.

===== Example 1:
<eucode>
-- The following are equivalent:
-- first way
s = {peek8s(100), peek8s(108), peek8s(116), peek8s(124)}

-- second way
s = peek8s({100, 4})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:poke4]], [[:peeks]], [[:peek4u]], [[:allocate]], [[:free]],
[[:peek2s]]





@[:eu:peek4u|]
==== peek4u
<eucode>
<built-in> function peek4u(object addr_n_length)
</eucode>

fetches an //unsigned// double word, or some //unsigned// double words,
from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr##

===== Returns:
An **object**, either an atom if the input was a single address, or
a sequence of atoms if a sequence was passed. In both cases, atoms
returned are double words, in the range 0..2^^32^^-1.

===== Errors:
Peeking in memory you do not own may be blocked by the OS, and cause
a machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several double words at once using the second form
of ##peek## than it is to read one double word at a time in a loop. The
returned sequence has the length you asked for on input.

Remember that ##peek4u## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek4s## and ##peek4u## is how double
words with the highest bit set are returned. ##peek4s## assumes them
to be negative, while ##peek4u## just assumes them to be large and
positive.

===== Example 1:
<eucode>
-- The following are equivalent:
-- first way
s = {peek4u(100), peek4u(104), peek4u(108), peek4u(112)}

-- second way
s = peek4u({100, 4})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:poke4]], [[:peek]], [[:peek4s]], [[:allocate]], [[:free]], [[:peek2u]]



@[:eu:peek8u|]
==== peek8u
<eucode>
<built-in> function peek8u(object addr_n_length)
</eucode>

fetches an //unsigned// quad word, or some //unsigned// quad words,
from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr##

===== Returns:
An **object**, either an atom if the input was a single address, or
a sequence of atoms if a sequence was passed. In both cases, atoms
returned are quad words, in the range 0..power(2,64)-1.

===== Errors:
Peeking in memory you do not own may be blocked by the OS, and cause
a machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several quad words at once using the second form
of ##peek## than it is to read one quad word at a time in a loop. The
returned sequence has the length you asked for on input.

Remember that ##peek8u## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek8s## and ##peek8u## is how quad
words with the highest bit set are returned. ##peek8s## assumes them
to be negative, while ##peek8u## just assumes them to be large and
positive.

===== Example 1:
<eucode>
-- The following are equivalent:
--first way
s = {peek8u(100), peek8u(108), peek8u(116), peek8u(124)}

-- second way
s = peek8u({100, 4})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:poke4]], [[:peek]], [[:peek4s]], [[:allocate]], [[:free]], [[:peek2u]]



@[:eu:peek_longu|]
==== peek_longu
<eucode>
<built-in> function peek_longu(object addr_n_length)
</eucode>

fetches an //unsigned// integer, or some //unsigned// integers,
from an address in memory.

===== Parameters:
# ##addr_n_length## : an object, either of
** an atom ##addr## ~-- to fetch one double word at ##addr##, or
** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr##

===== Returns:
An **object**, either an atom if the input was a single address, or a
sequence of atoms if a sequence was passed. In both cases, atoms returned
are based on the native size of a "long int."  On //Windows// and all other 32-bit
architectures, the number will be in the range 0..power(2,32)-1.
On other 64-bit architectures, the number will be in the range of
0..power(2,64)-1.

===== Errors:
Peeking in memory you do not own may be blocked by the OS, and cause
a machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

When supplying a ##{address, count}## sequence, the count must not be negative.

===== Comments:

Since addresses are 32-bit numbers on 32-bit architectures, they can be larger than the largest
value of type integer (31-bits). Variables that hold an address should
therefore be declared as atoms.

It is faster to read several integers at once using the second form
of ##peek## than it is to read one integer at a time in a loop. The
returned sequence has the length you asked for on input.

Remember that ##peek_longu## takes just one argument, which in the second
form is actually a 2-element sequence.

The only difference between ##peek_longs## and ##peek_longu## is how double
words with the highest bit set are returned. ##peek4s## assumes them
to be negative, while ##peek_longu## just assumes them to be large and
positive.

===== Example 1:
<eucode>
-- The following are equivalent (on a 32-bit architecture, or Windows):
-- first way
s = {peek_longu(100), peek4u(104), peek4u(108), peek4u(112)}

-- second way
s = peek_longu({100, 4})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:poke4]], [[:peek]], [[:peek4s]], [[:allocate]], [[:free]], [[:peek2u]],
[[:peek2s]], [[:peek8u]], [[:peek8s]], [[:peek_longs]], [[:poke_long]]


@[:eu:peek_string|]
==== peek_string
<eucode>
<built-in> function peek_string(atom addr)
</eucode>

reads an ASCII string in RAM, starting from a supplied address.

===== Parameters:
# ##addr## : an atom, the address at which to start reading.

===== Returns:
A **sequence**, of bytes, the string that could be read.

===== Errors:
Further, peeking in memory that does not belong to your process is something the operating
system could prevent, and you'd crash with a machine level exception.

===== Comments:

An ASCII string is any sequence of bytes and ends with a 0 byte.
If you ##peek_string## at some place where there is no string, you will get a sequence of garbage.

===== See Also:
[[:Using Strings]], [[:peek]], [[:peek_wstring]], [[:allocate_string]]


@[:eu:peek_pointer|]
==== peek_pointer
<eucode>
<built-in> function peek_pointer(object addr_n_length)
</eucode>


@[:machine:peek_wstring|]
==== peek_wstring
<eucode>
include std/machine.e
namespace machine
public function peek_wstring(atom addr)
</eucode>

  returns a unicode (utf16) string that are stored at machine address a.

===== Parameters:
# ##addr## : an atom, the address of the string in memory

===== Returns:
The **string**, at the memory position.  The terminator is the null word (two bytes equal to 0).

===== See Also:
[[:Using Strings]], [[:peek_string]]


=== Writing to Memory


@[:eu:poke|]
==== poke
<eucode>
<built-in> procedure poke(atom addr, object x)
</eucode>

stores one or more bytes, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either a byte or a non empty sequence of bytes.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. The ##-D SAFE## option will make ##poke## catch this sort of issues.

===== Comments:

The lower 8-bits of each byte value (such as ##remainder(x, 256)##) is actually
stored in memory.

It is faster to write several bytes at once by poking a sequence of values,
than it is to write one byte at a time in a loop.

Writing to the screen memory with ##poke## can be much faster than using
##puts## or ##printf##, but the programming is more difficult. In most cases
the speed is not needed. For example, the Euphoria editor, ##ed##, never uses
##poke##.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one byte at a time:
poke(a, 97)
poke(a+1, 98)
poke(a+2, 99)

-- poke 3 bytes at once:
poke(a, {97, 98, 99})
</eucode>

===== Example 2:
##demo/callmach.ex##

===== See Also:
[[:Using Data Bytes]], [[:peek]], [[:peeks]], [[:poke4]], [[:allocate]], [[:free]], [[:poke2]],
[[:mem_copy]], [[:mem_set]]



@[:eu:poke2|]
==== poke2
<eucode>
<built-in> procedure poke2(atom addr, object x)
</eucode>

stores one or more words, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either a word or a non empty sequence of words.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

===== Comments:

There is no point in having ##poke2s## or ##poke2u##. For example, both 32768
and -32768 are stored as ###F000## when stored as words. It is up to whoever
reads the value to figure it out.

It is faster to write several words at once by poking a sequence of
values, than it is to write one words at a time in a loop.

Writing to the screen memory with ##poke2## can be much faster than using
##puts## or ##printf##, but the programming is more difficult. In most cases
the speed is not needed. For example, the Euphoria editor, ed, never uses
##poke2##.

The 2-byte values to be stored can be negative or positive. You can read
them back with either ##peek2s## or ##peek2u##. Actually, only
##remainder(##x##,65536)## is being stored.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one 2-byte value at a time:
poke2(a, 12345)
poke2(a+2, #FF00)
poke2(a+4, -12345)

-- poke 3 2-byte values at once:
poke2(a, {12345, #FF00, -12345})
</eucode>

===== See Also:
[[:Using Data Words]], [[:peek2s]], [[:peek2u]], [[:poke]], [[:poke4]], [[:allocate]], [[:free]]



@[:eu:poke4|]
==== poke4
<eucode>
<built-in> procedure poke4(atom addr, object x)
</eucode>

stores one or more double words, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either a double word or a non empty sequence of
double words.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

===== Comments:

There is no point in having ##poke4s## or ##poke4u##. For example, both
+2^^31^^ and -(2^^31^^) are stored as ###F0000000##. It is up to whoever
reads the value to figure it out.

It is faster to write several double words at once by poking a sequence
of values, than it is to write one double words at a time in a loop.

Writing to the screen memory with ##poke4## can be much faster than using
##puts## or ##printf##, but the programming is more difficult. In most cases
the speed is not needed. For example, the Euphoria editor, ed, never uses
##poke4##.

The 4-byte values to be stored can be negative or positive. You can read
them back with either ##peek4s## or ##peek4u##. However, the results
are unpredictable if you want to store values with a fractional part or a
magnitude greater than 2^^32^^, even though Euphoria represents them
all as atoms.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one 4-byte value at a time:
poke4(a, 9712345)
poke4(a+4, #FF00FF00)
poke4(a+8, -12345)

-- poke 3 4-byte values at once:
poke4(a, {9712345, #FF00FF00, -12345})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:peek4s]], [[:peek4u]], [[:poke]], [[:poke2]], [[:allocate]], [[:free]], [[:call]]



@[:eu:poke8|]
==== poke8
<eucode>
<built-in> procedure poke8(atom addr, object x)
</eucode>

stores one or more quad words, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either a quad word or a non empty sequence of
double words.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

===== Comments:

There is no point in having ##poke8s## or ##poke8u##. For example, both
+power(2,63) and -power(2,63) are stored as ###F000000000000000##. It is up to whoever
reads the value to figure it out.

It is faster to write several quad words at once by poking a sequence
of values, than it is to write one quad words at a time in a loop.

The 8-byte values to be stored can be negative or positive. You can read
them back with either ##peek8s## or ##peek8u##. However, the results
are unpredictable if you want to store values with a fractional part or a
magnitude greater than power(2,64), even though Euphoria represents them
all as atoms.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one 8-byte value at a time:
poke8(a, 9712345)
poke8(a+8, #FF00FF00)
poke8(a+16, -12345)

-- poke 3 8-byte values at once:
poke8(a, {9712345, #FF00FF00, -12345})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:peek4s]], [[:peek4u]], [[:poke]], [[:poke2]], [[:allocate]], [[:free]], [[:call]]



@[:eu:poke_long|]
==== poke_long
<eucode>
<built-in> procedure poke_long(atom addr, object x)
</eucode>

stores one or more integers, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either an integer or a non empty sequence of
double words.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

===== Comments:

There is no point in having ##poke_longs## or ##poke_longu##. For example, both
+power(2,31) and -power(2,31) are stored as ###F0000000## on a 32-bit
architecture. It is up to whoever reads the value to figure it out.

On all //Windows// and other 32-bit operating systems, the ##poke_long##
uses 4-byte integers.  On 64-bit architectures using operating systems
other than //Windows//, ##poke_long## uses 8-byte integers.

It is faster to write several integers at once by poking a sequence
of values, than it is to write one double words at a time in a loop.

The 4-byte (or 8-byte) values to be stored can be negative or positive. You can read
them back with either ##peek_longs## or ##peek_longu##. However, the results
are unpredictable if you want to store values with a fractional part or a
magnitude greater than the size of a native ##long int##, even though Euphoria represents them
all as atoms.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one 4-byte value at a time (on Windows or other 32-bit operating system):
poke_long(a, 9712345)
poke_long(a+4, #FF00FF00)
poke_long(a+8, -12345)

-- poke 3 long int values at once:
poke_long(a, {9712345, #FF00FF00, -12345})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:peek4s]], [[:peek4u]], [[:poke]], [[:poke2]], [[:allocate]], [[:free]], [[:call]]



@[:eu:poke_pointer|]
==== poke_pointer
<eucode>
<built-in> procedure poke_pointer(atom addr, object x)
</eucode>

stores one or more pointers, starting at a memory location.

===== Parameters:
# ##addr## : an atom, the address at which to store
# ##x## : an object, either an integer or a non empty sequence of
pointers.

===== Errors:
Poking in memory you do not own may be blocked by the OS, and cause a
machine exception. If you use the define safe these routines will catch these problems with a Euphoria error.

===== Comments:

There is no point in having ##poke_pointers## or ##poke_pointersu##. For example, both
+power(2,31) and -power(2,31) are stored as ###F0000000## on a 32-bit
architecture. It is up to whoever reads the value to figure it out.

On all  32-bit operating systems, the ##poke_pointer##
uses 4-byte integers.  On 64-bit architectures using operating systems,
##poke_pointer## uses 8-byte integers.

It is faster to write several pointers at once by poking a sequence
of values, than it is to write one double words at a time in a loop.

The 4-byte (or 8-byte) values to be stored can be negative or positive. You can read
them back with either ##peek_pointer## or any other peek function of the correctsize. However, the results
are unpredictable if you want to store values with a fractional part or a
magnitude greater than the size of a native ##pointer##, even though Euphoria represents them
all as atoms.

===== Example 1:
<eucode>
 a = allocate(100)   -- allocate 100 bytes in memory

-- poke one 4-byte value at a time (on a 32-bit operating system):
poke_pointer(a, 9712345)
poke_pointer(a+4, #FF00FF00)
poke_pointer(a+8, -12345)

-- poke 3 long int values at once:
poke_pointer(a, {9712345, #FF00FF00, -12345})
</eucode>

===== See Also:
[[:Using Data Double Words]], [[:peek4s]], [[:peek4u]], [[:peek8u]], [[:peek8s]], [[:peek_pointer]] [[:poke]], [[:poke2]], [[:allocate]], [[:free]], [[:call]]



@[:machine:poke_string|]
==== poke_string
<eucode>
include std/machine.e
namespace machine
public function poke_string(atom buffaddr, integer buffsize, sequence s)
</eucode>

  Stores a C-style null-terminated ANSI string in memory

===== Parameters:
# ##buffaddr##: an atom, the RAM address to to the string at.
# ##buffsize##: an integer, the number of bytes available, starting from ##buffaddr##.
# ##s## : a sequence, the string to store at address ##buffaddr##.

===== Comments:
* This does not allocate an RAM. You must supply the preallocated area.
* This can only be used on ANSI strings. It cannot be used for double-byte strings.
* If ##s## is not a string, nothing is stored and a zero is returned.

===== Returns:
An atom. If this is zero, then nothing was stored, otherwise it is the
address of the first byte after the stored string.

===== Example 1:
<eucode>
 atom title

title = allocate(1000)
if poke_string(title, 1000, "The Wizard of Oz") then
    -- successful
else
    -- failed
end if
</eucode>

===== See Also:
[[:Using Strings]], [[:allocate]], [[:allocate_string]]


@[:machine:poke_wstring|]
==== poke_wstring
<eucode>
include std/machine.e
namespace machine
public function poke_wstring(atom buffaddr, integer buffsize, sequence s)
</eucode>

  stores a C-style null-terminated Double-Byte string in memory.

===== Parameters:
# ##buffaddr##: an atom, the RAM address to to the string at.
# ##buffsize##: an integer, the number of bytes available, starting from ##buffaddr##.
# ##s## : a sequence, the string to store at address ##buffaddr##.

===== Comments:
* This does not allocate an RAM. You must supply the preallocated area.
* This uses two bytes per string character. **Note** that ##buffsize##
is the number of //bytes// available in the buffer and not the number
of //characters// available.
* If ##s## is not a double-byte string, nothing is stored and a zero is returned.

===== Returns:
An atom. If this is zero, then nothing was stored, otherwise it is the
address of the first byte after the stored string.

===== Example 1:
<eucode>
 atom title

title = allocate(1000)
if poke_wstring(title, 1000, "The Wizard of Oz") then
    -- successful
else
    -- failed
end if
</eucode>

===== See Also:
[[:Using Strings]], [[:allocate]], [[:allocate_wstring]]


=== Memory Manipulation


@[:eu:mem_copy|]
==== mem_copy
<eucode>
<built-in> procedure mem_copy(atom destination, atom origin, integer len)
</eucode>

copies a block of memory from an address to another.

===== Parameters:
# ##destination## : an atom, the address at which data is to be copied
# ##origin## : an atom, the address from which data is to be copied
# ##len## : an integer, how many bytes are to be copied.

===== Comments:

The bytes of memory will be copied correctly even if the block of memory
at ##destination## overlaps with the block of memory at ##origin##.

mem_copy(destination, origin, len) is equivalent to: poke(destination,
peek({origin, len})) but is much faster.

===== Example 1:
<eucode>
dest = allocate(50)
src = allocate(100)
poke(src, {1,2,3,4,5,6,7,8,9})
mem_copy(dest, src, 9)
</eucode>

===== See Also:
[[:Using Data Bytes]], [[:mem_set]], [[:peek]], [[:poke]], [[:allocate]], [[:free]]



@[:eu:mem_set|]
==== mem_set
<eucode>
<built-in> procedure mem_set(atom destination, integer byte_value, integer how_many))
</eucode>

sets a contiguous range of memory locations to a single value.

===== Parameters:
# ##destination## : an atom, the address starting the range to set.
# ##byte_value## : an integer, the value to copy at all addresses in the range.
# ##how_many## : an integer, how many bytes are to be set.

===== Comments:

The low order 8 bits of ##byte_value## are actually stored in each byte.
mem_set(destination, byte_value, how_many) is equivalent to:
poke(destination, repeat(byte_value, how_many)) but is much faster.

===== Example 1:
<eucode>
destination = allocate(1000)
mem_set(destination, ' ', 1000)
-- 1000 consecutive bytes in memory will be set to 32
-- (the ASCII code for ' ')
</eucode>

===== See Also:
[[:Using Data Bytes]], [[:peek]], [[:poke]], [[:allocate]], [[:free]], [[:mem_copy]]



=== Calling Into Memory


@[:eu:call|]
==== call
<eucode>
<built-in> procedure call(atom addr)
</eucode>

calls a machine language routine which was stored in memory prior.

===== Parameters:
# ##addr## : an atom, the address at which to transfer execution control.

===== Comments:

The machine code routine must execute a RET instruction #C3 to return
control to Euphoria.
The routine should save and restore any registers that it uses.

You can allocate a block of memory for the routine and then poke in the
bytes of machine code using ##allocate_code##. You might allocate other blocks of memory for data
and parameters that the machine code can operate on using ##allocate##. The addresses of these
blocks could be part of the machine code.

If your machine code uses the stack, use ##c_proc## instead of ##call##.

===== Example 1:
##demo/callmach.ex##

===== See Also:
[[:Executable Memory]], [[:allocate_code]], [[:free_code]], [[:c_proc]], [[:define_c_proc]]


=== Allocating and Writing to memory:


@[:machine:allocate_code|]
==== allocate_code
<eucode>
include std/machine.e
namespace machine
public function allocate_code(object data, memconst :valid_wordsize wordsize = 1)
</eucode>

  allocates and copies data into executable memory.

===== Parameters:
# ##a_sequence_of_machine_code## : is the machine code to
be put into memory to be later called with [[:call]]
# the ##word length## : of the said code.  You can specify your
code as 1-byte, 2-byte or 4-byte chunks if you wish.  If your machine code is byte
code specify 1.  The default is 1.

===== Returns:
An **address**,
The function returns the address in memory of the code, that can be
safely executed whether DEP is enabled or not or 0 if it fails.  On the
other hand, if you try to execute a code address returned by [[:allocate]]
with DEP enabled the program will receive a machine exception.

===== Comments:

Use this for the machine code you want to run in memory.  The copying is
done for you and when the routine returns the memory may not be readable
or writeable but it is guaranteed to be executable.  If you want to also
write to this memory **after the machine code has been copied** you should
use [[:allocate_protect]] instead and you should read about having memory
executable and writeable at the same time is a bad idea.  You mustn't use
##free## on memory returned from this function.  You may instead
use ##free_code## but since you will probably need the code throughout
the life of your program's process this normally is not necessary.
If you want to put only data in the memory to be read and written use [[:allocate]].

===== See Also:
[[:Executable Memory]], [[:allocate]], [[:free_code]], [[:allocate_protect]]


@[:machine:allocate_string|]
==== allocate_string
<eucode>
include std/machine.e
namespace machine
public function allocate_string(sequence s, types :boolean cleanup = 0)
</eucode>

  Allocate a C-style null-terminated string in memory

===== Parameters:
# ##s## : a sequence, the string to store in RAM.
# ##cleanup## : an integer, if non-zero, then the returned pointer will be
automatically freed when its reference count drops to zero, or
when passed as a parameter to [[:delete]].

===== Returns:
An **atom**, the address of the memory block where the string was
stored, or 0 on failure.

===== Comments:
Only the 8 lowest bits of each atom in ##s## is stored. Use
##allocate_wstring##  for storing double byte encoded strings.

There is no ##allocate_string_low## function. However, you could easily
craft one by adapting the code for ##allocate_string##.

Since ##allocate_string## allocates memory, you are responsible to
[[:free]] the block when done with it if ##cleanup## is zero.
If ##cleanup## is non-zero, then the memory can be freed by calling
[[:delete]], or when the pointer's reference count drops to zero.

===== Example 1:
<eucode>
 atom title

title = allocate_string("The Wizard of Oz")
</eucode>

===== See Also:
[[:Using Strings]], [[:allocate]], [[:allocate_wstring]]


@[:machine:allocate_protect|]
==== allocate_protect
<eucode>
include std/machine.e
namespace machine
public function allocate_protect(object data, memconst :valid_wordsize wordsize = 1,
        valid_memory_protection_constant protection)
</eucode>

  Allocates and copies data into memory and gives it protection using
[[:Standard Library Memory Protection Constants]] or
[[:Microsoft Windows Memory Protection Constants]].  The user may only pass in one of these
constants.  If you only wish to execute a sequence as machine code use ##allocate_code##.
If you only want to read and write data into memory use ##allocate##.

See [[http://msdn.microsoft.com/en-us/library/aa366786(VS.85).aspx "MSDN: Microsoft's Memory Protection Constants"]]

===== Parameters:
# ##data## : is the machine code to be put into memory.
# ##wordsize## : is the size each element of data will take in
memory.  Are they 1-byte, 2-bytes, 4-bytes or 8-bytes long?  Specify here.  The default is 1.
# ##protection## : is the particular //Windows// protection.

===== Returns:
An **address**,
The function returns the address to the required memory
or 0 if it fails.  This function is guaranteed to return memory on
the 8 byte boundary.  It also guarantees that the memory returned with
at least the protection given (but you may get more).

If you want to call ##allocate_protect( data, PAGE_READWRITE )##, you can use
[[:allocate]] instead.  It is more efficient and simpler.

If you want to call ##allocate_protect( data, PAGE_EXECUTE )##, you can use
[[:allocate_code]] instead.  It is simpler.

You must not use [[:free]] on memory returned from this function, instead use [[:free_code]].

===== See Also:
[[:Executable Memory]]


=== Memory Disposal


@[:machine:free|]
==== free
<eucode>
include std/machine.e
namespace machine
public procedure free(object addr)
</eucode>

  frees up a previously allocated block of memory.

===== Parameters:
# ##addr##, either a single atom or a sequence of atoms; these are addresses of a blocks to free.

===== Comments:
* Use ##free## to return blocks of memory the during execution. This will reduce the chance of
running out of memory or getting into excessive virtual memory swapping to disk.
* Do not reference a block of memory that has been freed.
* When your program terminates, all allocated memory will be returned to the system.
* ##addr## must have been allocated previously using [[:allocate]]. You
cannot use it to relinquish part of a block. Instead, you have to allocate
a block of the new size, copy useful contents from old block there and
then ##free## the old block.
* If the memory was allocated and automatic cleanup
was specified, then do not call ##free## directly.  Instead, use [[:delete]].
* An ##addr## of zero is simply ignored.

===== Example 1:
##demo/callmach.ex##

===== See Also:
[[:Using Data Bytes]], [[:Using Data Words]], [[:Using Data Double Words]], [[:Using Strings]], [[:allocate_data]], [[:free_code]]



==== free_code
<eucode>
include std/machine.e
public procedure free_code( atom addr, integer size, valid_wordsize wordsize = 1 )
</eucode>

frees up allocated code memory.

===== Parameters:
# ##addr## : must be an address returned by [[:allocate_code]] or [[:allocate_protect]].  Do **not** pass memory returned from [[:allocate]] here!
# ##size## : is the length of the sequence passed to ##alllocate_code## or the size you specified when you called ##allocate_protect##.
# ##wordsize##: valid_wordsize  default = 1

===== Comments:
Chances are you will not need to call this function because code allocations are typically public scope operations that you want to have available until your process exits.

See Also: [[:Executable Memory]], [[:allocate_code]], [[:free]]


=== Automatic Resource Management

Euphoria objects are automatically garbage collected when they are no
longer referenced anywhere.  Euphoria also provides the ability to manage
resources associated with euphoria objects.  These resources could be open file
handles, allocated memory, or other euphoria objects.  There are two built-in
routines for managing these external resources.


@[:eu:delete_routine|]
==== delete_routine
<eucode>
<built-in> function delete_routine( object x, integer rid )
</eucode>

associates a routine for cleaning up after a Euphoria object.

===== Comments:
##delete_routine## associates a euphoria object with a routine id meant
to clean up any allocated resources.  It always returns an atom
(double) or a sequence, depending on what was passed (integers are
promoted to atoms).

The routine specified by ##delete_routine## should be a procedure that
takes a single parameter, being the object to be cleaned up after.
Objects are cleaned up under one of two circumstances.  The first is
if it's called as a parameter to ##delete##.  After the call, the
association with the delete routine is removed.

The second way for the delete routine to be called is when its
reference count is reduced to 0.  Before its memory is freed, the
delete routine is called. A default delete will be used if the cleanup
parameter to one of the [[:allocate]] routines is true.

##delete_routine## may be called multiple times for the same object.
In this case, the routines are called in reverse order compared to
how they were associated.


@[:eu:delete|]
==== delete
<eucode>
<built-in> procedure delete( object x )
</eucode>

calls the cleanup routines associated with the object, and removes the
association with those routines.

===== Comments:
The cleanup routines associated with the object are called in reverse
order than they were added.  If the object is an integer, or if no
cleanup routines are associated with the object, then nothing happens.

After the cleanup routines are called, the value of the object is
unchanged, though the cleanup routine will no longer be associated
with the object.


=== Types and Constants


@[:machine:std_library_address|]
==== std_library_address
<eucode>
include std/machine.e
namespace machine
public type std_library_address(object addr)
</eucode>

  an address returned from ##allocate## or ##allocate_protect##
or ##allocate_code## or the value 0.

===== Returns:
An **integer**,
The type will return 1 if the parameter, an address, was returned
from one of these Machine Level functions (and has not yet been freeed)

===== Comments:
This type is equivalent to atom unless SAFE is defined.
Only values that satisfy this type may be passed into
free or free_code.



==== valid_memory_protection_constant
<eucode>
include std/machine.e
public type valid_memory_protection_constant(object a)
</eucode>
protection constants type


==== machine_addr
<eucode>
include std/machine.e
public type machine_addr(object a)
</eucode>

a 32-bit non-null machine address


==== safe_address
<eucode>
include std/machine.e
public function safe_address(machine_addr start, natural len, 
              positive_int action )
</eucode>

action is some bitwise-or combination of the following constants:
A_READ, A_WRITE and A_EXECUTE.

===== Returns:
When [[:Safe Mode]] is turned on, this
returns true iff it is ok to perform action all addresses from start to start+len-1.

When [[:Safe Mode]] is not turned on, this always returns true.

===== Comments:
This is used mostly inside the safe library itself to check whenever
you call Machine Level Access Functions or Procedures.  It should only be used
for debugging purposes.



==== ADDRESS_LENGTH
<eucode>
include std/machine.e
namespace machine
public constant ADDRESS_LENGTH
</eucode>
The number of bytes required to hold a pointer.


==== PAGE_SIZE
<eucode>
include std/machine.e
namespace machine
public constant PAGE_SIZE
</eucode>
The operating system's memory page length in bytes.


== Indirect Routine Calling

<<LEVELTOC level=2 depth=4>>



@[dyncall|]
=== Accessing Euphoria coded routines



@[:eu:routine_id|]
==== routine_id
<eucode>
<built-in> function routine_id(sequence routine_name)
</eucode>

returns an integer id number for a user-defined Euphoria procedure or function.

===== Parameters:
# ##routine_name## : a string, the name of the procedure or function.

===== Returns:
An **integer**, known as a routine id, -1  if the named routine can't be found, else zero or more.

===== Errors:
##routine_name## should not exceed 1,024 characters.

===== Comments:
The id number can be passed to [[:call_proc]] or [[:call_func]], to indirectly call
the routine named by ##routine_name##. This id depends on the internal process of
parsing your code, not on ##routine_name##.

The routine named ##routine_name## must be visible (that is callable) at the place where
##routine_id## is used to get the id number. If it is not, -1 is returned.

Indirect calls to the routine can appear earlier in the program than the definition of the routine,
but the id number can only be obtained in code that comes after the definition
of the routine - see example 2 below.

Once obtained, a valid routine id can be used at any place in the program to call
a routine indirectly via [[:call_proc]] or [[:call_func]], including at places where
the routine is no longer in scope.

Some typical uses of ##routine_id## are:

# Creating a subroutine that takes another routine as a parameter. (See Example 2 below)
# Using a sequence of routine id's to make a case (switch) statement. Using the
[[:switch statement]] is more efficient.
# Setting up an Object-Oriented system.
# Getting a routine id so you can pass it to [[:call_back]]. (See [[:Platform-Specific Issues]])
# Getting a routine id so you can pass it to [[:task_create]]. (See [[:Multitasking in Euphoria]])
# Calling a routine that is defined later in a program. This is no longer needed from v4.0 onward.

Note that C routines, callable by Euphoria, also have ids, but they cannot be used where
routine ids are, because of the different type checking and other technical issues.

===== See Also:
[[:define_c_proc]] and [[:define_c_func]]

===== Example 1:
<eucode>
 procedure foo()
    puts(1, "Hello World\n")
end procedure

integer foo_num
foo_num = routine_id("foo")

call_proc(foo_num, {})  -- same as calling foo()
</eucode>

===== Example 2:
<eucode>
function apply_to_all(sequence s, integer f)
    -- apply a function to all elements of a sequence
    sequence result
    result = {}
    for i = 1 to length(s) do
        -- we can call add1() here although it comes later in the program
        result = append(result, call_func(f, {s[i]}))
    end for
    return result
end function

function add1(atom x)
    return x + 1
end function

-- add1() is visible here, so we can ask for its routine id
? apply_to_all({1, 2, 3}, routine_id("add1"))
-- displays {2,3,4}
</eucode>

===== See Also:
[[:call_proc]], [[:call_func]], [[:call_back]], [[:define_c_func]], [[:define_c_proc]],
[[:task_create]], [[:Platform-Specific Issues]], [[:Indirect routine calling]]


@[:eu:call_func|]
==== call_func
<eucode>
<built-in> function call_func(integer id, sequence args={})
</eucode>

calls the user-defined Euphoria function by routine id.

===== Parameters:
# ##id## : an integer, the routine id of the function to call
# ##args## : a sequence, the parameters to pass to the function.

===== Returns:
The **value**, the called function returns.

===== Errors:
If ##id## is negative or otherwise unknown, an error occurs.

If the length of ##args## is not the number of parameters the function takes, an error occurs.

===== Comments:
##id## must be a valid routine id returned by [[:routine_id]].

##args## must be a sequence of argument values of length n, where n is the number of
arguments required by the called function. Defaulted parameters currently cannot be
synthesized while making a indirect call.

If the function with id ##id## does not take any arguments then ##args## should be ##{}##.

===== Example 1:
Take a look at the sample program called ##demo/csort.ex##

===== See Also:
[[:call_proc]], [[:routine_id]], [[:c_func]]



@[:eu:call_proc|]
==== call_proc
<eucode>
<built-in> procedure call_proc(integer id, sequence args={})
</eucode>

calls a user-defined Euphoria procedure by routine id.

===== Parameters:
# ##id## : an integer, the routine id of the procedure to call
# ##args## : a sequence, the parameters to pass to the function.

===== Errors:
If ##id## is negative or otherwise unknown, an error occurs.

If the length of ##args## is not the number of parameters the function takes, an error occurs.

===== Comments:
##id## must be a valid routine id returned by [[:routine_id]].

##args## must be a sequence of argument values of length n, where n is the number of
arguments required by the called procedure. Defaulted parameters currently cannot be
synthesized while making a indirect call.

If the procedure with id ##id## does not take any arguments then ##args## should be ##{}##.

===== Example 1:
<eucode>
public integer foo_id

procedure x()
    call_proc(foo_id, {1, "Hello World\n"})
end procedure

procedure foo(integer a, sequence s)
    puts(a, s)
end procedure

foo_id = routine_id("foo")

x()
</eucode>

===== See Also:
[[:call_func]], [[:routine_id]], [[:c_proc]]


=== Accessing Euphoria Internals


@[:eu:machine_func|]
==== machine_func
<eucode>
<built-in> function machine_func(integer machine_id, object args={})
</eucode>

performs a machine-specific operation that returns a value.

===== Returns:
Depends on the called internal facility.

===== Comments:
This function us mainly used by the standard library files to implement machine dependent
operations such as graphics and sound effects. This routine should normally be called
indirectly via one of the library routines in a Euphoria include file.
User programs normally do not need to call ##machine_func##.

A direct call might cause a machine exception if done incorrectly.

===== See Also:
[[:machine_proc]]


@[:eu:machine_proc|]
==== machine_proc
<eucode>
<built-in> procedure machine_proc(integer machine_id, object args={})
</eucode>

perform a machine-specific operation that does not return a value.

===== Comments:
This procedure us mainly used by the standard library files to implement machine dependent
operations such as graphics and sound effects. This routine should normally be called
indirectly via one of the library routines in a Euphoria include file.
User programs normally do not need to call ##machine_proc##.

A direct call might cause a machine exception if done incorrectly.

===== See Also:
[[:machine_func]]



!!CONTEXT:../include/std/memconst.e
!!namespace:memconst
%%output = std_memconst

== Memory Constants

<<LEVELTOC level=2 depth=4>>



=== Microsoft Windows Memory Protection Constants === @[microsoftsmemoryprotectionconstants]
These constant names are taken right from Microsoft's Memory Protection constants.


@[:memconst:PAGE_EXECUTE|]
==== PAGE_EXECUTE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_EXECUTE
</eucode>

  You may run the data in this page


@[:memconst:PAGE_EXECUTE_READ|]
==== PAGE_EXECUTE_READ
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_EXECUTE_READ
</eucode>

  You may read or run the data


@[:memconst:PAGE_EXECUTE_READWRITE|]
==== PAGE_EXECUTE_READWRITE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_EXECUTE_READWRITE
</eucode>

  You may run, read or write in this page


@[:memconst:PAGE_EXECUTE_WRITECOPY|]
==== PAGE_EXECUTE_WRITECOPY
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_EXECUTE_WRITECOPY
</eucode>

  You may run or write in this page


@[:memconst:PAGE_WRITECOPY|]
==== PAGE_WRITECOPY
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_WRITECOPY
</eucode>

  You may write to this page.


@[:memconst:PAGE_READWRITE|]
==== PAGE_READWRITE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READWRITE
</eucode>

  You may read or write in this page.


@[:memconst:PAGE_READONLY|]
==== PAGE_READONLY
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READONLY
</eucode>

  You may only read data in this page


@[:memconst:PAGE_NOACCESS|]
==== PAGE_NOACCESS
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_NOACCESS
</eucode>

  You have no access to this page








=== Standard Library Memory Protection Constants === @[stardardlibrarymemoryprotectionconstants]


Memory Protection Constants are the same constants names and meaning
across all platforms yet possibly of different numeric value.
They are only necessary for [[:allocate_protect]]

The constant names are created like this:  You have four aspects of protection
READ, WRITE, EXECUTE and COPY.
You take the word PAGE and you concatonate an underscore and the aspect
in the order above.  For example: PAGE_WRITE_EXECUTE
The sole exception to this nomenclature is when you will have no acesss to the page the
constant is called PAGE_NONE.


@[:memconst:PAGE_NONE|]
==== PAGE_NONE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_NONE
</eucode>

  You have no access to this page.


@[:memconst:PAGE_READ_EXECUTE|]
==== PAGE_READ_EXECUTE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READ_EXECUTE
</eucode>

  You may read or run the data
An alias to PAGE_EXECUTE_READ


@[:memconst:PAGE_READ_WRITE|]
==== PAGE_READ_WRITE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READ_WRITE
</eucode>

  You may read or write to this page
An alias to PAGE_READWRITE


@[:memconst:PAGE_READ|]
==== PAGE_READ
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READ
</eucode>

  You may only read to this page
An alias to PAGE_READONLY


@[:memconst:PAGE_READ_WRITE_EXECUTE|]
==== PAGE_READ_WRITE_EXECUTE
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_READ_WRITE_EXECUTE
</eucode>

  You may run, read or write in this page
An alias to PAGE_EXECUTE_READWRITE


@[:memconst:PAGE_WRITE_EXECUTE_COPY|]
==== PAGE_WRITE_EXECUTE_COPY
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_WRITE_EXECUTE_COPY
</eucode>

  You may run or write to this page.  Data
will copied for use with other processes when
you first write to it.


@[:memconst:PAGE_WRITE_COPY|]
==== PAGE_WRITE_COPY
<eucode>
include std/memconst.e
namespace memconst
public constant PAGE_WRITE_COPY
</eucode>

  You may write to this page.  Data
will copied for use with other processes when
you first write to it.



!!CONTEXT:../include/std/graphcst.e
!!namespace:graphcst
%%output = std_graphcst

== Graphics Constants

<<LEVELTOC level=2 depth=4>>



=== Error Code Constants



@[:graphcst:BMP_SUCCESS|]
==== BMP_SUCCESS
<eucode>
include std/graphcst.e
namespace graphcst
public enum BMP_SUCCESS
</eucode>





@[:graphcst:BMP_OPEN_FAILED|]
==== BMP_OPEN_FAILED
<eucode>
include std/graphcst.e
namespace graphcst
public enum BMP_OPEN_FAILED
</eucode>





@[:graphcst:BMP_UNEXPECTED_EOF|]
==== BMP_UNEXPECTED_EOF
<eucode>
include std/graphcst.e
namespace graphcst
public enum BMP_UNEXPECTED_EOF
</eucode>





@[:graphcst:BMP_UNSUPPORTED_FORMAT|]
==== BMP_UNSUPPORTED_FORMAT
<eucode>
include std/graphcst.e
namespace graphcst
public enum BMP_UNSUPPORTED_FORMAT
</eucode>





@[:graphcst:BMP_INVALID_MODE|]
==== BMP_INVALID_MODE
<eucode>
include std/graphcst.e
namespace graphcst
public enum BMP_INVALID_MODE
</eucode>





=== video_config Sequence Accessors


@[:graphcst:VC_COLOR|]
==== VC_COLOR
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_COLOR
</eucode>





@[:graphcst:VC_MODE|]
==== VC_MODE
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_MODE
</eucode>





@[:graphcst:VC_LINES|]
==== VC_LINES
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_LINES
</eucode>





@[:graphcst:VC_COLUMNS|]
==== VC_COLUMNS
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_COLUMNS
</eucode>





@[:graphcst:VC_XPIXELS|]
==== VC_XPIXELS
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_XPIXELS
</eucode>





@[:graphcst:VC_YPIXELS|]
==== VC_YPIXELS
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_YPIXELS
</eucode>





@[:graphcst:VC_NCOLORS|]
==== VC_NCOLORS
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_NCOLORS
</eucode>





@[:graphcst:VC_PAGES|]
==== VC_PAGES
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_PAGES
</eucode>





@[:graphcst:VC_SCRNLINES|]
==== VC_SCRNLINES
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_SCRNLINES
</eucode>





@[:graphcst:VC_SCRNCOLS|]
==== VC_SCRNCOLS
<eucode>
include std/graphcst.e
namespace graphcst
public enum VC_SCRNCOLS
</eucode>







==== Colors



@[:graphcst:BLACK|]
==== BLACK
<eucode>
include std/graphcst.e
namespace graphcst
public constant BLACK
</eucode>





@[:graphcst:BLUE|]
==== BLUE
<eucode>
include std/graphcst.e
namespace graphcst
public constant BLUE
</eucode>





@[:graphcst:GREEN|]
==== GREEN
<eucode>
include std/graphcst.e
namespace graphcst
public constant GREEN
</eucode>





@[:graphcst:CYAN|]
==== CYAN
<eucode>
include std/graphcst.e
namespace graphcst
public constant CYAN
</eucode>





@[:graphcst:RED|]
==== RED
<eucode>
include std/graphcst.e
namespace graphcst
public constant RED
</eucode>





@[:graphcst:MAGENTA|]
==== MAGENTA
<eucode>
include std/graphcst.e
namespace graphcst
public constant MAGENTA
</eucode>





@[:graphcst:BROWN|]
==== BROWN
<eucode>
include std/graphcst.e
namespace graphcst
public constant BROWN
</eucode>





@[:graphcst:WHITE|]
==== WHITE
<eucode>
include std/graphcst.e
namespace graphcst
public constant WHITE
</eucode>





@[:graphcst:GRAY|]
==== GRAY
<eucode>
include std/graphcst.e
namespace graphcst
public constant GRAY
</eucode>





@[:graphcst:BRIGHT_BLUE|]
==== BRIGHT_BLUE
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_BLUE
</eucode>





@[:graphcst:BRIGHT_GREEN|]
==== BRIGHT_GREEN
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_GREEN
</eucode>





@[:graphcst:BRIGHT_CYAN|]
==== BRIGHT_CYAN
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_CYAN
</eucode>





@[:graphcst:BRIGHT_RED|]
==== BRIGHT_RED
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_RED
</eucode>





@[:graphcst:BRIGHT_MAGENTA|]
==== BRIGHT_MAGENTA
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_MAGENTA
</eucode>





@[:graphcst:YELLOW|]
==== YELLOW
<eucode>
include std/graphcst.e
namespace graphcst
public constant YELLOW
</eucode>





@[:graphcst:BRIGHT_WHITE|]
==== BRIGHT_WHITE
<eucode>
include std/graphcst.e
namespace graphcst
public constant BRIGHT_WHITE
</eucode>





@[:graphcst:true_fgcolor|]
==== true_fgcolor
<eucode>
include std/graphcst.e
namespace graphcst
export sequence true_fgcolor
</eucode>





@[:graphcst:true_bgcolor|]
==== true_bgcolor
<eucode>
include std/graphcst.e
namespace graphcst
export sequence true_bgcolor
</eucode>













@[:graphcst:BLINKING|]
==== BLINKING
<eucode>
include std/graphcst.e
namespace graphcst
public constant BLINKING
</eucode>

  Add to color number to get blinking text.


@[:graphcst:BYTES_PER_CHAR|]
==== BYTES_PER_CHAR
<eucode>
include std/graphcst.e
namespace graphcst
public constant BYTES_PER_CHAR
</eucode>





@[:graphcst:color|]
==== color
<eucode>
include std/graphcst.e
namespace graphcst
public type color(object x)
</eucode>



=== Routines


@[:graphcst:mixture|]
==== mixture
<eucode>
include std/graphcst.e
namespace graphcst
public type mixture(object s)
</eucode>

  Mixture Type

===== Comments:

A mixture is a ##{red, green, blue}## triple of intensities, which enables you to define
custom colors. Intensities must be from 0 (weakest) to 63 (strongest). Thus, the brightest
white is ##{63, 63, 63}##.


@[:graphcst:video_config|]
==== video_config
<eucode>
include std/graphcst.e
namespace graphcst
public function video_config()
</eucode>

  returns a description of the current video configuration.

===== Returns:
A **sequence**, of 10 non-negative integers, laid out as follows:
# color monitor? ~-- 0 if monochrome, 1 otherwise
# current video mode
# number of text rows in console buffer
# number of text columns in console buffer
# screen width in pixels
# screen height in pixels
# number of colors
# number of display pages
# number of text rows for current screen size
# number of text columns for current screen size

===== Comments:

A public enum is available for convenient access to the returned configuration data~:
* ##VC_COLOR##
* ##VC_MODE##
* ##VC_LINES##
* ##VC_COLUMNS##
* ##VC_XPIXELS##
* ##VC_YPIXELS##
* ##VC_NCOLORS##
* ##VC_PAGES##
* ##VC_SCRNLINES##
* ##VC_SCRNCOLS##

This routine makes it easy for you to parameterize a program so it will work in many
different graphics modes.

===== Example 1:
<eucode>
vc = video_config()
-- vc could be {1, 3, 300, 132, 0, 0, 32, 8, 37, 90}
</eucode>

===== See Also:
[[:graphics_mode]]


=== Color Set Selection



@[:graphcst:FGSET|]
==== FGSET
<eucode>
include std/graphcst.e
namespace graphcst
public enum FGSET
</eucode>

 Foreground ( text) set of colors




@[:graphcst:BGSET|]
==== BGSET
<eucode>
include std/graphcst.e
namespace graphcst
public enum BGSET
</eucode>

Background set of colors





!!CONTEXT:../include/std/graphics.e
!!namespace:graphics
%%output = std_graphics

== Graphics - Cross Platform

<<LEVELTOC level=2 depth=4>>



=== Routines



@[:eu:position|]
==== position
<eucode>
<built-in> procedure position(integer row, integer column)
</eucode>

===== Parameters:
# ##row## : an integer, the index of the row to position the cursor on.
# ##column## : an integer, the index of the column to position the cursor on.

sets the cursor to where the next character will be output.

===== Comments:
Set the cursor to line ##row##, column ##column##, where the top left corner of the screen is line 1,
column 1. The next character displayed on the screen will be printed at this location.
##position## will report an error if the location is off the screen.
The //Windows// console does not check for rows, as the physical height of the
console may be vastly less than its logical height.

===== Example 1:
<eucode>
position(2,1)
-- the cursor moves to the beginning of the second line from the top
</eucode>
===== See Also:
[[:get_position]]


@[:graphics:get_position|]
==== get_position
<eucode>
include std/graphics.e
namespace graphics
public function get_position()
</eucode>

  returns the current line and column position of the cursor.

===== Returns:
A **sequence**, ##{line, column}##, the current position of the text mode cursor.

===== Comments:
The coordinate system for displaying text is different from the one for displaying pixels.
Pixels are displayed such that the top-left is ##(x=0,y=0)## and the first coordinate controls
the horizontal, left-right location. In pixel-graphics modes you can display both text and
pixels. ##get_position## returns the current line and column for the text that you are
displaying, not the pixels that you may be plotting. There is no corresponding routine for
getting the current pixel position, because there is no such thing.

===== See Also:
[[:position]]


@[:graphics:text_color|]
==== text_color
<eucode>
include std/graphics.e
namespace graphics
public procedure text_color(color c)
</eucode>

  sets the foreground text color.

===== Parameters:
# ##c## : the new text color. Add ##BLINKING## to get blinking text in some modes.

===== Comments:
Text that you print after calling ##[[:text_color]]## will have the desired color.

When your program terminates, the last color that you selected and actually printed on the
screen will remain in effect. Thus you may have to print something, maybe just ##'\n'##,
in ##WHITE## to restore white text, especially if you are at the bottom line of the
screen, ready to scroll up.

===== Example 1:
<eucode>
text_color(BRIGHT_BLUE)
</eucode>

===== See Also:
[[:bk_color]] , [[:clear_screen]]


@[:graphics:bk_color|]
==== bk_color
<eucode>
include std/graphics.e
namespace graphics
public procedure bk_color(color c)
</eucode>

  sets the background color to one of the sixteen standard colors.

===== Parameters:
# ##c## : the new text color. Add ##BLINKING## to get blinking text in some modes.

===== Comments:
To restore the original background color when your program finishes,
( often ##0 - BLACK##), you must call ##[[:bk_color]](0)##. If the cursor is at the bottom
line of the screen, you may have to actually print something before terminating your
program; printing ##'\n'## may be enough.

===== Example 1:
<eucode>
bk_color(BLACK)
</eucode>

===== See Also:
[[:text_color]]


@[:graphics:console_colors|]
==== console_colors
<eucode>
include std/graphics.e
namespace graphics
public function console_colors(sequence colorset = {})
</eucode>

  sets the codes for the colors used in ##text_color## and ##bk_color##.

===== Parameters:
# ##colorset## : A sequence in one of two formats.
## Containing two sets of exactly sixteen color numbers in which the first set
are foreground (text) colors and the other set are background colors.
## Containing a set of exactly sixteen color numbers. These are to be
applied to both foreground and background.

===== Returns:
A sequence: This contains two sets of sixteen color values currently in
use for foreground and background respectively.

===== Comments:
* If the ##colorset## is omitted then this just returns the current values without
changing anything.
* A color set contains sixteen values. You can access the color value for a specific color
by using ##[X + 1]## where ##'X'## is one of the Euphoria color constants such as ##RED## or
##BLUE##.
* This can be used to change the meaning of the standard color codes for
some consoles that are not using standard values. For example, the //Unix// default
color value for RED is 1 and BLUE is 4, but you might need this to swapped. See
code Example 1. Another use might be to suppress highlighted (bold) colors. See
code Example 2.

===== Example 1:
<eucode>
sequence cs
cs = console_colors() -- Get the current FG and BG color values.
cs[FGSET][RED + 1] = 4 -- set RED to 4
cs[FGSET][BLUE + 1] = 1 -- set BLUE to 1
cs[BGSET][RED + 1] = 4 -- set RED to 4
cs[BGSET][BLUE + 1] = 1 -- set BLUE to 1
console_colors(cs)
</eucode>

===== Example 2:
<eucode>
-- Prevent highlighted background colors
sequence cs
cs = console_colors()
for i = GRAY + 1 to BRIGHT_WHITE + 1 do
   cs[BGSET][i] = cs[BGSET][i - 8]
end for
console_colors(cs)
</eucode>

===== See Also:
[[:text_color]] [[:bk_color]]


@[:graphics:wrap|]
==== wrap
<eucode>
include std/graphics.e
namespace graphics
public procedure wrap(object on = 1)
</eucode>

  determines whether text will wrap when hitting the rightmost column.

===== Parameters:
# ##on## : an object, 0 to truncate text, anything else to wrap.

===== Comments:
By default text will wrap.

Use ##wrap## in text modes or pixel-graphics modes when you are displaying long
lines of text.

===== Example 1:
<eucode>
puts(1, repeat('x', 100) & "\n\n")
-- now have a line of 80 'x' followed a line of 20 more 'x'
wrap(0)
puts(1, repeat('x', 100) & "\n\n")
-- creates just one line of 80 'x'
</eucode>

===== See Also:
[[:puts]], [[:position]]


@[:graphics:scroll|]
==== scroll
<eucode>
include std/graphics.e
namespace graphics
public procedure scroll(integer amount, console :positive_int top_line,
        console :positive_int bottom_line)
</eucode>

  scrolls a region of text on the screen.

===== Parameters:
# ##amount## : an integer, the number of lines by which to scroll.
This is ##>0## to scroll up and ##<0## to scroll down.
# ##top_line## : the 1-based number of the topmost line to scroll.
# ##bottom_line## : the 1-based number of the bottom-most line to scroll.

===== Comments:
* New blank lines will appear at the vacated lines.
* You could perform the scrolling operation using a series of calls to ##[[:puts]]##,
but ##scroll## is much faster.
* The position of the cursor after scrolling is not defined.

===== Example 1:
##.../euphoria/bin/ed.ex##

===== See Also:
[[:clear_screen]], [[:text_rows]]


=== Graphics Modes


@[:graphics:graphics_mode|]
==== graphics_mode
<eucode>
include std/graphics.e
namespace graphics
public function graphics_mode(object m = - 1)
</eucode>

  attempts to set up a new graphics mode.

===== Parameters:
# ##x## : an object, but it will be ignored.

===== Returns:
An **integer**, always returns zero.

===== Platform:
//Windows//

===== Comments:
* This has no effect on //Unix// platforms.
* On //Windows// it causes a console to be shown if one has not already been created.
===== See Also:
[[:video_config]]



!!CONTEXT:../include/std/image.e
!!namespace:image
%%output = std_image

== Graphics - Image Routines

<<LEVELTOC level=2 depth=4>>



@[:image:graphics_point|]
==== graphics_point
<eucode>
include std/image.e
namespace image
public type graphics_point(object p)
</eucode>



=== Bitmap Handling



@[:image:read_bitmap|]
==== read_bitmap
<eucode>
include std/image.e
namespace image
public function read_bitmap(sequence file_name)
</eucode>

  reads a bitmap (##.BMP##) file into a 2-d sequence of sequences (image)

===== Parameters:
# ##file_name## : a sequence, the path to a ##.bmp## file to read from. The extension is not assumed if missing.

===== Returns:
An **object**, on success, a sequence of the form ##{palette,image}##. On failure, an error code is returned.

===== Comments:
In the returned value, the first element is a list of three membered sequences, each containing
three color intensity values in the range 0 to 255, and the second, a list of pixel rows. Each
pixel in a row is represented by its color index in the said first element of the return value.

The file should be in the bitmap format. The most common variations of the format are supported.

Bitmaps of 2, 4, 16 or 256 colors are supported. If the file is not in a good format, an error
code (atom) is returned instead

<eucode>
public constant
    BMP_OPEN_FAILED = 1,
    BMP_UNEXPECTED_EOF = 2,
    BMP_UNSUPPORTED_FORMAT = 3
</eucode>

You can create your own bitmap picture files using Windows Paintbrush and many other
graphics programs. You can then incorporate these pictures into your Euphoria programs.

===== Example 1:

<eucode>
x = read_bitmap("c:\\windows\\arcade.bmp")
</eucode>

===== See Also:
[[:save_bitmap]]


@[:image:save_bitmap|]
==== save_bitmap
<eucode>
include std/image.e
namespace image
public function save_bitmap(two_seq palette_n_image, sequence file_name)
</eucode>

  create a ##.BMP## bitmap file, given a palette and a 2-d sequence of sequences of colors.

===== Parameters:
# ##palette_n_image## : a ##{palette, image}## pair, like [[:read_bitmap]] returns
# ##file_name## : a sequence, the name of the file to save to.

===== Returns:
An **integer**, 0 on success.

===== Comments:
This routine does the opposite of [[:read_bitmap]]().
The first element of ##palette_n_image## is a list of sequences each sequence containing
exactly three color intensity values in the range 0 to 255. The second element is a list of
sequences of colors. The inner sequences must have the same length.  Each element in the
each inner sequence represents the color index in ##palette_n_image## of a pixel.  Each inner
sequence is a row in the image.

The result will be one of the following codes~:
<eucode>
public constant
    BMP_SUCCESS = 0,
    BMP_OPEN_FAILED = 1,
    BMP_INVALID_MODE = 4 -- invalid graphics mode
                         -- or invalid argument
</eucode>


##save_bitmap## produces bitmaps of 2, 4, 16, or 256 colors and these can all be read with
##read_bitmap##. Windows Paintbrush and some other tools do not support 4-color bitmaps.

===== Example 1:
<eucode>
code = save_bitmap({paletteData, imageData},
                   "c:\\example\\a1.bmp")
</eucode>

===== See Also:
[[:read_bitmap]]



!!CONTEXT:../include/euphoria/info.e
!!namespace:info
%%output = euphoria_info

== Euphoria Information

<<LEVELTOC level=2 depth=4>>


=== Build Type Constants



@[:info:is_developmental|]
==== is_developmental
<eucode>
include euphoria/info.e
namespace info
public constant is_developmental
</eucode>

  Is this build a developmental build?



@[:info:is_release|]
==== is_release
<eucode>
include euphoria/info.e
namespace info
public constant is_release
</eucode>

  Is this build a release build?



=== Numeric Version Information



=== Compiled Platform Information


@[:info:platform_name|]
==== platform_name
<eucode>
include euphoria/info.e
namespace info
public function platform_name()
</eucode>

  Get the platform name

===== Returns:
A **sequence**, containing the platform name, i.e. Windows, Linux, FreeBSD or OS X.



@[:info:arch_bits|]
==== arch_bits
<eucode>
include euphoria/info.e
namespace info
public function arch_bits()
</eucode>

  Get the native architecture word size.

===== Returns:
A **sequence** in the form of "%d-bit", where %d is the word size for the
architecture for which this version of euphoria was built.


@[:info:version|]
==== version
<eucode>
include euphoria/info.e
namespace info
public function version()
</eucode>

  Get the version, as an integer, of the host Euphoria

===== Returns:
An **integer**, representing Major, Minor and Patch versions. Version
4.0.0 will return 40000, 4.0.1 will return 40001,
5.6.2 will return 50602, 5.12.24 will return 512624, etc...



@[:info:version_major|]
==== version_major
<eucode>
include euphoria/info.e
namespace info
public function version_major()
</eucode>

  Get the major version of the host Euphoria

===== Returns:
An **integer**, representing the Major version number. Version 4.0.0 will
return 4, version 5.6.2 will return 5, etc...



@[:info:version_minor|]
==== version_minor
<eucode>
include euphoria/info.e
namespace info
public function version_minor()
</eucode>

  Get the minor version of the hosting Euphoria

===== Returns:
An **integer**, representing the Minor version number. Version 4.0.0
will return 0, 4.1.0 will return 1, 5.6.2 will return 6, etc...



@[:info:version_patch|]
==== version_patch
<eucode>
include euphoria/info.e
namespace info
public function version_patch()
</eucode>

  Get the patch version of the hosting Euphoria

===== Returns:
An **integer**, representing the Path version number. Version 4.0.0
will return 0, 4.0.1 will return 1, 5.6.2 will return 2, etc...



@[:info:version_node|]
==== version_node
<eucode>
include euphoria/info.e
namespace info
public function version_node(integer full = 0)
</eucode>

  Get the source code node id of the hosting Euphoria

===== Parameters:
* ##full## - If TRUE, the full node id is returned. If FALSE
only the first 12 characters of the node id is returned.
Typically the short node id is considered unique.

===== Returns:
A text **sequence**, containing the source code management systems
node id that globally identifies the executing Euphoria.



@[:info:version_revision|]
==== version_revision
<eucode>
include euphoria/info.e
namespace info
public function version_revision()
</eucode>

  Get the source code revision of the hosting Euphoria

===== Returns:
A text **sequence**, containing the source code management systems
revision number that the executing Euphoria was built from.



@[:info:version_date|]
==== version_date
<eucode>
include euphoria/info.e
namespace info
public function version_date(integer full = 0)
</eucode>

  Get the compilation date of the hosting Euphoria

===== Parameters:
* ##full## - Standard return value is a string formatted as ##CCYY-MM-DD##. However,
if this is a development build or the ##full## parameter is TRUE (1), then
the result will be formatted as ##CCYY-MM-DD HH:MM:SS##.

===== Returns:
A text **sequence** containing the commit date of the
the associated SCM revision.

The date/time is UTC.



=== String Version Information



@[:info:version_type|]
==== version_type
<eucode>
include euphoria/info.e
namespace info
public function version_type()
</eucode>

  Get the type version of the hosting Euphoria

===== Returns:
A **sequence**, representing the Type version string. Version 4.0.0 alpha 1
will return ##alpha 1##. 4.0.0 beta 2 will return ##beta 2##. 4.0.0 final,
or release, will return ##release##.



@[:info:version_string|]
==== version_string
<eucode>
include euphoria/info.e
namespace info
public function version_string(integer full = 0)
</eucode>

  Get a normal version string

===== Parameters:
# ##full## - Return full version information regardless of
developmental/production status.

===== Returns:
A **#sequence**, representing the entire version information in one string.
The amount of detail you get depends on if this version of Euphoria has
been compiled as a developmental version (more detailed version information)
or if you have indicated TRUE for the ##full## argument.

Example return values
* "4.0.0 alpha 3 (ab8e98ab3ce4,2010-11-18)"
* "4.0.0 release (8d8874dc9e0a, 2010-12-22)"
* "4.1.5 development (12332:e8d8787af7de, 2011-07-18 12:55:03)"



@[:info:version_string_short|]
==== version_string_short
<eucode>
include euphoria/info.e
namespace info
public function version_string_short()
</eucode>

  Get a short version string

===== Returns:
A **sequence**, representing the Major, Minor and Patch all in
one string.

===== Example return values:
* "4.0.0"
* "4.0.2"
* "5.6.2"



@[:info:version_string_long|]
==== version_string_long
<eucode>
include euphoria/info.e
namespace info
public function version_string_long(integer full = 0)
</eucode>

  Get a long version string

===== Parameters:
# ##full## - Return full version information regardless of
developmental/production status.

===== Returns:
A **#sequence**, representing the entire version information in one string.
The amount of detail you get depends on if this version of Euphoria has
been compiled as a developmental version (more detailed version information)
or if you have indicated TRUE for the ##full## argument.

Example return values
* "4.0.0 alpha 3 (ab8e98ab3ce4,2010-11-18) for Windows 32-bit"
* "4.0.0 release (8d8874dc9e0a, 2010-12-22) for Linux 32-bit"
* "4.1.5 development (12332:e8d8787af7de, 2011-07-18 12:55:03) for OS X 64-bit"



=== Copyright Information



@[:info:euphoria_copyright|]
==== euphoria_copyright
<eucode>
include euphoria/info.e
namespace info
public function euphoria_copyright()
</eucode>

  Get the copyright statement for Euphoria

===== Returns:
A **sequence**, containing 2 sequences: product name and copyright message

===== Example 1:
<eucode>
sequence info = euphoria_copyright()
-- info = {
--     "Euphoria v4.0.0 alpha 3",
--     "Copyright (c) XYZ, ABC\n" &
--     "Copyright (c) ABC, DEF"
-- }
</eucode>



@[:info:pcre_copyright|]
==== pcre_copyright
<eucode>
include euphoria/info.e
namespace info
public function pcre_copyright()
</eucode>

  Get the copyright statement for PCRE.

===== Returns:
A **sequence**, containing 2 sequences: product name and copyright message.

===== See Also:
[[:euphoria_copyright()]]



@[:info:all_copyrights|]
==== all_copyrights
<eucode>
include euphoria/info.e
namespace info
public function all_copyrights()
</eucode>

  Get all copyrights associated with this version of Euphoria.

===== Returns:
A **sequence**, of product names and copyright messages.
<eucode>
{
    { ProductName, CopyrightMessage },
    { ProductName, CopyrightMessage },
    ...
}
</eucode>



=== Timing Information



@[:info:start_time|]
==== start_time
<eucode>
include euphoria/info.e
namespace info
public function start_time()
</eucode>

  Euphoria start time.

This time represents the time Euphoria itself started. This
time is recorded before any of the users code is opened, parsed
or executed. It can provide accurate timing information as to
how long it takes for your application to go from start time
to usable time.

===== Returns:
An **atom** representing the start time of Euphoria itself



=== Configure Information



@[:eu:include_paths|]
==== include_paths
<eucode>
<built-in> function include_paths(integer convert)
</eucode>

Returns the list of include paths, in the order in which they are searched

===== Parameters:
# ##convert## : an integer, nonzero to include converted path entries
that were not validated yet.

===== Returns:
A **sequence**, of strings, each holding a fully qualified include path.

===== Comments:

##convert## is checked only under //Windows//. If a path has accented characters in it, then
it may or may not be valid to convert those to the OEM code page. Setting ##convert## to a nonzero value
will force conversion for path entries that have accents and which have not been checked to be valid yet.
The extra entries, if any, are returned at the end of the returned sequence.

===== The paths are ordered in the order they are searched:
# current directory
# configuration file,
# command line switches,
# EUINC
# a default based on EUDIR.

===== Example 1:
<eucode>
sequence s = include_paths(0)
-- s might contain
{
  "/usr/euphoria/tests",
  "/usr/euphoria/include",
  "./include",
  "../include"
}
</eucode>

===== See Also:
[[:eu.cfg]], [[:include]], [[:option_switches]]




!!CONTEXT:../include/euphoria/keywords.e
!!namespace:keywords
%%output = euphoria_keywords

== Keyword Data

Keywords and routines built in to Euphoria.

<<LEVELTOC level=2 depth=4>>



=== Constants



@[:keywords:keywords|]
==== keywords
<eucode>
include euphoria/keywords.e
namespace keywords
public constant keywords
</eucode>

  Sequence of Euphoria keywords


@[:keywords:builtins|]
==== builtins
<eucode>
include euphoria/keywords.e
namespace keywords
public constant builtins
</eucode>

  Sequence of Euphoria's built-in function names



!!CONTEXT:../include/euphoria/syncolor.e
!!namespace:syncolor
%%output = euphoria_syncolor

== Syntax Coloring

<<LEVELTOC level=2 depth=4>>

Syntax Color
Break Euphoria statements into words with multiple colors.
The editor and pretty printer (eprint.ex) both use this file.


=== Routines



@[:syncolor:set_colors|]
==== set_colors
<eucode>
include euphoria/syncolor.e
namespace syncolor
public procedure set_colors(sequence pColorList)
</eucode>



@[:syncolor:init_class|]
==== init_class
<eucode>
include euphoria/syncolor.e
namespace syncolor
public procedure init_class()
</eucode>



@[:syncolor:new|]
==== new
<eucode>
include euphoria/syncolor.e
namespace syncolor
public function new()
</eucode>

  Create a new colorizer state

===== See Also:
[[:reset]], [[:SyntaxColor]]



@[:syncolor:reset|]
==== reset
<eucode>
include euphoria/syncolor.e
namespace syncolor
public procedure reset(atom state = g_state)
</eucode>



@[:syncolor:keep_newlines|]
==== keep_newlines
<eucode>
include euphoria/syncolor.e
namespace syncolor
public procedure keep_newlines(integer val = 1, atom state = g_state)
</eucode>



@[:syncolor:SyntaxColor|]
==== SyntaxColor
<eucode>
include euphoria/syncolor.e
namespace syncolor
public function SyntaxColor(sequence pline, atom state = g_state, multiline_token multi = 0)
</eucode>

  Parse Euphoria code into tokens of like colors.

===== Parameters:
# ##pline## the source code to color
# ##state## (default g_state) the tokenizer to use
# ##multi## the multiline token from the previous line

Break up a new-line terminated line into colored text segments identifying the
various parts of the Euphoria language. They are broken into separate tokens.

===== Returns:
===== A sequence that looks like:
<eucode>
{color1, "text1"}, {color2, "text2"}, ... }
</eucode>

===== Comments:
In order to properly color multiline syntax (strings and comments), you should pass
a value for ##multi##. This value can be attained by calling ##[[:last_multiline_token]]##
after coloring the previous line.



!!CONTEXT:../include/euphoria/tokenize.e
!!namespace:tokenize
%%output = euphoria_tokenize

== Euphoria Source Tokenizer

<<LEVELTOC level=2 depth=4>>



=== tokenize return sequence key


@[:tokenize:ET_TOKENS|]
==== ET_TOKENS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ET_TOKENS
</eucode>





@[:tokenize:ET_ERROR|]
==== ET_ERROR
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ET_ERROR
</eucode>





@[:tokenize:ET_ERR_LINE|]
==== ET_ERR_LINE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ET_ERR_LINE
</eucode>





@[:tokenize:ET_ERR_COLUMN|]
==== ET_ERR_COLUMN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ET_ERR_COLUMN
</eucode>





=== Tokens


@[:tokenize:T_EOF|]
==== T_EOF
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_EOF
</eucode>





@[:tokenize:T_NULL|]
==== T_NULL
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_NULL
</eucode>





@[:tokenize:T_SHBANG|]
==== T_SHBANG
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_SHBANG
</eucode>





@[:tokenize:T_NEWLINE|]
==== T_NEWLINE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_NEWLINE
</eucode>





@[:tokenize:T_COMMENT|]
==== T_COMMENT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_COMMENT
</eucode>





@[:tokenize:T_NUMBER|]
==== T_NUMBER
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_NUMBER
</eucode>





@[:tokenize:T_CHAR|]
==== T_CHAR
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_CHAR
</eucode>

quoted character




@[:tokenize:T_STRING|]
==== T_STRING
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_STRING
</eucode>

string




@[:tokenize:T_IDENTIFIER|]
==== T_IDENTIFIER
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_IDENTIFIER
</eucode>





@[:tokenize:T_KEYWORD|]
==== T_KEYWORD
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_KEYWORD
</eucode>





@[:tokenize:T_DOUBLE_OPS|]
==== T_DOUBLE_OPS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_DOUBLE_OPS
</eucode>





@[:tokenize:T_PLUSEQ|]
==== T_PLUSEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_PLUSEQ
</eucode>





@[:tokenize:T_MINUSEQ|]
==== T_MINUSEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_MINUSEQ
</eucode>





@[:tokenize:T_MULTIPLYEQ|]
==== T_MULTIPLYEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_MULTIPLYEQ
</eucode>





@[:tokenize:T_DIVIDEEQ|]
==== T_DIVIDEEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_DIVIDEEQ
</eucode>





@[:tokenize:T_LTEQ|]
==== T_LTEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_LTEQ
</eucode>





@[:tokenize:T_GTEQ|]
==== T_GTEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_GTEQ
</eucode>





@[:tokenize:T_NOTEQ|]
==== T_NOTEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_NOTEQ
</eucode>





@[:tokenize:T_CONCATEQ|]
==== T_CONCATEQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_CONCATEQ
</eucode>





@[:tokenize:T_DELIMITER|]
==== T_DELIMITER
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_DELIMITER
</eucode>





@[:tokenize:T_PLUS|]
==== T_PLUS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_PLUS
</eucode>





@[:tokenize:T_MINUS|]
==== T_MINUS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_MINUS
</eucode>





@[:tokenize:T_MULTIPLY|]
==== T_MULTIPLY
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_MULTIPLY
</eucode>





@[:tokenize:T_DIVIDE|]
==== T_DIVIDE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_DIVIDE
</eucode>





@[:tokenize:T_LT|]
==== T_LT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_LT
</eucode>





@[:tokenize:T_GT|]
==== T_GT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_GT
</eucode>





@[:tokenize:T_NOT|]
==== T_NOT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_NOT
</eucode>





@[:tokenize:T_CONCAT|]
==== T_CONCAT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_CONCAT
</eucode>





@[:tokenize:T_SINGLE_OPS|]
==== T_SINGLE_OPS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_SINGLE_OPS
</eucode>





@[:tokenize:T_EQ|]
==== T_EQ
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_EQ
</eucode>





@[:tokenize:T_LPAREN|]
==== T_LPAREN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_LPAREN
</eucode>





@[:tokenize:T_RPAREN|]
==== T_RPAREN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_RPAREN
</eucode>





@[:tokenize:T_LBRACE|]
==== T_LBRACE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_LBRACE
</eucode>





@[:tokenize:T_RBRACE|]
==== T_RBRACE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_RBRACE
</eucode>





@[:tokenize:T_LBRACKET|]
==== T_LBRACKET
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_LBRACKET
</eucode>





@[:tokenize:T_RBRACKET|]
==== T_RBRACKET
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_RBRACKET
</eucode>





@[:tokenize:T_QPRINT|]
==== T_QPRINT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_QPRINT
</eucode>





@[:tokenize:T_COMMA|]
==== T_COMMA
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_COMMA
</eucode>





@[:tokenize:T_PERIOD|]
==== T_PERIOD
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_PERIOD
</eucode>





@[:tokenize:T_COLON|]
==== T_COLON
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_COLON
</eucode>





@[:tokenize:T_DOLLAR|]
==== T_DOLLAR
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_DOLLAR
</eucode>





@[:tokenize:T_SLICE|]
==== T_SLICE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_SLICE
</eucode>





@[:tokenize:T_WHITE|]
==== T_WHITE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_WHITE
</eucode>





@[:tokenize:T_BUILTIN|]
==== T_BUILTIN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_BUILTIN
</eucode>





@[:tokenize:T_TEXT|]
==== T_TEXT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum T_TEXT
</eucode>





=== T_NUMBER formats and T_types
@[:tokenize:TF_HEX|]
==== TF_HEX
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_HEX
</eucode>





@[:tokenize:TF_INT|]
==== TF_INT
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_INT
</eucode>





@[:tokenize:TF_ATOM|]
==== TF_ATOM
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_ATOM
</eucode>





@[:tokenize:TF_STRING_SINGLE|]
==== TF_STRING_SINGLE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_STRING_SINGLE
</eucode>





@[:tokenize:TF_STRING_TRIPLE|]
==== TF_STRING_TRIPLE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_STRING_TRIPLE
</eucode>





@[:tokenize:TF_STRING_BACKTICK|]
==== TF_STRING_BACKTICK
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_STRING_BACKTICK
</eucode>





@[:tokenize:TF_STRING_HEX|]
==== TF_STRING_HEX
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_STRING_HEX
</eucode>





@[:tokenize:TF_COMMENT_SINGLE|]
==== TF_COMMENT_SINGLE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_COMMENT_SINGLE
</eucode>





@[:tokenize:TF_COMMENT_MULTIPLE|]
==== TF_COMMENT_MULTIPLE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TF_COMMENT_MULTIPLE
</eucode>





=== Token accessors


@[:tokenize:TTYPE|]
==== TTYPE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TTYPE
</eucode>





@[:tokenize:TDATA|]
==== TDATA
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TDATA
</eucode>





@[:tokenize:TLNUM|]
==== TLNUM
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TLNUM
</eucode>





@[:tokenize:TLPOS|]
==== TLPOS
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TLPOS
</eucode>





@[:tokenize:TFORM|]
==== TFORM
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum TFORM
</eucode>





=== ET error codes


@[:tokenize:ERR_NONE|]
==== ERR_NONE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_NONE
</eucode>





@[:tokenize:ERR_OPEN|]
==== ERR_OPEN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_OPEN
</eucode>





@[:tokenize:ERR_ESCAPE|]
==== ERR_ESCAPE
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_ESCAPE
</eucode>





@[:tokenize:ERR_EOL_CHAR|]
==== ERR_EOL_CHAR
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_EOL_CHAR
</eucode>





@[:tokenize:ERR_CLOSE_CHAR|]
==== ERR_CLOSE_CHAR
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_CLOSE_CHAR
</eucode>





@[:tokenize:ERR_EOL_STRING|]
==== ERR_EOL_STRING
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_EOL_STRING
</eucode>





@[:tokenize:ERR_HEX|]
==== ERR_HEX
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_HEX
</eucode>





@[:tokenize:ERR_DECIMAL|]
==== ERR_DECIMAL
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_DECIMAL
</eucode>





@[:tokenize:ERR_UNKNOWN|]
==== ERR_UNKNOWN
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_UNKNOWN
</eucode>





@[:tokenize:ERR_EOF|]
==== ERR_EOF
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_EOF
</eucode>





@[:tokenize:ERR_EOF_STRING|]
==== ERR_EOF_STRING
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_EOF_STRING
</eucode>





@[:tokenize:ERR_HEX_STRING|]
==== ERR_HEX_STRING
<eucode>
include euphoria/tokenize.e
namespace tokenize
public enum ERR_HEX_STRING
</eucode>





@[:tokenize:error_string|]
==== error_string
<eucode>
include euphoria/tokenize.e
namespace tokenize
public function error_string(integer err)
</eucode>

  Get an error message string for a given error code.



@[:tokenize:new|]
==== new
<eucode>
include euphoria/tokenize.e
namespace tokenize
public function new()
</eucode>

  Create a new tokenizer state

===== See Also:
[[:reset]], [[:tokenize_string]], [[:tokenize_file]]



@[:tokenize:reset|]
==== reset
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure reset(atom state = g_state)
</eucode>

  Reset the state to begin parsing a new file

===== See Also:
[[:new]], [[:tokenize_string]], [[:tokenize_file]]



=== get/set options


@[:tokenize:keep_builtins|]
==== keep_builtins
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure keep_builtins(integer val = 1, atom state = g_state)
</eucode>

  Specify whether to identify builtins specially or not

default is FALSE


@[:tokenize:keep_keywords|]
==== keep_keywords
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure keep_keywords(integer val = 1, atom state = g_state)
</eucode>

  Specify whether to identify keywords specially or not

default is TRUE


@[:tokenize:keep_whitespace|]
==== keep_whitespace
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure keep_whitespace(integer val = 1, atom state = g_state)
</eucode>

  Return white space (other than newlines) as tokens.

default is FALSE


@[:tokenize:keep_newlines|]
==== keep_newlines
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure keep_newlines(integer val = 1, atom state = g_state)
</eucode>

  Return new lines as tokens.

default is FALSE


@[:tokenize:keep_comments|]
==== keep_comments
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure keep_comments(integer val = 1, atom state = g_state)
</eucode>

  Return comments as tokens

default is FALSE



@[:tokenize:return_literal_string|]
==== return_literal_string
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure return_literal_string(integer val = 1, atom state = g_state)
</eucode>

  When returning string tokens, we have the option to process them and
return their value, or to return the literal text that made up the
original string.

Right now, this option only affects the processing of hex strings.

default is FALSE - process the string and return its value



@[:tokenize:string_strip_quotes|]
==== string_strip_quotes
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure string_strip_quotes(integer val = 1, atom state = g_state)
</eucode>

  When returning string tokens, we have the option to strip the quotes.

default is TRUE



@[:tokenize:string_numbers|]
==== string_numbers
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure string_numbers(integer val = 1, atom state = g_state)
</eucode>

  Return TDATA for all T_NUMBER tokens in "string" format.

===== Defaults:
* T_NUMBER tokens return atoms
* T_CHAR tokens return single integer chars
* T_EOF tokens return undefined data
* Other tokens return strings



@[:tokenize:multiline_token|]
==== multiline_token
<eucode>
include euphoria/tokenize.e
namespace tokenize
public type multiline_token(object mlt)
</eucode>



@[:tokenize:last_multiline_token|]
==== last_multiline_token
<eucode>
include euphoria/tokenize.e
namespace tokenize
public function last_multiline_token()
</eucode>

  
===== Returns:
One of 0, TF_COMMENT_MULTIPLE, TF_STRING_BACKTICK, TF_STRING_TRIPLE.

===== Comments:
After calling ##[[:tokenize_string]]##, this function will return a value of 0
if the line did not end in the middle of a multiline construct, or the value
for the respective token. This is meant to facilitate proper tokenizing of
individual lines of code.


=== Routines


@[:tokenize:tokenize_string|]
==== tokenize_string
<eucode>
include euphoria/tokenize.e
namespace tokenize
public function tokenize_string(sequence code, atom state = g_state,
        integer stop_on_error = TRUE, multiline_token multi = 0)
</eucode>

  Tokenize euphoria source code

===== Parameters:
# ##code## The code to be tokenized
# ##state## (default g_state) the tokenizer returned by ##[[:new]]##
# ##stop_on_error## (default TRUE)
# ##multi## one of 0, TF_COMMENT_MULTIPLE, TF_STRING_BACKTICK, TF_STRING_TRIPLE

===== Returns:
Sequence of tokens


@[:tokenize:tokenize_file|]
==== tokenize_file
<eucode>
include euphoria/tokenize.e
namespace tokenize
public function tokenize_file(sequence fname, atom state = g_state,
        integer mode = io :BINARY_MODE)
</eucode>

  Tokenize euphoria source code

===== Parameters:
# ##fname## the file to be read and tokenized
# ##state## (default g_state) the tokenizer returned by ##[[:new]]##
# ##mode## the mode in which to open the file. One of: ##[[:io:BINARY_MODE]]## (default) or ##[[:io:TEXT_MODE]]##.
Note that for large files with Windows line endings, text mode may be much slower.
See [[:io:read_file]] for more information.

===== Returns:
Sequence of tokens


=== Debugging



@[:tokenize:token_names|]
==== token_names
<eucode>
include euphoria/tokenize.e
namespace tokenize
public constant token_names
</eucode>

  Sequence containing token names for debugging


@[:tokenize:token_forms|]
==== token_forms
<eucode>
include euphoria/tokenize.e
namespace tokenize
public constant token_forms
</eucode>





@[:tokenize:show_tokens|]
==== show_tokens
<eucode>
include euphoria/tokenize.e
namespace tokenize
public procedure show_tokens(integer fh, sequence tokens)
</eucode>

  Print token names and data for each token in `tokens` to the file handle `fh`

===== Parameters:
* ##fh## - file handle to print information to
* ##tokens## - token sequence to print

===== Comments:
This does not take direct output from ##[[:tokenize_string]]## or ##[[:tokenize_file]]##. Instead
they take the first element of their return value, the token stream only.

===== See Also:
[[:tokenize_string]], [[:tokenize_file]]




!!CONTEXT:../include/std/unittest.e
!!namespace:unittest
%%output = std_unittest

== Unit Testing Framework

<<LEVELTOC level=2 depth=4>>

=== Background
Unit testing is the process of assuring that the smallest programming units
are actually delivering functionality that complies with their specification.
The units in question are usually individual routines rather than whole programs
or applications.

The theory is that if the components of a system are working correctly, then
there is a high probability that a system using those components can be made
to work correctly.

In Euphoria terms, this framework provides the tools to make testing and reporting on
functions and procedures easy and standardized. It gives us a simple way to
write a test case and to report on the findings.\\
Example~:
<eucode>
include std/unittest.e

test_equal( "Power function test #1", 4, power(2, 2))
test_equal( "Power function test #2", 4, power(16, 0.5))

test_report()
</eucode>

Name your test file in the special manner, ##t_NAME.e## and then simply run
##eutest## in that directory.

{{{
C:\Euphoria> eutest
t_math.e:
failed: Bad math, expected: 100 but got: 8
2 tests run, 1 passed, 1 failed, 50.0% success

Test failure summary:
FAIL: t_math.e

2 file(s) run 1 file(s) failed, 50.0% success--
}}}

In this example, we use the ##test_equal## function to record the result of
a test. The first parameter is the name of the test, which can be anything
and is displayed if the test fails. The second parameter is the expected
result ~-- what we expect the function being tested to return. The third
parameter is the actual result returned by the function being tested. This
is usually written as a call to the function itself.

It is typical to provide as many test cases as would be required to give us
confidence that the function is being truly exercised. This includes calling
it with typical values and edge-case or exceptional values. It is also useful
to test the function's error handling by calling it with bad parameters.

When a test fails, the framework displays a message, showing the test's name,
the expected result and the actual result. You can configure the framework to
display each test run, regardless of whether it fails or not.

After running a series of tests, you can get a summary displayed by calling
the ##test_report## procedure. To get a better feel for unit testing, have
a look at the provided test cases for the standard library in the //tests//
directory.

When included in your program, ##unittest.e## sets a crash handler to log a crash
as a failure.


=== Constants



@[:unittest:TEST_QUIET|]
==== TEST_QUIET
<eucode>
include std/unittest.e
namespace unittest
public enum TEST_QUIET
</eucode>





@[:unittest:TEST_SHOW_FAILED_ONLY|]
==== TEST_SHOW_FAILED_ONLY
<eucode>
include std/unittest.e
namespace unittest
public enum TEST_SHOW_FAILED_ONLY
</eucode>





@[:unittest:TEST_SHOW_ALL|]
==== TEST_SHOW_ALL
<eucode>
include std/unittest.e
namespace unittest
public enum TEST_SHOW_ALL
</eucode>





=== Setup Routines


@[:unittest:set_test_verbosity|]
==== set_test_verbosity
<eucode>
include std/unittest.e
namespace unittest
public procedure set_test_verbosity(atom verbosity)
</eucode>

  set the amount of information that is returned about passed and failed tests.

===== Parameters:
# ##verbosity## : an atom which takes predefined values for verbosity levels.

===== Comments:
The following values are allowable for ##verbosity##:
* ##TEST_QUIET## ~--  0,
* ##TEST_SHOW_FAILED_ONLY## ~--  1
* ##TEST_SHOW_ALL## ~-- 2

However, anything less than ##TEST_SHOW_FAILED_ONLY## is treated as ##TEST_QUIET##, and everything
above ##TEST_SHOW_ALL## is treated as ##TEST_SHOW_ALL##.

* At the lowest verbosity level, only the score is shown, ie the ratio passed tests/total tests.
* At the medium level, in addition, failed tests display their name, the expected outcome and
the outcome they got. This is the initial setting.
* At the highest level of verbosity, each test is reported as passed or failed.

If a file crashes when it should not, this event is reported no matter the verbosity level.

The command line switch ##"-failed"## causes verbosity to be set to medium at startup. The
command line switch ##"-all"## causes verbosity to be set to high at startup.

===== See Also:
[[:test_report]]


@[:unittest:set_wait_on_summary|]
==== set_wait_on_summary
<eucode>
include std/unittest.e
namespace unittest
public procedure set_wait_on_summary(integer to_wait)
</eucode>

  requests the test report to pause before exiting.

===== Parameters:
# ##to_wait## : an integer, zero not to wait, nonzero to wait.

===== Comments:
Depending on the environment, the test results may be invisible if
##set_wait_on_summary(1)## was not called prior, as this is not the default. The command
line switch ##"-wait"## performs this call.

===== See Also:
[[:test_report]]


@[:unittest:set_accumulate_summary|]
==== set_accumulate_summary
<eucode>
include std/unittest.e
namespace unittest
public procedure set_accumulate_summary(integer accumulate)
</eucode>

  requests the test report to save run stats in ##"unittest.dat"## before exiting.

===== Parameters:
# ##accumulate## : an integer, zero not to accumulate, nonzero to accumulate.

===== Comments:
The file "unittest.dat" is appended to with {t,f}\\
: where
:: //t// is total number of tests run
:: //f// is the total number of tests that failed



@[:unittest:set_test_abort|]
==== set_test_abort
<eucode>
include std/unittest.e
namespace unittest
public function set_test_abort(integer abort_test)
</eucode>

  sets the behavior on test failure, and return previous value.

===== Parameters:
# ##abort_test## : an integer, the new value for this setting.

===== Returns:
An **integer**, the previous value for the setting.

===== Comments:
By default, the tests go on even if a file crashed.


=== Reporting


@[:unittest:test_report|]
==== test_report
<eucode>
include std/unittest.e
namespace unittest
public procedure test_report()
</eucode>

  outputs the test report.

===== Comments:

The report components are described in the comments section for [[:set_test_verbosity]]. Everything
prints on the standard error device.

===== See Also:
[[:set_test_verbosity]]


=== Tests



@[:unittest:test_equal|]
==== test_equal
<eucode>
include std/unittest.e
namespace unittest
public procedure test_equal(sequence name, object expected, object outcome)
</eucode>

  records whether a test passes by comparing two values.

===== Parameters:
# ##name## : a string, the name of the test
# ##expected## : an object, the expected outcome of some action
# ##outcome## : an object, some actual value that should equal the reference ##expected##.

===== Comments:

* For floating point numbers, a fuzz of ##1e-9## is used to assess equality.

A test is recorded as passed if equality holds between ##expected## and ##outcome##. The latter
is typically a function call, or a variable that was set by some prior action.

While ##expected## and ##outcome## are processed symmetrically, they are not recorded
symmetrically, so be careful to pass ##expected## before ##outcome## for better test failure
reports.

===== See Also:
[[:test_not_equal]], [[:test_true]], [[:test_false]], [[:test_pass]], [[:test_fail]]


@[:unittest:test_not_equal|]
==== test_not_equal
<eucode>
include std/unittest.e
namespace unittest
public procedure test_not_equal(sequence name, object a, object b)
</eucode>

  records whether a test passes by comparing two values.

===== Parameters:
# ##name## : a string, the name of the test
# ##expected## : an object, the expected outcome of some action
# ##outcome## : an object, some actual value that should equal the reference ##expected##.

===== Comments:
* For atoms, a fuzz of ##1e-9## is used to assess equality.
* For sequences, no such fuzz is implemented.

A test is recorded as passed if equality does not hold between ##expected## and ##outcome##. The
latter is typically a function call, or a variable that was set by some prior action.

===== See Also:
[[:test_equal]], [[:test_true]], [[:test_false]], [[:test_pass]], [[:test_fail]]


@[:unittest:test_true|]
==== test_true
<eucode>
include std/unittest.e
namespace unittest
public procedure test_true(sequence name, object outcome)
</eucode>

  records whether a test passes.

===== Parameters:
# ##name## : a string, the name of the test
# ##outcome## : an object, some actual value that should not be zero.

===== Comments:
This assumes an expected value different from 0. No fuzz is applied when checking whether an
atom is zero or not. Use [[:test_equal]] instead in this case.

===== See Also:
[[:test_equal]], [[:test_not_equal]], [[:test_false]], [[:test_pass]], [[:test_fail]]


@[:unittest:assert|]
==== assert
<eucode>
include std/unittest.e
namespace unittest
public procedure assert(object name, object outcome)
</eucode>

  records whether a test passes. If it fails, the program also fails.

===== Parameters:
# ##name## : a string, the name of the test
# ##outcome## : an object, some actual value that should not be zero.

===== Comments:
This is identical to ##test_true## except that if the test fails, the
program will also be forced to fail at this point.

===== See Also:
[[:test_equal]], [[:test_not_equal]], [[:test_false]], [[:test_pass]], [[:test_fail]]


@[:unittest:test_false|]
==== test_false
<eucode>
include std/unittest.e
namespace unittest
public procedure test_false(sequence name, object outcome)
</eucode>

  records whether a test passes by comparing two values.

===== Parameters:
# ##name## : a string, the name of the test
# ##outcome## : an object, some actual value that should be zero

===== Comments:
This assumes an expected value of 0. No fuzz is applied when checking whether an atom is zero
or not. Use [[:test_equal]] instead in this case.

===== See Also:
[[:test_equal]], [[:test_not_equal]], [[:test_true]], [[:test_pass]], [[:test_fail]]


@[:unittest:test_fail|]
==== test_fail
<eucode>
include std/unittest.e
namespace unittest
public procedure test_fail(sequence name)
</eucode>

  records that a test failed.

===== Parameters:
# ##name## : a string, the name of the test

===== See Also:
[[:test_equal]], [[:test_not_equal]], [[:test_true]], [[:test_false]], [[:test_pass]]



@[:unittest:test_pass|]
==== test_pass
<eucode>
include std/unittest.e
namespace unittest
public procedure test_pass(sequence name)
</eucode>

  records that a test passed.

===== Parameters:
# ##name## : a string, the name of the test

===== See Also:
[[:test_equal]],  [[:test_not_equal]],[[:test_true]], [[:test_false]], [[:test_fail]]



!!CONTEXT:../include/euphoria/debug/debug.e
!!namespace:debug
%%output = euphoria_debug_debug

== Debugging tools

<<LEVELTOC level=2 depth=4>>


=== Call Stack Constants


@[:debug:CS_ROUTINE_NAME|]
==== CS_ROUTINE_NAME
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_ROUTINE_NAME
</eucode>

 CS_ROUTINE_NAME: index of the routine name in the sequence returned by [[:call_stack]]



@[:debug:CS_FILE_NAME|]
==== CS_FILE_NAME
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_FILE_NAME
</eucode>

 CS_FILE_NAME: index of the file name in the sequence returned by [[:call_stack]]



@[:debug:CS_LINE_NO|]
==== CS_LINE_NO
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_LINE_NO
</eucode>

 CS_LINE_NO: index of the line number in the sequence returned by [[:call_stack]]



@[:debug:CS_ROUTINE_SYM|]
==== CS_ROUTINE_SYM
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_ROUTINE_SYM
</eucode>

 CS_ROUTINE_SYM: (debugger only) Pointer to the routine symbol



@[:debug:CS_PC|]
==== CS_PC
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_PC
</eucode>

 CS_PC: (debugger only) The program counter pointer for this routine



@[:debug:CS_GLINE|]
==== CS_GLINE
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum CS_GLINE
</eucode>

 CS_GLINE: (debugger only) The index into the global line array



=== DEBUG_ROUTINE Enum Type
These constants are used to register euphoria routines that handle various debugger
tasks, displaying information or waiting for user input.


@[:debug:SHOW_DEBUG|]
==== SHOW_DEBUG
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum SHOW_DEBUG
</eucode>

SHOW_DEBUG
a procedure that takes an integer parameter that represents the current line in the global line table




@[:debug:DISPLAY_VAR|]
==== DISPLAY_VAR
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum DISPLAY_VAR
</eucode>

DISPLAY_VAR
A procedure that takes a pointer to the variable in the symbol table, and a flag to indicate whether the user requested this variable or not.  Euphoria generally
calls this when a variable is assigned to.




@[:debug:UPDATE_GLOBALS|]
==== UPDATE_GLOBALS
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum UPDATE_GLOBALS
</eucode>

UPDATE_GLOBALS
A procedure called when the debug screen should update the display of any non-private
variables




@[:debug:DEBUG_SCREEN|]
==== DEBUG_SCREEN
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum DEBUG_SCREEN
</eucode>

 DEBUG_SCREEN: called when the debugger should finish displaying and wait for user input before continuing



@[:debug:ERASE_PRIVATES|]
==== ERASE_PRIVATES
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum ERASE_PRIVATES
</eucode>

 ERASE_PRIVATES: A procedure that takes a pointer to the routine  that has gone out of scope, and whose symbols should be removed from the display.



@[:debug:ERASE_SYMBOL|]
==== ERASE_SYMBOL
<eucode>
include euphoria/debug/debug.e
namespace debug
public enum ERASE_SYMBOL
</eucode>

 ERASE_SYMBOL: A procedure that takes a pointer to the symbol that should be removed from the display



=== Debugging Routines


@[:debug:call_stack|]
==== call_stack
<eucode>
include euphoria/debug/debug.e
namespace debug
public function call_stack()
</eucode>

Returns information about the call stack of the code currently running.

===== Returns:
A sequence where each element represents one level in the call stack.  See the
[[:Call Stack Constants]] for constants that can be used to access the call stack
information.
# routine name
# file name
# line number


@[:debug:M_INIT_DEBUGGER|]
==== M_INIT_DEBUGGER
<eucode>
include euphoria/debug/debug.e
namespace debug
public constant M_INIT_DEBUGGER
</eucode>





@[:debug:initialize_debugger|]
==== initialize_debugger
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure initialize_debugger(atom init_ptr)
</eucode>

Initializes an external debugger.  It can also be called
from a debugger compiled into a DLL / SO.

===== Parameters:
# ##init_ptr## : The result of ##[[:machine_func]]( M_INIT_DEBUGGER, {} )##.


@[:debug:set_debug_rid|]
==== set_debug_rid
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure set_debug_rid(DEBUG_ROUTINE rtn, integer rid)
</eucode>



@[:debug:read_object|]
==== read_object
<eucode>
include euphoria/debug/debug.e
namespace debug
public function read_object(atom sym)
</eucode>



@[:debug:trace_off|]
==== trace_off
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure trace_off()
</eucode>



@[:debug:disable_trace|]
==== disable_trace
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure disable_trace()
</eucode>



@[:debug:step_over|]
==== step_over
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure step_over()
</eucode>



@[:debug:abort_program|]
==== abort_program
<eucode>
include euphoria/debug/debug.e
namespace debug
public procedure abort_program()
</eucode>



@[:debug:get_current_line|]
==== get_current_line
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_current_line()
</eucode>



@[:debug:symbol_lookup|]
==== symbol_lookup
<eucode>
include euphoria/debug/debug.e
namespace debug
public function symbol_lookup(sequence name, integer line = get_current_line(),
        atom pc = get_pc())
</eucode>



@[:debug:get_pc|]
==== get_pc
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_pc()
</eucode>



@[:debug:is_novalue|]
==== is_novalue
<eucode>
include euphoria/debug/debug.e
namespace debug
public function is_novalue(atom sym_ptr)
</eucode>



@[:debug:debugger_call_stack|]
==== debugger_call_stack
<eucode>
include euphoria/debug/debug.e
namespace debug
public function debugger_call_stack()
</eucode>



@[:debug:break_routine|]
==== break_routine
<eucode>
include euphoria/debug/debug.e
namespace debug
public function break_routine(atom routine_sym, integer enable)
</eucode>



@[:debug:get_name|]
==== get_name
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_name(atom sym)
</eucode>



@[:debug:get_source|]
==== get_source
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_source(integer line)
</eucode>



@[:debug:get_file_no|]
==== get_file_no
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_file_no(integer line)
</eucode>



@[:debug:get_file_name|]
==== get_file_name
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_file_name(integer file_no)
</eucode>



@[:debug:get_file_line|]
==== get_file_line
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_file_line(integer line)
</eucode>



@[:debug:get_next|]
==== get_next
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_next(atom sym)
</eucode>



@[:debug:is_variable|]
==== is_variable
<eucode>
include euphoria/debug/debug.e
namespace debug
public function is_variable(atom sym_ptr)
</eucode>



@[:debug:get_parameter_syms|]
==== get_parameter_syms
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_parameter_syms(atom rtn_sym)
</eucode>



@[:debug:get_symbol_table|]
==== get_symbol_table
<eucode>
include euphoria/debug/debug.e
namespace debug
public function get_symbol_table()
</eucode>




!!CONTEXT:../include/std/win32/msgbox.e
!!namespace:msgbox
%%output = std_win32_msgbox

== Windows Message Box

<<LEVELTOC level=2 depth=4>>



=== Style Constants

Possible style values for message_box() style sequence



@[:msgbox:MB_ABORTRETRYIGNORE|]
==== MB_ABORTRETRYIGNORE
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ABORTRETRYIGNORE
</eucode>

 Abort, Retry, Ignore



@[:msgbox:MB_APPLMODAL|]
==== MB_APPLMODAL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_APPLMODAL
</eucode>

 User must respond before doing something else



@[:msgbox:MB_DEFAULT_DESKTOP_ONLY|]
==== MB_DEFAULT_DESKTOP_ONLY
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_DEFAULT_DESKTOP_ONLY
</eucode>





@[:msgbox:MB_DEFBUTTON1|]
==== MB_DEFBUTTON1
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_DEFBUTTON1
</eucode>

 First button is default button



@[:msgbox:MB_DEFBUTTON2|]
==== MB_DEFBUTTON2
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_DEFBUTTON2
</eucode>

 Second button is default button



@[:msgbox:MB_DEFBUTTON3|]
==== MB_DEFBUTTON3
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_DEFBUTTON3
</eucode>

 Third button is default button



@[:msgbox:MB_DEFBUTTON4|]
==== MB_DEFBUTTON4
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_DEFBUTTON4
</eucode>

 Fourth button is default button



@[:msgbox:MB_HELP|]
==== MB_HELP
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_HELP
</eucode>

 Windows 95: Help button generates help event



@[:msgbox:MB_ICONASTERISK|]
==== MB_ICONASTERISK
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONASTERISK
</eucode>





@[:msgbox:MB_ICONERROR|]
==== MB_ICONERROR
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONERROR
</eucode>





@[:msgbox:MB_ICONEXCLAMATION|]
==== MB_ICONEXCLAMATION
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONEXCLAMATION
</eucode>

 Exclamation-point appears in the box



@[:msgbox:MB_ICONHAND|]
==== MB_ICONHAND
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONHAND
</eucode>

 A hand appears



@[:msgbox:MB_ICONINFORMATION|]
==== MB_ICONINFORMATION
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONINFORMATION
</eucode>

 Lowercase letter i in a circle appears



@[:msgbox:MB_ICONQUESTION|]
==== MB_ICONQUESTION
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONQUESTION
</eucode>

 A question-mark icon appears



@[:msgbox:MB_ICONSTOP|]
==== MB_ICONSTOP
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONSTOP
</eucode>





@[:msgbox:MB_ICONWARNING|]
==== MB_ICONWARNING
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_ICONWARNING
</eucode>





@[:msgbox:MB_OK|]
==== MB_OK
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_OK
</eucode>

 Message box contains one push button: OK



@[:msgbox:MB_OKCANCEL|]
==== MB_OKCANCEL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_OKCANCEL
</eucode>

 Message box contains OK and Cancel



@[:msgbox:MB_RETRYCANCEL|]
==== MB_RETRYCANCEL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_RETRYCANCEL
</eucode>

 Message box contains Retry and Cancel



@[:msgbox:MB_RIGHT|]
==== MB_RIGHT
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_RIGHT
</eucode>

 Windows 95: The text is right-justified



@[:msgbox:MB_RTLREADING|]
==== MB_RTLREADING
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_RTLREADING
</eucode>

 Windows 95: For Hebrew and Arabic systems



@[:msgbox:MB_SERVICE_NOTIFICATION|]
==== MB_SERVICE_NOTIFICATION
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_SERVICE_NOTIFICATION
</eucode>

 Windows NT: The caller is a service



@[:msgbox:MB_SETFOREGROUND|]
==== MB_SETFOREGROUND
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_SETFOREGROUND
</eucode>

 Message box becomes the foreground window



@[:msgbox:MB_SYSTEMMODAL|]
==== MB_SYSTEMMODAL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_SYSTEMMODAL
</eucode>

 All applications suspended until user responds



@[:msgbox:MB_TASKMODAL|]
==== MB_TASKMODAL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_TASKMODAL
</eucode>

 Similar to MB_APPLMODAL



@[:msgbox:MB_YESNO|]
==== MB_YESNO
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_YESNO
</eucode>

 Message box contains Yes and No



@[:msgbox:MB_YESNOCANCEL|]
==== MB_YESNOCANCEL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant MB_YESNOCANCEL
</eucode>

 Message box contains Yes, No, and Cancel



=== Return Value Constants

possible values returned by MessageBox(). 0 means failure


@[:msgbox:IDABORT|]
==== IDABORT
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDABORT
</eucode>

 Abort button was selected.



@[:msgbox:IDCANCEL|]
==== IDCANCEL
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDCANCEL
</eucode>

 Cancel button was selected.



@[:msgbox:IDIGNORE|]
==== IDIGNORE
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDIGNORE
</eucode>

 Ignore button was selected.



@[:msgbox:IDNO|]
==== IDNO
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDNO
</eucode>

 No button was selected.



@[:msgbox:IDOK|]
==== IDOK
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDOK
</eucode>

 OK button was selected.



@[:msgbox:IDRETRY|]
==== IDRETRY
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDRETRY
</eucode>

 Retry button was selected.



@[:msgbox:IDYES|]
==== IDYES
<eucode>
include std/win32/msgbox.e
namespace msgbox
public constant IDYES
</eucode>

 Yes button was selected.



=== Routines



@[:msgbox:message_box|]
==== message_box
<eucode>
include std/win32/msgbox.e
namespace msgbox
public function message_box(sequence text, sequence title, object style)
</eucode>

  Displays a window with a title, message, buttons and an icon, usually known as a message box.

===== Parameters:
# ##text##: a sequence, the message to be displayed
# ##title##: a sequence, the title the box should have
# ##style##: an object which defines which,icon should be displayed, if any, and which buttons will be presented.

===== Returns:
An **integer**, the button which was clicked to close the message box, or 0 on failure.

===== Comments:
See [[:Style Constants]] above for a complete list of possible values for ##style## and
[[:Return Value Constants]] for the returned value. If ##style## is a sequence, its elements will be
or'ed together.



!!CONTEXT:../include/std/win32/sounds.e
!!namespace:sound
%%output = std_win32_sounds

== Windows Sound

<<LEVELTOC level=2 depth=4>>



@[:sound:SND_DEFAULT|]
==== SND_DEFAULT
<eucode>
include std/win32/sounds.e
namespace sound
public constant SND_DEFAULT
</eucode>





@[:sound:SND_STOP|]
==== SND_STOP
<eucode>
include std/win32/sounds.e
namespace sound
public constant SND_STOP
</eucode>





@[:sound:SND_QUESTION|]
==== SND_QUESTION
<eucode>
include std/win32/sounds.e
namespace sound
public constant SND_QUESTION
</eucode>





@[:sound:SND_EXCLAMATION|]
==== SND_EXCLAMATION
<eucode>
include std/win32/sounds.e
namespace sound
public constant SND_EXCLAMATION
</eucode>





@[:sound:SND_ASTERISK|]
==== SND_ASTERISK
<eucode>
include std/win32/sounds.e
namespace sound
public constant SND_ASTERISK
</eucode>





@[:sound:sound|]
==== sound
<eucode>
include std/win32/sounds.e
namespace sound
public procedure sound(atom sound_type = SND_DEFAULT)
</eucode>

  Makes a sound.

===== Parameters:
# sound_type: An atom. The type of sound to make. The default is SND_DEFAULT.

===== Comments:
The ##sound_type## value can be one of ...
* ##SND_ASTERISK##
* ##SND_EXCLAMATION##
* ##SND_STOP##
* ##SND_QUESTION##
* ##SND_DEFAULT##

These are sounds associated with the same Windows events
via the Control Panel.

===== Example:
<eucode>
 sound( SND_EXCLAMATION )
</eucode>



!!CONTEXT:../docs/unsupported.txt
%%output = unsupported

== Unsupported Features

:<<LEVELTOC level=2 depth=4>>

These are features that have been implemented either partly
or fully, but are not officially part of the Euphoria Language. They may
one day be officially sanctioned and thus fully supported, but that is
not certain. And even if an unsupported feature does make it way into
the language, it may not be exactly what is documented in this section.

So if you use **any** of these unsupported features then be aware that your code
might break in future releases.

=== UTF Encoded String Literals

* using word strings hexadecimal (for utf-16) and double word hexadecimal 
(for utf-32)  e.g.

<eucode>
u"65 66 67 AE" -- ==> {#65,#66,#67,#AE}
U"65 66 67 AE" -- ==> {#65,#66,#67,#AE}
</eucode>

The value of the strings above are equivalent.  
Spaces seperate values to other elements.  
When you put too many hex characters together for the kind of string they are
split up appropriately for you:

<eucode>
x"6566 67AE"  -- 8-bit  ==> {#65,#66,#67,#AE}
u"6566 67AE"  -- 16-bit ==> {#6566,#67AE}
U"6566 67AE"  -- 32-bit ==> {#6566,#67AE}
U"6566_67AE"  -- 32-bit ==> {#656667AE} 
              --            Uses '_' to aid readability for long values.
U"656667AE"   -- 32-bit ==> {#656667AE}
</eucode>

String literals encoded as ASCII, UTF-8, UTF-16, UTF-32 or really any encoding
that uses elements that are 32-bits long or shorter can be built with U"" 
syntax.
Literals of encodings that have 16-bit long or shorter or 8-bit long or shorter
elements can be built using u"" syntax or x"" syntax  respectively.  
Use delimiters, such as spaces and underscores, to break the ambiguity and
improve readability. 

The following is code with a vaild UTF8 encoded string:

<eucode>
sequence utf8_val = x"3e 65" -- This is ">e"
</eucode>

**However,** it is up to the coder to know the correct code-point values for
these to make any sense in the encoding the coder is using. That is to say,
it is possible for the coder to use the x"", u"", and U"" syntax to create
literals that are **not valid** UTF strings.

!!
!! WHERE? The link is invalid, I do not see any in the manual
!!
!! There are routines for working with Unicode strings and for
!! validating, converting and working with Unicode strings. See
!! [[:Unicode]].
!!

Hexadecimal strings can be used to encode UTF-8 strings, even though the 
resulting string does not have to be a valid UTF-8 string. 

**The rules for unicode strings are...**

# they begin with the pair ##u"## for UTF-16 and ##U"## for UTF-32 strings, and
 end with a double-quote (##"##) character
# they can only contain hexadecimal digits (0-9 A-F a-f), and space, underscore,
 tab, newline, carriage-return. Anything else is invalid.
# an underscore is simply ignored, as if it was never there. It is used to aid
 readability.
# For UTF-16 strings, each set of four contiguous hex digits represent a single 
sequence element with a value from 0x0000 to 0xFFFF
# For UTF-32 strings, each set of eight contiguous hex digits represent a single
sequence element with a value from 0x0000 to 0xFFFFFFFF
# they can span multiple lines
# The non-hex digits are treated as punctuation and used to delimit individual 
  values.
# The resulting string does not have to be a valid UTF-16/UTF-32 string.

<eucode>
u"1 2 34 5678AbC" == {0x0001, 0x0002, 0x0034, 0x5678, 0x0ABC}
U"1 2 34 5678AbC" == {0x0000_0001, 0x0000_0002, 0x0000_0034, 0x05678ABC}
U"1 2 34 5_678_AbC" == {0x0000_0001, 0x0000_0002, 0x0000_0034, 0x0567_8ABC}
</eucode>
%%output=relnotes
= Release Notes
<<LEVELTOC level=1 depth=2>>

!!CONTEXT:../docs/release/4.1.0.txt
%%output = release_4.1.0

== Version 4.1.0 Date TBD

=== Bug Fixes

* [[ticket:665]] Fixed to load socket routines from its DLL only when needed.
* [[ticket:744]] Detect duplicate ##case## values in a ##[[:switch statement]]## and throw
  an error at compile or parse time
* OS X bug fixes:
** Callbacks function again, including on 64bit platforms
** Memory maps function
* Fix std/net/http.e that caused malformed HTTP GET requests
* Updated demo/news.ex with up-to-date URLs for some news web sites.
* Fix std/net/http.e so it can handle cases where the Content-Length header is not present
* Fix std/sequence.e so store() will correctly handle the one-element index case - it was duplicating the entire sequence before.
* [[ticket:710]] Updated tokenizer and syntax coloring to be able to preserve state between lines.
  The euphoria trace screen and ed.ex now properly colorize multiline strings and comments.
* ##[[:tokenize_string]]## had an infinite loop if the string ended with a single or double quote and a backslash
* euphoria/tokenizer.e does not add a leading zero to floating point numbers without one when
  ##[[:string_numbers]]## is set
* fixed detection of hex string tokens in ##[[:tokenize_string]]##
* tokenizing better respects the value of ##stop_on_error## parameter for ##[[:tokenize_string]]##
* [[ticket:884]] 32-bit translator crash when translating a 64-bit target
* [[ticket:886]] system_exec with quotes on Windows failed due to quotes being removed
* [[ticket:887]] EDS: crash if create_table and clear_table init_records parameter was less than MAX_INDEX
* [[ticket:898]] fix ##[[:uname]]## to report Windows 8 correctly

=== Enhancements

* Euphoria can be built natively as a 64-bit programming language.
* Added 8-byte memory access: [[:poke8]], [[:peek8s]], [[:peek8u]]
* eucoverage also outputs a file "big_routines.html" that shows covered routines
  from all files sorted by descending routine size
* Added [[:poke_pointer]] and [[:peek_pointer]]
* New [[:sizeof]] built-in for determining size of certain data types.
* [[ticket:631]] Scientific parsing code moved from the euphoria source directory and into the
  standard library.  Routines in ##std/get.e## now return the proper precision data
  based on the native platform (32 or 64 bits).
* Users can write their own debuggers and use them instead of the built in trace debugger.
* gcc builds now include -fPIC (position independent code) runtime libraries for translating
  euphoria code into shared objects.
* -lib-pic switch for translator to specify the PIC runtime library to be used
* [[ticket:166]] get_integer{16,32} will return -1 on EOF.
* Added [[:deprecate]] keyword
* Architecture ifdefs (X86, X86_64, ARM, BITS32, BITS64, LONG32, LONG64)
* -arch option for translator for cross translating
* -cc-prefix option for translator
* Can [[assign to multiple variables -> :Multiple Assignment]] with one statement using sequence semantics.
* Use ##?## to stand in for default parameters.
* eudis now tabulates counts of forward references
* Added [[:poke_long]], [[:peek_longu]] and [[:peek_longs]]
* [[ticket:735]] The number of lines to be used in ctrace.out by ##trace(3)## can be configured
  using ##-trace-lines n## command line switch. See [[Command line switches -> :command line switches]]
  for more information.
* [[ticket:782]] When downloading http content, std/net/http.e will yield to other tasks
* [[t_integer32]] type for checking to see if an object is an integer based on 32-bit Euphoria's definition
* Improved identification of ##routine_id()## targets by the translator
* Smaller translated DLLs are produced by improved identification of routines that need to be exported
* Eutest now has an eubin option for specifying all binaries in a single option.
* Eutest has a retest option for retesting all tests that had previously failed.
* Front end optimizations to reduce parsing time
* Added dynamic library uninitialization to reduce memory leaks if a euphoria translated .dll or .so
  is unloaded
* [[ticket:838]] Eutest now reports the date of the Interpreter, and when the test was completed.
* Much faster and simpler implementation of maps in std/map.e inspired by the implementation of python's
  dictionary object. Some functions and parameters have been deprecated (such as any distinction between
  small and large maps), as they no longer make sense for the new implementation.
* [[ticket:532]] extra-cflags and extra-lflags for translator (thanks to Ira Hill)
* ##[[:lock_file]]## on Windows now supports ##LOCK_SHARED## and ##LOCK_EXCLUSIVE##
* ##[[:tokenize_file]]## uses ##[[:io:BINARY_MODE]]## by default instead of ##[[:io:TEXT_MODE]]##, which
  improves performance on large files with Windows style newlines
* [[ticket:883]] Improved error messages on subscript / slice errors
* ed.ex renamed edx.ex

!!CONTEXT:../docs/release/4.0.6.txt
%%output = release_4.0.6

== Version 4.0.6 Date TBD

=== Bug Fixes

* [[ticket:872]] fix documentation error involving ##[[:or_all]]##
* [[ticket:880]] fix documentaiton error involving ##[[:poke2]]##
* [[ticket:708]] specified that color triples are specified between 0..255 in ##[[:read_bitmap]]## and ##[[:save_bitmap]]##.
* [[ticket:801]] fix translator memory leak for ##[[:insert]]##
* [[ticket:799]] fix memory leak in ##[[:gets]]## when reading EOF
* [[ticket:819]] use operating system sleep functions for fractions of seconds to avoid needless CPU utilization
* [[ticket:824]] fix OpenWatcom installer PCRE directory
* [[ticket:823]] emit error in translator when user specifies a file for the build directory
* [[ticket:781]] http_post and http_get now follow redirects
* [[ticket:835]] translator properly handles sequences passed to ##floor##
* [[ticket:830]] fixed memory leak in ##[[:replace]]##
* [[ticket:847]] fixed memory leak in ##[[:remove]]##
* [[ticket:837]] fixed documentation error involving ##[[:load_map]]##
* Fix std/sequence.e so store() will correctly handle the one-element index case - it was duplicating the entire sequence before.
* [[ticket:638]] ##[[:value]]## and ##[[:get]]## handle multi-line strings
* [[ticket:836]] ##[[:canonical_path]]## works when path is not on the current drive on Windows
* [[ticket:630]] shrouder ignores binder options that are not applicable
* [[ticket:776]] Updated ##[[:walk_dir]]## parameter documentation
* functions imported from msvcrt.dll should use cdecl (affects ##[[:now_gmt]]##, ##[[:locale:get]]##,
  ##[[:locale:set]]## and ##[[:locale:datetime]]##)
* [[ticket:882]] Translated ##[[:remove]]## works correctly with empty sequence
* [[ticket:885]] Translated ##[[:splice]]## properly counts references when splicing an atom
* [[ticket:898]] fix ##[[:uname]]## to report Windows 8 correctly

=== Enhancements

* command line help is now sorted by option

!!CONTEXT:../docs/release/4.0.5.txt
%%output = release_4.0.5

== Version 4.0.5 October 19, 2012

=== Bug Fixes
* [[ticket:777]] When invalid input is sent to 'match' or 'find' the error includes 'match' or 'find' in the error message repectively.
* [[ticket:749]] Fix init checks for while-entry and goto
* [[ticket:563]] Default values for arguments are always parsed and resolved as though they
  were being evaluated from the point of the routine declaration, not the point where the
  routine is called
* [[ticket:763]] In some cases, the translator did not keep potential [[:routine_id]] targets
  when dynamic routine names were used
* [[ticket:665]] documented minimal requirements for various features in EUPHORIA on various platforms.
* [[ticket:665]] set minimal version for Windows in its installer to avoid installing on computers that it wont work on.
* [[ticket:767]] translated ##[[:insert]]()## could segfault when inserting an atom stored as an integer
* [[ticket:744]] Duplicate case values in a switch block no longer result in a failed compile after being translated to C.
* [[ticket:775]] Fixed potential memory leak when a temp is passed to one of the
  native type check functions: [[:integer]](), [[:atom]](), [[:object]]() or [[:sequence]]()
* [[ticket:778]] Translator keeps forward referenced routine_id routines in include files
* [[ticket:789]] Make parser read Windows eols the same as unix eols on Linux.
* [[ticket:795]] Corrected std/serialize.e to call define_c_proc correctly
* [[ticket:795]] Corrected std/net/http.e to call do a case insensitive search for 'content-length'
* [[ticket:796]] when binding and translating use different EXE names
* Fixed memory leak in translator when calls to ##head()## result in an empty sequence

=== Enhancements

* [[ticket:768]] Backported support for deserializing 8-byte integers and 10-byte floating point.
* Optimization of std/map.e ##remove()## to prevent unnecessary copy on write
* [[ticket:787]] Document cases where you pass an empty sequence into search routines


!!CONTEXT:../docs/release/4.0.4.txt
%%output = release_4.0.4

== Version 4.0.4 April 4, 2012

=== Bug Fixes

* [[ticket:664]] Symbol resolution errors now report whether you use a symbol is not declared or is declared more than once, 
	or from not declared in the file you specify (via a namespace), or not a builtin.  When declared more than once, you are now
	told where the symbols were declared.
* [[ticket:602]] socket create documentation corrected to state that it returns an error code on failure.
* [[ticket:672]] fixed dll creation under Windows.
* [[ticket:687]] fixed source file distribution.
* [[ticket:681]] fixed error reporting when the error is the last symbol on a line, but that might be part of
  and expression that carries over to the next line
* [[ticket:694]] do not short circuit inside of forward function calls
* [[ticket:699]] Include public and export symbols in ex.err output
* [[ticket:717]] Fix docs to correctly describe bitwise functions
* [[ticket:725]] Smarter reading of command line options.  Euphoria could consume switches meant for the
  the end user program
* When there is a user supplied library, the translator does not abort when the library doesn't exist and one of 
  ##-nobuild##, ##-makefile## or ##-makefile-partial## is used
* [[ticket:728]] Fix sequence slice error when invalid command line arguments are passed to euphoria. 
* [[ticket:730]] Fixed initialization of private variables.  The translator incorrectly assumed that all
  variables started as integers to prevent them from being dereferenced.
* [[ticket:722]] Use backslashes for the filesystem seperator when passing 
  to Watcom even if the supplied data uses forward slashes.
* [[ticket:611]] an no-longer existing install.doc was being referenced by a
  an install script.  This has been updated.
* [[ticket:683]] [[ticket:685]] fixes for building the interpreter itself 
  for MinGW 
* [[ticket:732]] fixes in building console less programs using MinGW
* [[ticket:721]] fixes drive letter case descrepency between various functions defined in sys/filesys.e

=== Enhancements

* [[ticket:611]] A more complete explaination of how to install has been added to the documentation.
* [[ticket:727]] The interpreter and translator no longer show you all of their options when you make
 a mistake at the command line.
* [[ticket:727]] cmd_parse() can take a new option NO_HELP_ON_ERROR, which means it will not display all
  of the options on error.
* [[ticket:741]] minor format/refactor win32 demos to use C_TYPES more win64 compatible & eu4.1 ready.


!!CONTEXT:../docs/release/4.0.3.txt
%%output = release_4.0.3

== Version 4.0.3 June 23, 2011

=== Bug Fixes

* [[ticket:655]] Integer values stored as doubles weren't being correctly
  coerced back to euphoria integers in translated code.
* [[ticket:656]] Translated ##[[:not_bits]]## made incorrect type assumptions
* [[ticket:662]] Switches with all integer cases, but with a range of greater than
  1024 between the biggest and smallest were interpreted incorrectly.
* [[ticket:661]] fixed translator linking to use comctl32 library on windows
* [[ticket:663]] Translator ##-plat## switch now uses ##WINDOWS## instead of ##WIN##.
* [[ticket:666]] fixed to allow integers stored as doubles in be_sockets.c.
* [[ticket:654]] removed internal use-only standard library routines and constants from the user documentation.
* [[ticket:667]] Fixed optimization of translated IF when the conditions were known
  to be false.
* [[ticket:654]] Removed from documentation the internal workings of Machine Level Access and reorganized Documentation.
* [[ticket:676]] Changed search order for [[:locate_file]]
* [[ticket:675]] Fixed machine crash in [[:splice]] when splicing an atom before beginning
  of sequence or after end
* [[ticket:665]] Windows 95 and above is supported.  For using sockets you must have Windows Sockets 2.2
* [[ticket:680]] Fixed ##[[:socket]]## type checking.
* [[ticket:720]] Fix propagation of ##public include## among reincluded files
 
=== Enhancements

* Minor changes to eutest output to read its console output
* The interpreter and programs created with the translator (for WATCOM only) will now run on older versions of Windows that don't support
  sockets unless this program //uses// sockets.
* New math functions ##[[:larger_of]]## and ##[[:smaller_of]]##

!!CONTEXT:../docs/release/4.0.2.txt
%%output = release_4.0.2

== Version 4.0.2 April 5, 2011

=== Bug Fixes

* Fixed ##[[:canonical_path]]## performance issues introduced in 4.0.1.
* [[ticket:646]] ##[[:dir]]## can now handle multiple wildcards on non-Windows platforms
* [[ticket:647]] The version detection system has been improved so that all binaries use
  the same C header file, which should prevent the potential of mismatched versions.
* [[ticket:644]] ##[[:canonical_path]]## leaves alone path components (and anything after them)
  with wildcards.
* Fixed compiler directives about functions that don't return.  Removed some that were obsolete,
  and corrected for MinGW to use the GCC directives.
* [[ticket:648]] Fix small memory leak from while loops

=== New Functionality

* The ##std\rand.e function##, **##sample()##**, now implements both //with replacement//
and //without replacement// sampling methods.

!!CONTEXT:../docs/release/4.0.1.txt
%%output = release_4.0.1

== Version 4.0.1 March 29, 2011

=== Bug Fixes

* Renamed implicit Top Level SubProgram to an illegal name.  Previously used "_toplevel_",
  which became a legal name for euphoria 4.0
* [[ticket:577]] ##object()## works same on translator as the interpreter.
* euc now uses quotes around filenames when processing resource files
* [[ticket:575]] OW installer file setenv-ow.bat functionality restored from 4.0.0RC2.
* case issues were removed from pathinfo(), canonical_path(), and abbreviate_path()
  these functions now return raw OS output; it is up to the user to change case when necessary
* [[ticket:593]] Atoms represented as doubles, but that hold the double representation of a
  euphoria integer, now hash as though they were actually represented as an integer.  This
  ensures that two objects that evaluate as ##equal()## will have the same hash value.
* [[ticket:597]] Invalid negative routine ids were not detected properly by the interpreter,
  leading to a machine crash.
* Now EUPHORIA can be installed under the Windows' 'Program Files' (with spaces) and the
  translated code will be compiled.
* Fixed Demos to not rely on EUDIR being set and to not issue warnings
* Improved confirmation in the algorithm that determines where EUPHORIA is.
* [[ticket:601]] Missing htmldoc added to Makefile
* [[ticket:604]] Uninstaller now completely cleans up after the installer. 
  Note %EUBIN%\bin\eu.cfg is left  in place if modified.
* Fixed link to PDF documentation
* Added HTML documentation
* [[ticket:610]] Euphoria Installer that includes Watcom will now prevent the user from
  installing Euphoria under a directory with spaces.  Watcom itself has a lot of problems
  when spaces are in its path
* [[ticket:614]] maybe_any_key() was not pausing when a Console Program was run from 
  Windows Explorer.
* [[ticket:591]] updated copyright and version and added documentation reminding us
  all of the places we need to change that information.
* [[ticket:607]] Fixed translation of integers with decimals (e.g., 2.0) when
  assigned to constants
* [[ticket:598]] Link windows binaries to comdlg32.dll to make sure GUI calls work
  with the new manifest.
* [[ticket:590]] Fixed outdated or incorrect documentation on loop statements
* [[ticket:594]] Fixed problem with not being able to link to resource file in a 
  location with spaces.
* [[ticket:615]] Fixed abbreviate_path for Windows 
* [[ticket:595]] When it is necessary, tell user to change directory before using the make program.
* [[ticket:592]] eu.cfg files in the program's directory and the euphoria executable directories
  are searched before platform specific directories
* [[ticket:609]] Scientific notation not handling a decimal of all zeroes correctly.
* [[ticket:621]] Add ##-eudir <dir>## handler to binder and shrouder
* [[ticket:617]] Fix top level ##case## values when referencing an unqualified constant
  in another file
* [[ticket:620]] Added comdlg32.dll to mingw linking flags
* [[ticket:625]] Negative subscripts result in runtime errors.
* Fixed eu.cfg handling precedence and parameter merge / de-dupe algorithm to
  keep correct order of switches.
* Load eu.cfg arguments when running programs with no arguments, e.g., "eui app.ex"
* [[ticket:619]] GNU makefile "all" target builds all binaries now
* [[ticket:632]] fix trace screen prompts to prompt to continue
* [[ticket:633]] On Windows, ##[[:dir]]## was incorrectly case sensitive if wildcards were used.
* [[ticket:624]] Fixed regex function ##[[:is_match]]## to use the ##from## parameter
* [[ticket:596]] Worked around GNU C problem of a lack of alias attribute support on some Mac OS X machines.
* [[ticket:636]] Source files checked out from Mercurial (and thus distributed packages) 
  will use the conventions of the OS for line breaks. 
* [[ticket:639]] In place RHS slice (on sequence with reference count 1), followed by in 
  place ##[[:splice]]## (on sequence still with reference count 1) works correctly
* [[ticket:640]] Fix ##[[:dir]]## when a file cannot be stat()ed
* [[ticket:641]] Use ##[[:dir]]## instead of just calling raw machine_func in 
  ##[[:canonical_path]]## and ##[[:abbreviate_path]]##

=== Enhancements

* Added parsing of two digit years to ##std/datetime.e## ##[[:parse]]##.
* [[ticket:516]] added ##[[:join_path]]## and ##[[:split_path]]## routines.
* ##[[:current_dir]]()## now always returns an upper case letter for the drive
  id.
* ##[[:canonical_path]]()## can now leave the case alone, lower the case,
  correct the case, and even get short file names for programs that still 
  cannot handle quoted arguments at the command line.
  

!!CONTEXT:../docs/release/4.0.0.txt
%%output = release_4.0.0

== Version 4.0.0 December 22, 2010

4.0.0 was released on December 22, 2010.

For a concise list of what has changed from 3.1.1 to 4.0.0 final, please see 
[[:What's new in 4.0?]] section of this manual.

=== Deprecation

* with/without warning lists have changed from ##( name1, name2 )## to
##{ name1, name2 }## as to be more like Euphoria sequences. In the
future the old ##( name1, name2 )## syntax will be removed.


=== Possible Breaking Changes

* ##std/sequence.e##/##[[:series]]## has changed the functionality of the last parameter.
  Previously ##series(1,1,5)## would produce ##{1,2,3,4,5,6}##. i.e. 5 was the number of
  items to add onto the starting 1. The last parameter has been changed to be the number
  of items in the resulting list. Thus, ##series(1,1,5)## will now produce
  ##{1,2,3,4,5}##, i.e. a sequence of 5 items. ##series(1,1,0)## before would produce
  ##{1}##. Now it produces ##{}##, i.e. an empty series.
* [[ticket:551]]: ##WIN32_GUI##, ##WIN32_CONSOLE##, ##EUB_CONSOLE##, ##EUC_CONSOLE## have been changed
  to simply refer to ##GUI## or ##CONSOLE##.  On non-Windows platforms, ##CONSOLE## 
  will be defined.

=== Removed

* ##creolehtml## is no longer shipped with Euphoria. It has been enhanced to support
  multiple output formats and thus its name has been changed to simply ##creole##. HTML
  remains the default output. Usage remains the same thus simply renaming build systems
  to use ##creole## instead of ##creolehtml## will work.

=== Bug Fixes

* [[ticket:438]], removed path test in ##demos/santiy.ex## as it does not function
                  correctly with bound, translated or even a non-standard eui location and
                  actually cannot, thus it was removed.
* [[ticket:514]], Fixed bug with internal ##dir## implementation that would prevent displaying
                  the content of a directory if given without a trailing slash on Windows.
* [[ticket:517]], Added a bounds check that could cause the translator or binder to crash.
* [[ticket:518]], Prevented write_coverage from being called twice on CTRL+C/error condition.
* [[ticket:519]], preproc and net demos are now in the debian package.
* [[ticket:530]], ##t_command_line_quote## test fixed on Windows.
* [[ticket:533]], Debian package copyright was updated in accordance to Debian policy.
* [[ticket:540]], ##[[:get_key]]## was described in both ##io.e## and ##console.e##, removed
                  from ##io.e##
* [[ticket:545]], ##[[:canonical_path]]## did not properly insert the drive letter on Windows
                  when the path began with a forward slash ##/##.
* [[ticket:548]], Fixed error in emitted C in some translated ##for## loops.
* [[ticket:550]], Examples for regex ##[[:matches]]## and ##[[:all_matches]]## now properly
                  either supply or use the default ##from## parameter.
* [[ticket:555]], Fixed parsing of constants when first statement is a constant assigned by a
                  built-in function.
* [[ticket:556]], Fixed type inference for return value from ##[[:rand]]## in translator.
* [[ticket:557]], ##euphoria.h## had gotten out of sync when some OPs were removed.
* [[ticket:558]], Fixed crash caused by undeclared variable assignment by properly subscripting
		  [i] when looking up forward references in the toplevel subroutine
* [[ticket:560]], Functions that started with an unqualified variable from another file
                  being assigned by the return value of an unqualified function from another
                  file could result in a crash.
* [[ticket:564]], Documentation fix on parameter name for ##[[:calc_hash]]##.
* Fix backend and interpreter to avoid "press any key" prompts when
  running as a console from a shared console window.
* Ensure forward type checks aren't resolved until after the variable being type checked has
  been resolved.

=== Enhancements/Changes

* Made previously private method ##iscon## in ##std/console.e## a public method named
  ##[[:has_console]]## which will return TRUE/FALSE if the current application has a
  console window attached.
* ##[[:cmd_parse]]## now splits onto two lines an option whose command is longer than
  the maximum pad size and its description.
* PDF documentation is now much better, generated from LaTeX sources.
* Bundled ##creole## program supports multiple output formats now, the addition of LaTeX
  for great printed or PDF documentation from your creole sources.
* Bundled utility ##bench.ex## now outputs timing information to STDERR
  by default. ##--stdout## can be supplied if output to STDOUT is desired. It now also
  displays the min and max iteration times in addition to the already average and total.
* ##demo/net/pastey.ex## demo has been updated to function with
  OpenEuphoria's pastey service. It can also now accept file input via stdin.
* ##-version## on main products now reports build date in addition to
  previous information.
* ##euphoria/info.e## version methods ##[[:version_string]]## and ##[[:version_string_long]]##
  now have the ability to report the enhanced version information.
* Optimized for loops to check for integer initial value and
  limits.

!!CONTEXT:../docs/release/4.0.0.rc2.txt
%%output = release_4.0.0.rc2

== Version 4.0.0 Release Candidate 2 December 8, 2010

=== Deprecation

* ##[[:find_from]]## and ##[[:match_from]]## have been deprecated. ##[[:find]]## and 
  ##[[:match]]## accept an optional argument (##start##) allowing these functions to be a
  100% drop in replacement.
* ##OPT_EXTRAS## in ##std/cmdline.e## has been replaced by a more favored name ##EXTRAS##.
* ##iff## from ##std/utils.e## has been replaced by a more favored name ##[[:iif]]##.

=== Removed

* [[ticket:371]], ##replace_all## has been removed as it was a duplicate of the
                  more powerful [[:match_replace]] routine.
* [[ticket:376]], ##mouse.e## and ##std/mouse.e##
* [[ticket:484]], ##wildcard_file## is very DOS centric, doesn't act right at all on
                  modern consoles. It has been removed.
* [[ticket:486]], ##can_add## docs have been removed, they pointed to the name change
                  of ##can_add## to ##binop_ok##, changed during beta stage.
* [[ticket:487]], ##wildcard:new()##, method really didn't make sense as a planning
                  stage for regex usage as too much would have to change, a simply call
                  to new did not save much and possibly just caused bad programming
                  methods to be used.
* Support for alternate style eu.cfg sections, i.e. bind:unix and unix:bind were 
  previously supported, now only the documented method: bind:unix is accepted.

=== Bug Fixes

* [[ticket:118]], ##object()## tests now function properly when translated.
* [[ticket:169]], ##[[:find_nested]]## no longer defaults the ##rtn_id## parameter
                  to ##-1## as that is the "invalid" return value of [[:routine_id]]
                  in which case a typo in your routine id would be silently ignored
* [[ticket:335]], ##eui## now only accepts -v, ~-~-version as parameters to display
                  the version number instead of -v, ~-~-v, -version and ~-~-version.
* [[ticket:338]], Fixed //Data Execution Prevention// for FreeBSD systems.
* [[ticket:339]], Fixed locale for FreeBSD systems.
* [[ticket:341]], Removed unused variables in the standard library.
* [[ticket:343]], Resolution of unqualified symbols from other files is deferred until
                  all files that could cause symbol resolution conflicts have been read.
* [[ticket:345]], Forward patches now update the stack space for a routine when
                  they create temps.
* [[ticket:349]], Fixed resolution of qualified public symbols when the namespace points
                  to the wrong file, but the namespace file directly includes the file with
                  the actual routine
* [[ticket:352]], A function with a defaulted parameter that is both forward
                  referenced and inlined no longer crashes.
* [[ticket:358]], The programs eutest, creolehtml, and eudoc now all support a
                  command line option to display their version number.
* [[ticket:362]], The handing of regular expressions which match the text but
                  didn't have any matching sub-groups was not correct nor
                  documented.
* [[ticket:366]], Created a new module, base64, to implement the standard
                  Base-64 encoding algorithms.
* [[ticket:367]], ##[[:http_post]]## properly handles multi-part form data.
* [[ticket:372]], When an application ends, it closes all the opened files. 
                  However if it was ending due to an syntax error, it was
                  closing those files before trying to access the message 
                  text database that had been opened, thus causing a seek() to fail
                  and crash the application.
* [[ticket:378]], On Linux and FreeBSD, the socket tests failed to detect the
                  correct error code.
* [[ticket:392]], ##[[:seek]]## was not returning the correct failure code on
                  some errors.
* [[ticket:396]], Continue operations are now properly back patched.
* [[ticket:391]], Watcom build system was lacking the ability to build the manual.
* [[ticket:402]], ##[[:maybe_any_key]]## now works when run from the command line version
                  of EUPHORIA even when run without a command-line shell.
* [[ticket:403]], Many documentation examples used ? func() and showed the output in
                  string format which ? does not do. It was misleading to the new person
                  to Euphoria. Found instances have been updated.
* [[ticket:405]], ##dis.ex## no longer creates a build directory for no reason.
* [[ticket:409]], Calls to ##Head()## that should have altered the sequence in place
                  did not, resulting in slower code.
* [[ticket:417]], Accidental inclusion of TOC was removed
* [[ticket:418]], ##-debug## ##eu.cfg## switch text was corrected
* [[ticket:418]], Clarified what (all) and (translator) means
* [[ticket:425]], Fixed crash when branches were inlined into the top level
* [[ticket:426]], Eutest uses binary binder
* [[ticket:429]], ##tokenize.e## no longer drops the first character of a backtick string
* [[ticket:431]], ##tokenize.e## properly parses \xXX escapes
* [[ticket:434]], ##tokenize.e## no longer strips leading zeros on numbers when using
                  the ##[[:string_numbers]]## option.
* [[ticket:435]], ##tokenize.e## handles 0?NN numbers properly now. Returns 
                  ##[[:T_NUMBER]]## as the token type and either ##[[:TF_INT]]##
                  or ##[[:TF_HEX]]## as the form. If ##[[:string_numbers]]## is
                  enabled, the prefix is returned as part of the string, i.e.
                  ##integer a = 0b0101## will return ##"0b0101"##.
* [[ticket:439]], ##tokenize.e## fixed breakage with slice operator due to new string
                  number parsing.
* [[ticket:448]], Fixed ##splice()## translation.
* [[ticket:453]], Reworked the way open files are cleaned up so that coverage works properly
* [[ticket:457]], cmd_parse() now correctly honors the NO_HELP option and allows
                  the coder to override the default help switches.
* [[ticket:461]], Fixed error checking for invalid C routines for c_func / c_proc.
* [[ticket:463]], Fixed large file support for MinGW
* [[ticket:464]], Fixed translated for loops that could result in incorrectly emitted brackets
* [[ticket:465]], Fixed stack space calculations for forward proc to func conversion and type checks.
* [[ticket:466]], Fixed line reporting on compile time type check error.
* [[ticket:467]], Fixed interpreter, translator and binder for handling multiple parameters
                  when one comes from a eu.cfg file and the other from the command line, but
                  the given option was designed to only be used ONCE, such as -batch
* [[ticket:469]], Fixed translated block comments
* [[ticket:471]], When using the ##-lib## parameter to ##euc##, it's canoncial path is used
                  and it's existance is checked before translation has begun to prevent wasting
                  time only to find the linker fails.
* [[ticket:472]], eui --help display is now in a logical display order.
* [[ticket:473]], euc --help display is now in a logical display order.
* [[ticket:475]], Fixed memory leak with interpreted [[:rand]]
* [[ticket:476]], ##euc## can now translated single character base filenames, i.e. h.ex
* [[ticket:477]], ##canonical_path## expansion of ~ now works in MSYS and CMD.exe with 
                  the MinGW build.
* [[ticket:479]], Installer now writes a eu.cfg, appends at the confirmation of the user.
* [[ticket:481]], RD_INPLACE, RD_PRESORTED, RD_SORT are now documented individually.
* [[ticket:485]], Fixed scanner initialization to prevent invalid accesses.
* [[ticket:490]], Fixed large file support for Watcom
* [[ticket:491]], ##cmd_parse## now appends everything after the first extra to the 
                  ##OPT_EXTRAS## entry when ##NO_VALIDATION_AFTER_FIRST_EXTRA## is supplied
                  as a parsing option.
* [[ticket:501]], rand_range(hi,lo) now works with lo > 30-bits. 
* [[ticket:505]], Fixed front-end command line processing
* [[ticket:509]], fix pointer handling in regex back end code
* [[ticket:503]], When translating, temps that were thought to be either sequences or objects,
  but were ultimately atoms were not having their possible min / max values reset, leading to 
  incorrect C code being emitted.
* Fixed [[:seek]] return value for large files on Linux.
* [[:connect]] return value was documented incorrectly.
* ##std/cmdline.e##, ##cmd_parse## sets the NO_CASE option when option does not have HAS_CASE.
* ##std/cmdline.e##, ##cmd_parse## sets the NO_PARAMETER option when option does not have HAS_PARAMETER.
* ##std/cmdline.e##, ##cmd_parse## sets the ONCE option when option does not have MULTIPLE.
* The euphoria coded backend (eu.ex) in some cases did not handle recursive calls correctly.
* Too numerous to list: Many documentation typo, spelling mistakes and formatting
  errors have been corrected.
* Removed many unnecessary ##[[:maybe_any_key]]## uses from the general demos
* ##net/http.e## now properly handles ##{ {key,value}, ...}##, ##{ encoding_type, {key,val}, ...}##
  and already encoded string data, ##"name=John%20Doe"##.
* Fixed eutext.ex and std/unittest.e. Under some circumstances, they would report 100%
  success even though there were some failures.
* Fixed ##std/filesys.e## and ##std/locale.e## for use on OpenBSD and NetBSD.
* Use POSIX random() to initialize random seed1 on non-Windows platforms.
* Updated ##t_io.e## as OpenBSD and NetBSD allows seeking on STDIN, STDOUT and 
  STDERR.
* Now ensure internal C strings in be_pcre are properly null terminated.
* Fixed version display information for NetBSD

=== Enhancements/Changes

* [[ticket:334]], *nix generic distribution build scripts are now combined for easier maintenance.
* [[ticket:341]], [[ticket:344]], Many unused variables have been cleaned up in the 
                  standard library.
* [[ticket:363]], ##euc## now has an optional parameter ##-rc-file## that will compile
                  and bind the resource file to windows executables.
* [[ticket:411]], documented the ##$## character as applied to a sequence terminator.
* [[ticket:413]], Qualified the standard library. With so many forward lookups this allows
                  for a pretty large speedup when using multiple standard library includes.
* [[ticket:499]], Add support for using '1', '2', and 'j' in place of F1, F2,
                  and the DOWN_ARROW key in the Trace screen. This allows Unix users to use
                  trace(1) even if we don't recognize escape sequences for their particular
                  $TERM
* [[ticket:513]], Moved [[:get_text]] from ##std/text##.e to ##std/locale.e##
* ##manual-upload## target was added to GNU and Watcom makefiles
* Formatted ##buzz.ex## example
* ##euc## will always remove it's temporary build directory unless the ##-keep##
  option is supplied. If one wants to keep the build directory for some reason, they
  sould probably use ##-build-dir## as well, for example: ##euc -build-dir my-build 
  hello.ex## which will automatically keep the build directory since it was user specified.
* Converted ##bin/lines.ex## to use new language constructs and the standard library
  as an example of how an application take advantage of 4.0. Code base went from 591
  lines of code to 195 lines of code. Bugs were fixed, comment percentage calculations
  and header/footer lines were added in the new, smaller version as well.\\
  \\
  This program also now has the ability to sort results by numerous options in normal
  or reverse order.
* Moved network demos from ##demos/## to ##demos/net## for better organization.
* ##euphoria/tokenize.e## BLANK concept has changed. tokenize use to consume all newlines
  and only report double blanks. It now simply tokenizes the data and returns a newline
  if requested. ##keep_blanks## has been renamed to ##[[:keep_newlines]]## and 
  ##T_BLANK## has been renamed to ##[[:T_NEWLINE]]##. Thus the tokenizer doesn't perform
  any 'parser' functions, it simply tokenizes the source.
* Added ##show_tokens##, ##token_names## and ##token_forms## to ##euphoria/tokenize.e## to
  help in debugging both tokenize internal routines and applications that make use of
  ##euphoria/tokenize.e##
* Installer now creates a eu.cfg directory in EUDIR/bin
* Speed improvements to map:put()
* Demoted several "bin" programs to demos including:
** ##ascii.ex##
** ##eprint.ex##
** ##eused.ex##
** ##guru.ex##
** ##key.ex##
** ##search.ex##
** ##where.ex##
* All demos and bundled bin programs are unit tested to ensure at least eui -test passes
* Removed ##analyze.ex## as it never was a finished, deployable product
* eu.cfg "win32" sections ([win32], [bind:win32], [translate:win32], [bind:win32]) have
  now all been changed to "windows", not "win32"
* Removed demo/demo.doc and instead included in the header of each demo program what
  they do and included them into a section in the manual about demos.
* ##-test## parameter now displays warnings as well as errors
* Translator speed optimizations.
* Improved logging and error checking for sock_server.ex demo
* Renamed ##bin/lines.ex## to ##bin/euloc.ex## since it's more Euphoria centric now.
* Removed left-over translator command line parameter ##-fastfp## which was for DOS only.
* Reuse memory buffer in HSIEH32 hash implementation
* ##abbreviate_path## is used to cleanup the display from ##euc## regarding the Build 
  Directory.
* ##printf##s third argument is now optional. ##printf(1, "Hello\n", {})## is no longer
  needed, it can be shortened to ##printf(1, "Hello\n")##
* Added another hashing algorithm. HSIEH30 is identical to HSIEH32 but will only
  ever return a 30-bit integer (a Euphoria integer).
* Removed hash elements from map.e and placed them in a new standard library module, hash.e
* Performance tweaks to maps. 
* Removed support for ##emake.bat## build scripts, please use direct build or makefiles,
  both of which ##euc## supports directly.

!!CONTEXT:../docs/release/4.0.0.rc1.txt
%%output = release_4.0.0.rc1

== Version 4.0.0 Release Candidate 1 November 8, 2010

The release of Euphoria 4.0 is like no other. It's updates are massive. The change log
here is not designed to detail every minor change that has taken place during the 4.0
development cycle. Included in this release note are the language changes only.

The entire standard library is brand new. The manual should be consulted to learn about
the new standard library, it's changes are not documented here as it would just be a
duplicate of the manual API sections. We will, however, mention a few major additions
to the API library that has required binary changes in the backend:

==== Major Library Additions

* Dictionary Type
* Regular Expressions
* Sockets

=== Contributors

Another thing you will notice that is slightly different about this release note is that
we are not attributing "Change ABC" to person "DEF." Many of the changes made have been
an iterative process involving many people. Euphoria 4.0 has had a large number of
contributors. We will, however, list all those that have contributed, the list is in
last name alphabetical order:

* Jiri Babor
* Chris Bensler
* Jim C. Brown
* CoJaBo
* Jeremy Cowgar
* Robert Craig
* Chris Cuvier
* Jason Glade
* Ryan W. Johnson
* C.K. Lester
* Matthew Lewis
* Junko Miura
* Marco Antonio Achury Palma
* Derek Parnell
* Shawn Pringle
* Michael Sabal
* Kathy Smith
* Yuku (Aku)

If we have forgotten your name, please forgive us and bring it to our attention, the
addition will be made promptly.

=== Bug Fixes

* $$(bugfix) 1855414. ##open()## max path length is now determined by the underlying
  operating system and not a generic default. ##open()## also now returns -1 when the
  filename is too long instead of causing a fatal error.
* $$(bugfix) 1608870. ##dir()## now handles *.abc correctly, not showing a file ending
  with .abcd. ##dir()## also now supports wildcard characters (* and ?) on all platforms.

=== Changes

* DOS support has been withdrawn. OpenEuphoria from version 4 onwards will not be specifically
  supporting DOS editions of the language.
* Comments may now be embedded in data passed to **value()** in **get.e**.
* Documentation moved to a new format.

=== New Programs

* ##eutest## - Unit testing system for Euphoria

=== New Features

* New standard include files are in ##include/std## to resolve many conflicts.
* Include file names with accent characters now supported.
* Enhanced symbol resolution to take into account information regarding which files were
  included by which files.
* Namespaces for a source file now can be used for identifiers in the specified file and for
  global identifiers in all files included by the specified file.
* Command line arguments for the translator allow for creating binaries with debugging
  symbols, and to specify a different runtime library.
* In trace mode, '?' will show the last defined variable of the requested name.
* Include directories can now be specified based on command line arguments and config files
  in addition to environment variables.
* Improved accuracy in scanning numbers in scientific notation. Scanned numbers are accurate
  to the full precision of the IEEE 754 floating point standard.
* New **loop do** ... **until** //condition// end loop construct, which differs from a while loop
  in that it performs its test at the end of the block, rather than at the start.
* New keywords to give greater control over the instruction flow:
** **continue**: start next iteration of a loop;
** **retry**: restarts the current iteration of a loop
** **entry**: marks the entry point into a loop, skipping initial test
** **break**: exit an if block or switch block
** **goto**: jump to a label that is in the same scope
* The **exit**, **break**, **continue** and **retry** keywords now can take an optional
  parameter, which enables to exit several blocks at a time, or (re)starting an iteration of
  a loop which is not the innermost one.
* Block headers now may mention a label. This label can be used as the optional parameter of
  flow control keywords.
* Variables can now be initialized right on the spot at which they are declared, just like
  constants.
* Any routine parameter can be defaulted, i.e. given a default value that is plugged in if
  omitted on a call. Any expression can be used, and parameters of the same call can even be
  used.
* New **switch** ... **end switch** construct, which more efficiently implements a series
  of **elsif**, using the compact **case** statement.
* **Unit testing added to Euphoria**.
* Condition compiling keywords (**ifdef**, **elsifdef**, **end ifdef**) and **with
  define=xyz** or command line **-D XYZ** to insert/omit code in interpreter IL code and
  in translated C code.
* New enum keyword that allows for //parse time// sequential constant creation.
* The namespace **eu** is predefined, and can be used to fully qualify built-in routines.
* ##with warning## has been enhanced in order to individually turn warnings on or
  off.
* New scope: **export**.  Identifiers with the export scope can only be seen from files that:
## directly include the file where the identifiers are defined
* New scope: **public**.  Identifiers with the public scope can only be seen from files that:
## directly include the file where the identifiers are defined
## directly include a file that uses the "public include file.e" construct to pass public
   identifiers
* Routine resolution changes
## Routines the same name as an internal no longer override the internal by default. You
   must use the keyword **override**.
## An unqualified call to routine that exists as an internal calls the internal unless
   overridden with the override keyword. global, public and export functions are not called. A
   namespace must be used.
* ##-STRICT## option added that will display **all** warnings regardless of the file's
  ##with/without warning## setting.
* ##-BATCH## option designed to run in an automated environment. Causes any
  "Press Enter" type prompt due to error to be suppressed. Exit code will be
  1 on success, 0 on failure as normal.
* ##-TEST## option allows for editing/IDE environments to perform a syntax
  check on the euphoria code in question. Causes euphoria interpreter to do
  all parsing, syntax checking, etc... but does not execute the code. Exit
  code will be 1 on success, 0 on failure as normal. Editors/IDE's may need
  both -test and -batch.
* dis.ex (in the source directory) will parse a euphoria program and output the symbol table
  and the IL code in a readable format.
* Variables may be in any part of a routine, or in **for**, **while**, **if**, **loop** and
  **switch** blocks, in which case the scope of the variable ends when its block ends.



!!CONTEXT:../docs/release/3.1.1.txt
%%output = release_3.1.1

== Version 3.1.1 August 2007

This release is a minor update to fix some bugs.

=== Bug Fixes

* **bug fixed: ** A storage leak (memory allocated
  but never freed) was introduced in version 3.1, on the Linux and FreeBSD
  platforms.  Fixed by Matthew Lewis.
* **bug fixed: ** When Euphoria failed to open the
  main program file, the error message would sometimes show the wrong file type.
  Fixed by Matthew Lewis.
* **bug fixed: **
  Bugs in the new library routines, find_from() and match_from() were corrected.
  The third argument (the starting index) is now tightly-checked.  Fixed by
  Matthew Lewis and Rob Craig.
* **bug fixed: ** The ed script on Linux was changed
  to allow blanks in the path of the file to be edited. Fixed by Rob Craig.
* **bug fixed: ** Double-quotes were added to ed.ex
  so Esc e will work with paths containing blanks.  Reported by Alex
  Caracatsanis. Fixed by Rob Craig.
* **bug fixed: ** database.e was fixed so forward
  slashes are allowed in the db_compress() file name. Reported by Frank Dowling.
  Fixed by Rob Craig.

!!CONTEXT:../docs/release/3.1.0.txt
%%output = release_3.1.0

== Version 3.1 June 2007

This release adds some new features, fixes some bugs, and improves the documentation.

=== New Features

* New built-in routines, **find_from()** and **match_from()** have been added.
  These work like find() and match() but they let you start searching from any
  element in the sequence, not necessarily at element 1.  This makes some
  algorithms simpler and much faster. Implemented by Matthew Lewis.
* When searching for an include file specified with a relative (i.e. not
  absolute) file path, Euphoria will check first for a file relative to the
  location of the current source file.  If not found, then the usual rules will
  apply, i.e. it will check relative to the main program file, then check the
  EUINC directories (if any), and finally euphoria\include.  Suggested by C.K.
  Lester and, in various forms, by several other people. Implemented by C.K.
  Lester.  Checked in by Matt Lewis.
* **ex int.ex** (in euphoria\source) will now work, since the interpreter now
  supports machine_proc(65,...) which passes IL to the fast C-coded back-end. You
  can also run int.ex with eui.  This lets you easily modify the front end and
  get a modified Euphoria interpreter, for all platforms, that runs programs at
  full speed (much faster than the Euphoria-coded execute.e). You might also bind
  int.ex to get a single executable file for whatever platform you like.
* If the user does not supply a filename with an extension, Euphoria will attempt
  to open the file first with the standard extension for its respective platform,
  but if it does not find it, it will also look for files with the standard
  extensions for the other platforms. Implemented by Matthew Lewis.
* **Translator: ** The limit on the number of additional .c files that can be
  created per Euphoria file has been raised from 36 to well over 1000.

=== New Documentation

* The "storage cache" compression technique that's used for bound executables and
  .il files, was documented in comments added to compress.e.  It reduces the size
  of the IL by 30% or more, while allowing fast decompression.
* A documentation file, tasks.doc, was added to euphoria\demo\langwar.
  It describes the multiple tasks used in Language War.

=== Bug Fixes

* **bug fixed: ** **Translator: ** Translated code for routine_id() erroneously
  returned -1 when a global symbol was looked up which matched a symbol in the
  same file as the call to routine_id(), as well as a global symbol in another
  earlier file. It was treated incorrectly as a multiply-defined symbol that was
  lacking a namespace qualifier. Thanks to Daniel Kluss.
* **bug fixed: ** **Translator: ** In rare situations, a naming conflict could
  occur when more than one .c file is created for a Euphoria file.  Thanks to DB
  James.
* **bug fixed: ** **Translator:** get_key(), when translated/compiled with
  Borland or LCC, required an extra keystroke after a carriage return.
  Implemented by Jacques Deschenes.
* **bug fixed: ** **Source Code Portability:** euphoria.h: CLK_TCK is now defined
  as CLOCKS_PER_SEC if not defined previously in the source. Implemented by Matt
  Lewis.
* **bug fixed: ** **Installer:** Double-quotes were added around several
  filenames used in the INNO installer script (though this did not seem to affect
  many people).



!!CONTEXT:../docs/release/3.0.2.txt
%%output = release_3.0.2

== Version 3.0.2 February 9, 2007

This release fixes some important bugs in 3.0.1, and improves the source code documentation.

=== Bug Fixes

* **bug fixed: ** **Translator: ** Programs translated to C and compiled for
  Windows would crash if they used the new multitasking feature.  (This worked in
  3.0.0 but was broken accidentally in 3.0.1 because some stack offsets
  changed.)
* **bug fixed: ** **Interpreter: ** In fairly rare situations, the interpreter
  for Windows might crash.  This was due to a bug in load_private_block() where
  it was freeing a block of memory and then returning a pointer into that
  block.  In rare cases, a page of virtual memory might be removed from the
  heap by the Windows O/S before the block could be read.  Thanks to Andy
  Serpa, Pete Lomax, Matt Lewis, Derek Parnell, and others for helping to
  pin-point the location of the bug.
* **bug fixed: ** **Source Code: ** "\euphoria" was changed to to %EUDIR% in 4 .bat
  files in the source directory. Thanks to Jaime Marcos.

=== Improved Documentation

* A new document (translator.doc) was added to euphoria\source. It describes
  the internals of the Translator, with emphasis on the many optimizations
  that the Translator performs.
* The user documentation was also improved in a few places.

=== C Source Code Changes

* Matthew Lewis added a Linux/FreeBSD make file, and made source code
  changes to better support Open Watcom and a newer version of GCC.


!!CONTEXT:../docs/release/3.0.1.txt
%%output = release_3.0.1

== Version 3.0.1 November 3, 2006

This release cleans up a number of bugs and documentation errors in 3.0.0.

=== Improved Documentation

* A separate new document on [[:multitasking]] was added.
* Obsolete pre-open-source concepts in the 3.0.0 documentation were deleted or
  corrected.

=== Bug Fixes

* Euphoria-coded .dll / .so files were not working at all, due to a
  multitasking-related glitch. Thanks to Andrea Cini.\\
  \\
  Note: execution of multitasking built-in routines is currently not
  supported inside a Euphoria-coded .dll / .so.
  You'll get a compile-time error message from the
  Translator if you use the -dll option and your library source code
  contains multitasking operations. Other than that, use of
  Euphoria-coded .dll / .so files by main programs that do
  multitasking is fine.
* A text console bug was fixed.  It involved output to the screen involving tabs
  and/or wrap-around (at 80 columns). Thanks to Pete Lomax, Juergen Luethje, Matt
  Lewis.
* bind.bat, bindw.bat and shroud.bat were changed to use %EUDIR% rather than
  \EUPHORIA. Thanks to Ray Smith.
* syncolor.e now includes keywords.e (relative to euphoria\bin)
  rather than \euphoria\bin\keywords.e. Thanks to Rick Bettis.

=== C Source Code Changes

* All of the #ifdef ENCURSES code was stripped out.  We don't plan to use ncurses
  again, and this change makes parts of the source code much more readable.
* A thread5() machine language macro was added to be_execute.c This helps the
  interpreter to compile correctly with Open Watcom, avoiding a C optimizer bug.
  Thanks to Matt Lewis.


!!CONTEXT:../docs/release/3.0.0.txt
%%output = release_3.0.0

== Version 3.0.0 October 17, 2006

With this release, Euphoria has become a totally **free**
and totally **open source** product! RDS will continue to develop
Euphoria with the aid of many additional clever programmers.
The free download package now includes the Interpreter (with either
a C or a Euphoria-coded back-end), Binder/shrouder, fully-enabled
Translator, and the full source code for all of these.
Thousands of people can now examine the full source code for bugs,
performance improvements, and potential new features.

Rather than having alpha, beta and official releases, we will now
simply have numbers, 3.0.0, 3.0.1 ... We expect to have releases
more frequently, though each release will likely be a smaller
change compared to the previous release.

=== Enhanced Features

* **Cooperative Multitasking**. Rather than having just a single thread of
  execution, you can now create multiple tasks that run independently of one
  another. Each task has its own currently-executing statement, subroutine
  call-stack, and private variables for all routines on its call-stack. Tasks
  share global and local variables but not private variables. At any point during
  its execution, a task can call task_yield() to transfer control to the Euphoria
  scheduler which will choose the next task to run. When control returns to the
  original task, execution will continue from the statement after task_yield().
* New Run-time routines: task_create(), task_schedule(), task_yield(),
  task_suspend(), task_self(), task_list(), task_status(), task_clock_start(),
  task_clock_stop()
* Use of the **ncurses** library has been eliminated for Linux and FreeBSD.
  ncurses routines sometimes caused problems on some Linux/FreeBSD systems.  The
  Euphoria backend now uses ANSI escape chars to get 2-d positioning and colors
  for a plain text-mode console.  Also, the use of libgpm (console mouse support)
  has been dropped on Linux.  (It was never supported by Euphoria on FreeBSD).
* **Include files** with the same file name but a different path as an earlier
  include, will no longer be ignored. To be ignored, an include must refer to the
  exact same file as an earlier include.  (a new name space can still be defined,
  even though the include file is not actually included again.) On Linux/FreeBSD
  a case-sensitive file-name comparison is now used.\\
  \\
  There is possible (but unlikely) breakage of old code:\\
  \\
  You might start including files that you did not intend to include, if you have
  a previously-ignored include statement for them in your code.  Solution: Delete
  the undesired include statement.\\
  \\
  If an include is incorrect (file is not on the include search path), this error
  may have been hidden under the old system, if a correct include with the same
  file name (but different path) came earlier. Solution: Specify the correct path
  to the include file.
* There is no longer a limit on the number of **warnings** that can be displayed.
  Instead, you will be given the chance to scroll through all the warnings, 20 at
  a time. As before, if a ex.err file is created, then all warnings will also be
  stored at the end of the ex.err file.  Thanks to Judith Evans.
* **Translator**: You can set the run-time stack size for your program using the
  -stack nnnn option. The default stack size has been increased for most of the
  supported C compilers, especially when your program contains a call to
  task_create().
* If a run-time error occurs and ex.err can't be opened, a check will be made to
  see if it's because you have **too many open files**. An appropriate message
  will then be issued. Several people ran into this situation.
* **execute.e**: Additional run-time error checks were added to several run-time
  routines to allow the pure-Euphoria source interpreter to catch more errors
  itself, rather than letting the C-coded run-time routines used by the "real"
  interpreter or translator catch them.
* **pretty_print()**, option 3, now includes \t \r and \n as valid "ASCII range"
  characters. This increases the likelihood of strings being displayed. Thanks to
  Juergen Luethje.
* The **ASCII 127** char will not be graphically displayed on Linux in trace or
  in default pretty_print(). It displays as a backspace when ANSI codes are used.
* **Binder** options are checked more strictly. e.g. -xxxoutxxx was dangerous The
  binder now looks for match(x,y) = 1, rather than match(x,y) != 0.  The binder
  also avoids overwriting a source file when -out is used.  Thanks to Mike Sabal,
  Greg Haberek
* We've switched to using transparent Euphoria icons. Thanks to Vincent Howell.
* Pure Euphoria interpreter (eu.ex): The "not initialized" message has been
  improved to: "xyz has not been initialized"
* Many small improvements were made to the **documentation**. e.g.  the use of a
  single atom value by multiple printf() formats was documented for the first
  time. Thanks to Pete Lomax.

=== Bug Fixes

* **bug fixed: ** **Translator**: a Euphoria file named "main.e" or "init.e"
  could possibly lead to a file naming conflict. The chance of a conflict is now
  greatly reduced, and if a conflict occurs, a meaningful error message will be
  issued.  Thanks to Vincent Howell.
* **bug fixed: ** **Translator**: using "interrupt" as a Euphoria variable name
  caused a naming conflict when compiling with Watcom. Thanks to Louis Bryant.
* **bug fixed: ** **Translator**: A backslash at the end of a Euphoria comment
  could be considered a line continuation character by the C compiler. This could
  result in incorrect code being generated. Thanks to Mark Honnor.
* **bug fixed: ** **Translator**: A call to a Euphoria-coded routine in a .dll,
  i.e. via c_func(), could cause a bug if the return type was sequence or object.
  Thanks to Thomas Jansen.
* **bug fixed:** If you pass file number -1 to **printf()** you will now get a
  run-time error report.  In all previous releases, -1 would simply cause
  printf() to produce no output. Thanks to Daniel Kluss.
* **bug fixed:** scanner.e: Source lines longer than 10000 characters caused a
  problem.  Also we were not checking for allocate() returning 0 in pack_source()
  (i.e. out of memory condition). Thanks to Antonio Alessi.
* **bug fixed:** **execute.e**: (pure Euphoria interpreter) In some cases slice
  indexes were not being bounds checked before being used. eu.ex would crash
  rather than report the error in the user's program.
* **bug fixed:** Assignments of the form: **x[a][b..c] += expr** were likely to
  trigger an erroneous subscript error in **execute.e**, the pure Euphoria
  interpreter. Thanks to Vincent Howell.10813
* **bug fixed:** **execute.e** did not handle fractional subscripts correctly in
  some situations.  Thanks to C Bouzy and Vincent Howell.



!!CONTEXT:../docs/release/2.5.0.txt
%%output = release_2.5.0

== Version 2.5 March 8, 2005

=== Enhanced Features

* The Source Code Product now includes the C code for interactive
  trace/debug and profiling. This was not provided in any previous release.
* **Translator**: A new **-fastfp**
  option has been added for WATCOM/DOS (registered version only).
  This option can double the speed of a floating-point intensive,
  translated/compiled, program. The resulting .exe file requires a
  Pentium class CPU, or a 386/486 with floating-point hardware.
* **eu.ex**: execute.e now uses call-back machine code supplied by
  Matthew Lewis. As a result, there is no longer a limit on the number
  of call-backs a program can use.
* **Translator**: There is now a **-keep** option that prevents the deletion
  of any C files or object files created during translation. Thanks to Matthew
  Lewis.
* **Translator**: In order to handle huge programs without exceeding the limits of
  the C compiler, the translator will split init_.c into several pieces. Thanks to
  Matthew Lewis.
* **Translator**: Better checking is provided for incorrect command-line options.
* **Translator**:  The translator avoids creating any files until it confirms that a
  valid source file has been provided on the command line, or via the interactive
  prompt.
* **ed.ex**: **ed** will only call free_console() at the end of execution
  on Linux or FreeBSD. It was causing a slight screen flicker on DOS/Windows,
  and was not necessary.

=== Bug Fixes

* **bug fixed**: The error traceback from a bound or shrouded program had garbage showing
  for the file names and line numbers. This bug was introduced in the beta release.
* **bug fixed**: Bound or shrouded programs were not starting off with a fresh random seed
  value. Normal interpreted or translated programs were OK. Thanks to Michael Bolin.
* **bug fixed**: The error traceback could be wrong if you (illegally) tried to pass a
  sequence as the routine id for call_proc/func. Thanks to Mario Steele.
* **bug fixed**: When displaying a large variable value during interactive trace, the first
  few lines might be printed in white, while the rest was printed in bright white.
  Thanks to Al Getz.
* **bug fixed**: routine_id() of the form: routine_id("namespace:name") was not working
  correctly in the interpreter or in the PD source interpreter. The Translator was ok.
  This worked fine in 2.4 and earlier. Thanks to Verne Tice.
* **bug fixed**: command_line() now shows the extra file name when the user types the file
  name interactively at the ex/exw/exu prompt. This is now compatible with 2.4 and earlier.
  Thanks to Bob Elia.
* **bug fixed**: Warnings were not getting reported when a program ended with a call to abort(),
  or it ended with a fatal run-time error. Thanks to Juergen Luethje.
* **bug fixed**: The platform() function is now evaluated in backend/backendw/backendu for .il
  files (rather than in the front-end of the shrouder). This allows a .il file to be
  portable to multiple platforms. In other situations, the interpreter
  and translator will continue to evaluate platform() in the front-end
  for maximum efficiency. Thanks to Ken Rhodes

=== Documentation

* Many small corrections and improvements were made to the documentation.
  Some important ones were provided by Juergen Luethje and Wolfgang Fritz.
* A paragraph was added to the Reference Manual explaining what happens
  when you try to modify a variable by function side-effects at the
  same time that you try to modify it via subscripted assignment.
  The 2.5 alpha release notes were updated to point out an
  incompatibility with 2.4.


!!CONTEXT:../docs/release/2.5.0b.txt
%%output = release_2.5.0b

== Version 2.5 Beta January 14, 2005

=== Improved Performance

* The initial parse time (start-up time) of interpreted programs
  has been reduced, typically by 25% on newer machines, and 40% on older
  machines, when compared to 2.5 alpha.  In the case of old machines running
  very large programs, the start-up time can be 65% to 90% less, especially when
  ##with trace## or ##with profile## are in effect.
* Most of the optimizations were made to the Euphoria front-end
  source that's shared with the Public Domain source interpreter, so **eu.ex**
  also has reduced parse times.
* A major speed improvement was made in opASSIGN_SUBS() in the PD source
  interpreter. This operation handles assignments to subscripted sequences, and
  is executed a lot. Thanks to Greg Haberek for showing the slowness.
* **Translator**: In many more cases, the **Translator** now knows the type of all
  elements of a sequence. This is especially useful when the elements are known to be
  integers. Smaller and faster code is generated for accessing the elements, and freeing
  the sequence.
* In most cases, the **Interpreter** and the **Translator** now evaluate
  sequence-formation {a, b, c, ...} expressions once at compile-time, instead of
  each time at run-time, when the elements are all constant integers (either
  hard-coded numbers or symbols declared as constant). This saves time, and also
  reduces code size for translated programs.
* **database.e**: **db_select_table()** returns quickly if you happen to select
  the table that's already selected. This can save a lot of time in situations
  where it's not convenient for the application to keep track of which table is
  currently selected.  Thanks to Derek Parnell.

=== Enhanced Features

* The **shrouder** will now supply a default **#!** (shebang) line at the top of
  the **.il** file, if none was specified. Thanks to Kenneth Rhodes.
* On **Linux**, the **shrouder** will give the **.il** file execute permission.
  Thanks to Kenneth Rhodes.
* On **Linux/FreeBSD** the **Binder** no longer creates bound executable programs
  with a ".exe" extension. Now, no extension is used. This is compatible with the
  **Translator**, and more in keeping with the standard on **Linux/FreeBSD**
  systems. Thanks to Jerry Story.
* **database.e**: Extra checks were added to some routines to give a more
  meaningful error message when no table has been selected yet. Thanks to Derek
  Parnell.
* Several small improvements in the Source Code product and its documentation
  make it easier to compile using Open Watcom and other compilers. Thanks to
  Jean-Marc Duro.
* The main source file is now closed right after the front-end finishes.  This
  allows a program to edit or otherwise modify its own source.
* The initial random seed value is now chosen more randomly
  on **Windows**. Thanks to Yuku Sugianto.

=== DOS/Windows Installation Program

* The install program will set up ed.bat to run ed.ex with ex.exe on ME/98/95,
  and exwc.exe on NT/2000/XP.
* The **install** program will not change any existing file associations for
  Euphoria file types. (If you install Euphoria in a new directory, you might
  have to change these yourself.) Thanks to Juergen Luethje and others.
* The Start Menu links created by the **install** program were wrong: exw was
  incorrectly pointing to **ecw.exe**, and ex was incorrectly pointing
  to **ec.exe**. Thanks to Yuku Sugianto.
* It's ok now to have a blank in the path of the installation directory: e.g.
  "C:\Program Files". Thanks to Rich.

=== Bug Fixes

* **bug fixed**: When building a Linux/FreeBSD .so file from Euphoria code that
  contained **call_proc()** or **call_func()**, an undefined "~_~_stdcall" symbol
  appeared in the C file by mistake. Thanks to Matt Lewis.
* **bug fixed**: The opening message displayed by the Binder on Linux/FreeBSD and
  on Windows was wrong.  Thanks to Kenneth Rhodes and Igor Kachan.
* **bug fixed**: **routine_id()** was checking for symbols coming later in the
  code. This happened in the Interpreter only, and only at the top-level, not
  inside a routine.\\
  This fix requires .il files shrouded with 2.5 alpha to be reshrouded
  with 2.5 beta or later. Bound files are not a problem.
* **bug fixed**: A complex expression on the left hand side of an assignment, involving
  nested use of ##$##, could crash. Thanks to Andy Serpa.
* **bug fixed -  Translator: ** A call to **routine_id()** would sometimes search
  past the end of a list and start reading garbage in memory. In most instances
  this did not cause a problem, but in some cases it could cause a crash. Thanks
  to Kenneth Rhodes.
* **bug fixed -  Translator: ** In a rare situation, the 2.5 alpha Translator
  could crash while attempting to optimize some code.
* **bug fixed -  Translator: ** In a rare situation, at the end of execution of a
  particular routine, the translated code would fail to free some space used for
  a temporary value.  Thanks to Wolfgang Fritz.
* **bug fixed**: After a compile error in **exw** you would have to hit Enter,
  then a message would say: "Press Enter...".  (Things worked properly for
  run-time errors).  Thanks to Tone Skoda.</li>
* **bug fixed**: An incompatibility existed between the way that **abort(1)** was
  handled in the Translator vs the Interpreter. Thanks to Juergen Luethje.
* **bug fixed**: **save_text_image()**, when run by **exw** or **exwc**,
  occasionally returned some garbage in the upper bits of the character
  attributes. Thanks to Brian Broker.
* **bug fixed**: The CAPS lock key generated a key code when using **ed** with
  **exwc**. The key had the desired effect, but it caused **ed** to display a message
  at the top of the screen. **ed** will no longer display the message. Thanks Alex
  Caracatsanis.
* **bug fixed**: **routine_id("")** would crash the Binder and Translator. Thanks
  to Antonio Alessi.
* **bug fixed**: A line longer than 200 chars crashed the **trace** display.
 Thanks to Thomas Betterly.
* **bug fixed**: Symbols declared as constant were not defined in the **trace**
  window.  Thanks to Matthew Lewis.
* **bug fixed**: **printf()** format strings were wrong in two error messages in
  **execute.e** &nbsp;Thanks to Derek Parnell.
* **bug fixed**: The caret (arrow) symbol,
  displayed in compile-time error messages, was shifted one position to the
  right, when compared with version 2.4. This has been corrected.  Thanks to
  Juergen Luethje.
* **bug fixed**: For compatibility with the official Interpreter, routine id's
  now start at 0 instead of 1 in the PD source interpreter.

=== Documentation

* A paragraph was added to "Scope" discussing how you can override predefined
  routines with your own variables and routines.  Thanks to Mike.
* A warning was added to **open()** about the use of CON and CON.*, and other
  file names that are reserved by DOS.  Thanks to Igor Kachan.
* The fact that programs are now fully parsed before being executed was explained
  better in the Reference Manual.
* Obsolete uses of the phrase "Complete Edition" were removed from a few places
  in the documentation. Thanks to Juergen Luethje.
* Various documents were fixed where miscellaneous 2.4 information
  has now become now obsolete.
* The Reference Manual said that the limit on nested include files was 10 deep.
  It should have said 30 deep. Thanks to Darkvincentdude.
* In the PD source interpreter, **eu.ex**, there was an error in the
  comments at the top. Thanks to Yuku Sugianto.
* The fact that **crash_message()** is now only useful for run-time errors was
  made clear. Thanks to Juergen Luethje.
* A bad HTML link to the WIN32 API .hlp file was fixed.  Thanks to "Bro
  George".
* Many other minor clarifications were made.



!!CONTEXT:../docs/release/2.4.0.txt
%%output = release_2.4.0

== Version 2.4 July 3, 2003

* **define_c_proc()** and **define_c_func()** have been extended, so in
  addition to defining C routines in external .dll's and shared
  libraries, you can now define the parameters and return value for a
  machine-code routine that your program pokes into its own
  memory. You can call the machine-code routine using **c_proc()** or
  **c_func()**. Thanks to Daniel Kluss.

* Performance Improvement: **get4()** and **put4()** in **database.e**
  have been sped up slightly. They are very important to the overall
  speed of **EDS**. Thanks to Derek Parnell.

* Performance Improvement: **get_bytes()** is now much faster when the
  number of bytes requested far exceeds the number of bytes remaining in
  the file. Thanks to Pier Feddema.

* **Translator**: When translating a huge Euphoria routine (many
  hundreds of Euphoria statements), the Translator will now output
  calls to a dereference routine, rather than using in-lined C
  statements. This reduces the chance of exceeding a size limit
  imposed by the C compiler (especially Watcom C). It also reduces the
  **.exe** size. Since the dereference routine is more likely than the
  in-lined statements to be in cache, the speed difference is not that
  great.

* **Interpreter Source Code**: In **watexw.bat**, **runtime
  windows=4.0** was added to the link command for building
  **exw.exe**.

* There are now some checks for invalid argument type and invalid
  return type in calls to **define_c_func()** and **define_c_proc()**.

* Some syntax error messages are now more descriptive when namespace
  identifiers are involved.

* The filesort.ex tutorial program was altered to make it more usable
  under Linux and FreeBSD.

* By default, **safe.e** now does a less-strict, "edges-only" check for
  memory corruption, when the platform is **WIN32**. Windows programs
  often access memory that was not allocated using Euphoria's
  **allocate()**.

* **bug fixed**: When a literal floating-point constant in the Euphoria
  program was larger than about 1e308, the Translator would output
  "inf" in **init_.c**. This caused the C compiler to issue an
  undefined symbol error. Thanks to Juergen Luethje.

* **bug fixed**: In a rare case, the Translator was failing to emit C
  code to make a copy of a sequence with multiple references to it,
  before overwriting an element of that sequence. Thanks to Juergen
  Luethje.

* **bug fixed**: In certain cases, when a Euphoria program exchanged
  Euphoria data with a **.dll** written in Euphoria, the data might
  not be freed (until the program terminated). Thanks to Wayne
  Overman.

* **bug fixed**: If you used "asm" in your program, as a private
  variable or parameter name, the Translator would use "_asm" in the C
  code. This was not acceptable for some C compilers. The Translator
  will now avoid using "_asm", as well as "_try", "_Seg16", "_stdcall"
  and several other single-underscore names that are reserved by
  various C compilers. Thanks to George Papadopoulos and Matt Lewis.

* **bug fixed**: If the HOT_KEYS parameter in **ed.ex** was set to
  FALSE, then **Esc h Enter** would not bring up the help
  prompt. Thanks to J. Brown.

!!CONTEXT:../docs/release/2.4.0b.txt
%%output = release_2.4.0b

== Version 2.4 Beta April 10, 2003

This release updates the **Euphoria Interpreter**, the **Euphoria To C
Translator**, and the **Interpreter Source Code** products, for **Windows**,
**DOS**, **Linux** and **FreeBSD**.

=== New Features

* **bind** and
    **shroud** now have an option
    ##-out## for specifying the output file,
    so you won't be prompted for it. Thanks to Jonas Temple, Rusty Davis
    and others.

* **bind**
    and **shroud** now have an option
    ##-quiet## that suppresses normal messages
    and statistics, and therefore eliminates the window that normally pops up.
    Only errors are reported. Thanks to Jonas Temple.

* The namespace error message that's issued when you refer to a global
    symbol that's defined in two or more files, now
    gives you a list of all the files where that symbol
    has been defined. Thanks to Derek Parnell and Irv Mullins.

* **Translator**: In many cases,
    the C code generated for **remainder()**,
    integer multiplication, and **compare()**
    is smaller and faster.

* **exw, ecw -wat**: Deallocation of space for huge numbers of small
    objects (atoms or small sequences) is much faster than in 2.4 alpha.
    Thanks to Andy Serpa.
    (Note that //allocation// of huge numbers of small objects in **exw**,
    or **ecw -wat**, became much faster in 2.4 alpha,
    and remains much faster.)

* When an **ex.err** file is created,
    any warnings issued against the program will be listed at the end of
    the **ex.err** file. Thanks to Al Getz.

* The file name is now included in the warning message that you get for
    some of the common warnings (variable not used, variable not assigned to).
    Thanks to Al Getz.

* **New Icon**: On
    **Windows**, Euphoria include files are
    now labelled with a gray-scale version of the Euphoria ##E)## icon.
    This lets you easily distinguish the executable Euphoria files from the
    include files. Thanks to Wolfgang Fritz.

* Out-of-bounds floating-point subscript values
    were being reported after rounding down to an integer.
    Now the value before rounding is reported.

* **Euphoria Database System (EDS)**:
    **db_rename_table()** now checks to see
    if the target table name already exists, before it renames a table.
    Thanks to Mike Nelson.

* The first value returned by **rand()**
    (in the absence of **set_rand()**)
    is now more "random". Thanks to Yuku Sugianto.



=== Bug Fixes


* **bug fixed**: Due to a change made in
    2.4 alpha, the **dir()** routine
    for Borland and Lcc was concatenating the file attributes
    characters (if any)  to the file name field.
    Thanks to Dr. Juan R. Herguijuela.

* **bug fixed**: No error message was
    issued when ',' was followed immediately by ')' in a routine's parameter
    declaration list. Thanks to Brage Moris.

* **bug fixed**: Huge positive out-of-bounds
    subscripts (over 2 billion) were reported as huge negative values.

* **bug fixed**:
    **repeat(0, size)**, where size was a
    huge positive floating-point number, incorrectly reported:
    "repetition count must not be negative". Now it reports:
    "repetition count is too large". Thanks to Martin Stachon.

* **bug fixed**:
    **machine_proc(x, 5)**, where x was a huge
    floating-point number, incorrectly reported:
    "an integer was expected, not a sequence".
    Now it reports: "The first argument to machine_proc/func must be a small
    positive integer". Thanks to Martin Stachon.


!!CONTEXT:../docs/release/2.4.0a.txt
%%output = release_2.4.0a

== Version 2.4 Alpha February 21, 2003

=== New Features

*  Most machine-level exceptions (peek/poke to bad addresses etc.)
  in both the main program and in .dlls, are now caught by
  **exw**
  and **exu**,
  and reported in the usual way, with a full traceback and
  **ex.err**
  variable dump. This is a great improvement over the cryptic
  machine-level messages you used to get (and still get when using
  compiled languages, and most interpreted languages) about
  "segmentation violation", "illegal instruction" etc.).
  Thanks to Martin Stachon.

*  In addition to ##stdcall##, the C ##cdecl## calling
  convention
  is now supported for calls to C routines in .dll's and also call-backs
  to Euphoria routines from C code.

*  Euphoria's support for DOS long filenames has been extended to
  Windows XP.

*  The **trace** screen shows you large
  sequences in pretty-print display on a separate
  screen. You can scroll through the whole sequence.

*  **pretty_print()** was added to
  **misc.e**.
  It lets you display Euphoria objects
  with a nice, readable structured display, and many formatting options.

*  Pretty-printing of sequences is now done in
  **ex.err**,
  the **?** command, and
  **db_dump()**.

*  **Euphoria Database System (EDS)**:
  **db_rename_table(name, new_name)**
  was added to **database.e**.
  This routine was submitted by Jordah Ferguson, and included
  with only trivial changes.

*  **Linux/FreeBSD**:
  **system()** no longer initializes
  curses when there is no console window yet. Thanks to Daniel Johnson.

*  The number of levels of nested include files has been raised to 30 (from 10).
  Thanks to Tone Skoda.

*  Include statement path names can have double-quotes around them,
  so paths containing blanks can be handled correctly. This was
  actually implemented for 2.3 but never documented.

*  **exw.exe**, and any executables
  produced by the **Translator** with Watcom,
  now have the subsystem set to 4.0 instead of 3.1. This improves the
  appearance of GUI's in some cases. The utility
  **make31.exw** will
  create a version of **exw.exe** that
  supports Windows GUI 3.1 as before,
  in the unlikely case that there are compatibility problems with
  Euphoria 2.3. Thanks to H. W. Overman, Brian Broker and others for
  recommending this change.

*  **makecon.exw** - will create a version
  of **exw.exe** that
  operates as a console application - no console window is popped up,
  and **stdin/stdout** can be redirected

*  **trace(1 2 and 3)** are now allowed
  with **bind -clear**
  (still not allowed with **shrouded bind**
  for security reasons). Thanks to Jonas Temple.

*
  **Translator**: You can now make a
  Euphoria .dll using Lcc and interface it with interpreted programs running
  under **exw**, and translated programs
  using Borland and Watcom. Previously, the main program had to also be
  compiled with Lcc.

*  The **Translator** no longer uses
  the **-m486** or **-mpentium** options available with
  GCC and DJGPP.
  These options were causing warnings, and the C compiler apparently
  sets the machine model correctly by itself. Thanks to Kenneth Rhodes.

*  The **Translator** will now perform
  automatic calls
  to user-defined types, in the
  unusual case where the type routine has side-effects (it sets global
  variables, performs I/O etc.). Thanks to Andy Serpa.

*  **euphoria\demo\bench** compares
  the
  **Euphoria Interpreter** and the
  **Euphoria To C Translator** against
  more than 20 other interpreted languages.



=== Porting Activity

* We ported the **Interpreter**
  and **Translator**
  to **FreeBSD.**
  The source now has several C #ifdef's for FreeBSD.

* Andy Cranston has ported Euphoria to HP Unix, and he plans to do
  Sun Unix.



=== Optimizations

==== Interpreter


*  Typical large slices are faster.
  About 30% faster for slices from about 100 to 50000 in length.
  (Overhead dominates for smaller slices, and lack of caching
  affects larger slices.)
  This assumes the slice is mostly integers (usually true),
  and an actual copy of the data is made (usually true since v1.4b).

* Statements that contain multiple ##&## concatenations are much faster.

  {{{        e.g. instead of:
             **result = a & b & c**
             being evaluated as:
               1. copy a and b into temp
               2. copy temp and c into result
                  (a and b are effectively copied twice!)

             We now do:
               1. copy a and b and c directly into result
  }}}

  So there is less copying of data and fewer temp sequences to create.
  The more ##&## operators in an
  expression, the greater the speed-up. e.g. with 3
  ##&## operators some of the data
  was copied 3 times, etc.
  Jordah Ferguson pointed out that this was slow.

* The time overhead involved in calling and returning from a
  Euphoria call-back routine has been reduced by about 10 percent.

* In **exw** and **ecw -wat**, allocation of space for large numbers of
  objects is faster. It can be tremendously faster when hundreds of
  thousands or millions of objects are involved.

* Better UPX compression has chopped a few K off
  **exw.exe** vs. 2.3
  (even though new code was added). Thanks to Wolfgang Fritz


==== Euphoria Database System

* Keys and records are read faster due to a faster
  **decompress()** routine.
  Almost twice as fast when the key or record data to be retrieved
  consists mainly of sequences of characters or small integers.
  This case is quite common.

* Allocating new space in a database is much faster, up to 4x faster,
  especially in large databases with a large list of free blocks

* Inserting and deleting records in huge tables is now much faster.
  Combined with the speeded-up slices in Euphoria 2.4,
  **database.e** is
  now about 25% faster for a table with 10,000 records and
  over 3x faster for a table with 100,000 records.
  This really only matters if you are trying to insert/delete hundreds
  of records per second. In the typical case of a human operator
  entering data via GUI, you would never notice the insert/delete time
  for one record (a few milliseconds). Derek Parnell pointed out the
  slowness.

* **db_select_table()** is significantly
  faster.

* **get4()** is faster which speeds up
  everything.

==== Other Optimizations

* **bytes_to_int()** in
  **machine.e** is now more than twice as fast.

* **gets()** is about 5% faster

* **sort()** and
  **custom_sort()** are a few percent faster.
  Thanks to Ricardo Forno for tweaking the Shell sort algorithm.

* Several additional optimizations have been added to the
  **Translator**.
  It produces executables that are faster and smaller
  than version 2.3. The 2.4 Translator has been successfully tested
  on hundreds of thousands of lines of Euphoria code, and there are
  currently no known code generation bugs. Some Translator
  benchmark results are in
  **euphoria\demo\bench**.


=== Bug Fixes


==== Source Code


* **bug fixed**: The
  **gnubsd** batch file referred to
  **syncolor.c** and
  **syncolor.o**.
  (**gnuexu** was ok.)

* **bug fixed**: Karl Bochert pointed out a necessary C coding
  change to make **poke()** work with
  the latest version of Lcc. The change
  corrected the **Translator** (with
  recent versions of Lcc) and the **Interpreter
  Source Code** (compiled with Lcc)


==== Interpreter


* **bug fixed**: A crash might occur in situations where a call-back routine
  indirectly called itself recursively. Thanks to Matthew Lewis
  and George Papadopoulos.

* **bug fixed**: In for-loops at the top-level of a program
  (outside of any routine),
  that incremented the loop variable by an integer other than the default
  of +1, ##end for## was taking up to
  15x longer than necessary due to a
  bug fix that was made back in November 1999. Only the
  ##end for##
  itself was slow, not the code contained in the body of the loop.
  Antoine Tammer detected this.

* **bug fixed**: On XP, when you open a new DOS window that has more than 25 lines,
  the Virtual DOS Machine (VDM) is at first confused about the true number
  of lines. The first time (only) when you ran a Euphoria program in
  that window, if you ran it near the very bottom of the screen, the output
  might disappear, or the VDM or Euphoria might report an error etc.
  Euphoria (**ex.exe**) now detects the
  rare cases when VDM is
  confused and clears the screen, which clears up the confusion.
  A similar problem existed on NT, and was fixed a few years ago.

* **bug fixed**: The interpreter was referring
  to "call back from Windows" in **ex.err**,
  even on Linux or FreeBSD. It now says "call-back from external source"
  on those systems. Thanks to Pete Eberlein.

* **bug fixed**: When an include file couldn't
  be found, the error message
  referred to "euphoria\include". It now uses %EUDIR%\include

* **bug fixed**: An error message will no longer be generated on any platform
  for ##without profile_time##. Thanks to Alan Oxley.


==== Translator


* **bug fixed**: When assigning
  the result of an arithmetic calculation (typically multiply)
  involving two integers, to a variable declared as atom,
  where the atom variable had already (in the same basic block)
  been assigned an integer value, the Translator might
  not output any code to check for integer overflow (result outside
  of +/- one billion). This could cause a crash. Thanks to Andy Serpa.

* **bug fixed**: DJGPP strip.exe command
  in **emake.bat** would fail on XP,2000 due to
  a bug in DJGPP.
  Now **emake.bat** has: **SET LFN=n**
  to work around the bug in strip.exe

* **bug fixed**: Translated code compiled
  with Borland C was not producing
  INF's and NAN's, like Watcom and Lcc. Rather, it was crashing when
  a floating-point overflow (over 1e308), or an undefined f.p.
  result was calculated. The **Interpreter Source
  Code** was also
  corrected for those who wish to compile **exw.exe**
   using Borland.
  Thanks to Andy Serpa.

* **bug fixed**: In the first basic block
  of a Euphoria routine (i.e. before any control-flow statements),
  **peek4u()**, <font color="#006699">
  **peek4s()**, and the
  "add integer 1" operation, would sometimes neglect to check for
  possible 31-bit integer overflow when assigning to a private variable
  declared as atom, unless the variable had been previously
  initialized. Thanks to Mike Duffy.

* **bug fixed**: In some cases, when
  assigning a sequence element
  to a variable declared as integer, and known to have an integer value
  at this point, the case where the element was an integer value stored
  in C double form was not handled correctly.

* **bug fixed**: In rare cases, the
  translator might output two unary minus operators
  in a row, which would be parsed by a C compiler as the
  C decrement operator "--".

* **bug fixed**: Euphoria .dll's were not
  always correctly freeing storage
  allocated by the main program, and vice versa. Memory could be wasted,
  and you might get a machine-level crash. Thanks to H. W. Overman.

  **Note:** Due to this fix, any Euphoria .dll's created with the
  Translator version 2.3 or earlier, must be re-translated with 2.4,
  and re-compiled, in order to interface with the Euphoria 2.4 (or later)
  interpreter or translated code. New .dll's created with version 2.4
  or later, will not work with the interpreter version 2.3 or earlier,
  except in trivial cases.

* **bug fixed**: The
  **sleep(x)** function was only sleeping
  for x milliseconds
  when using the Lcc run-time library. It now sleeps for x seconds,
  to conform with the Euphoria documentation for
  **sleep()**. Thanks to Wolfgang Fritz.

* **bug fixed**: On some versions of Linux, a translated/compiled Euphoria
  program would crash if standard output was redirected, e.g. for CGI

* **bug fixed**: On some versions of Linux, a translated/compiled Euphoria
  program would crash if machine(M_GET_SCREEN_CHAR, {row, col}) were called.

* **bug fixed**: In some cases the code was not correct when an
  integer variable was assigned the unary minus of an atom variable.

* **bug fixed**: In a very rare case, an uninitialized value in memory
  might be used to determine if a literal floating-point value should be
  treated as an integer or not. Incorrect code could result.



==== Binder



* **bug fixed**: The binder would crash
  after seeing a comment with no new-line character, just EOF, on the last
  line of a file. Some versions of Win32Lib.ew had this.
   Thanks to Henri Goffin.

* **bug fixed**: The usage report of
  **bind**/<font color="#993333">**shroud**
   still said "-scramble", instead of "-clear" and had other
  errors for Linux/FreeBSD. Thanks to Chris Bensler.

* **bug fixed**:
  **bind/shroud -clear** might neglect to
  rename a private variable, when an earlier local variable gets renamed
  into the same name. Thanks to Pete Lomax.

* **bug fixed**: When an include file was
  missing ##\n## on the last line,
  **bind/shroud -clear** might neglect to leave some whitespace
  before the next word in the main file. Thanks to Pete Lomax.

* **bug fixed**: If you defined a constant
   that was never used, and
   it was defined using an expression that contained a binary
   minus operator, a syntax error could occur in the bound or
   shrouded file that you create. Thanks to Chris Bensler.

==== Library Routines

* **bug fixed**:
  **walk_dir("/",...)** would fail on Linux.
  Thanks to Ricardo Forno.

* **bug fixed**:
  **db_compress()** of EDS had an error
  if the database file or it's path contained a blank character. A
  blank is ok now on all platforms except DOS. Thanks to Virtual B.

* **bug fixed**:
  **wildcard_file()** in
  **euphoria\include\wildcard.e** is now case
  sensitive on Linux/FreeBSD (but is still case insensitive on DOS/Windows).
  Thanks to Jeff Fielding.

* **bug fixed**:
  **dir()** was not always reporting file
  sizes greater than 1 Gb correctly. It now handles up to 4 Gb. Arithmetic
  performed on the file size would probably fail. Thanks to Ricardo Forno.

* **bug fixed**:
  **where()** was not always reporting file
  positions greater than 1 Gb
  correctly. Arithmetic performed on the position would probably fail.
  It now handles up to 2 Gb.

* **bug fixed**:
  **ex, exw, ec -wat, ecw -wat**: The
  **dir()** function for
  DOS and Windows was not handling wildcards correctly when a backslash
  appeared at the end of the file or directory path. Thanks to Juergen Luethje.

==== Namespace Feature


* **bug fixed**: If you tried to declare a
  new variable, using a namespace
  qualifier, e.g. **integer y:x** (which is illegal)
  it wouldn't complain, and would just ignore the "y:" part,
  as long as y:x was a routine (not a variable) in an earlier file.
  This is now caught as an error. Thanks to Martin Stachon.

* **bug fixed**: When declaring the type of a parameter, using a global type that was
  defined in more than one file, you would get an unclear error
  message stating "a type is expected here". Now you'll get a
  message pointing out that the type requires a namespace identifier
  to resolve it. Thanks to Juergen Luethje.

* **bug fixed**: The error message that you get if you specify a namespace
  qualifier and a ':', but you neglect to follow it with a properly-formed
  identifier, has been improved.  Thanks to Carl White.

==== Demo Programs

* **bug fixed**:
  In the **window.exw** demo program,
  **allocate(64)** and
  **allocate(16)**
  caused a storage leak. Thanks to Wolfgang Fritz and Jordah Ferguson.

==== Trace/Debug


* **bug fixed**: When
  **trace(0)** was executed, followed later by
  **trace(1)**, with no
  screen I/O in between, the values of some variables on the trace screen
  were not updated. Thanks to Ricardo Forno.

* **bug fixed**:
  **with trace** /
  **with profile** /
  **trace(3)**, used all together,
  produced garbage source lines in
  **ctrace.out**. Thanks to Kat.

!!CONTEXT:../docs/release/2.3.0.txt
%%output = release_2.3.0

== Version 2.3 February 11, 2002

This release updates the Euphoria Interpreter,
the Euphoria To C Translator, and the Interpreter Source Code product,
for all platforms.

* The DJGPP version of the interpreter source code now uses
  GNU C's dynamic labels, just like the Linux version. This allows
  it to achieve full speed, without the need for any assembly-level
  tweaking. Thanks to Bernie Ryan.
* The Interpreter Source Code now includes an overview document
  describing how the interpreter works.
* In the Complete Edition, bind.bat and bindw.bat now use exw to run
  the binder/shrouder. This avoids problems with long filenames
  on some systems. A console window will appear while the binder/shrouder
  is running. Thanks to "void", Bruce Axtens, and others.
* **bug fixed : **
  Due to a bug in the WATCOM 10.6 C library, the ex and exw interpreters,
  and code translated to C and compiled by Watcom, might get the wrong
  result from Euphoria's where() function when the file was opened in
  append mode, and the file pointer was in the uncommitted (not written
  to disk yet) portion of the file. The bug has been worked around
  by having Euphoria flush() the file in this particular case,
  before calling the Watcom routine. Thanks to Bob Elia.
* **bug fixed : **
  A bug introduced in the binder for 2.3 beta, might cause
  a function call on the last line of a program to be ignored.
  Thanks to Wolfgang Fritz.
* **bug fixed : **
  Several Euphoria files in the WIN32+DOS32 distribution had Linux-style
  line terminators (\n only). This made them hard to view using
  NotePad and some other editors. Thanks to Pete Lomax.
* **bug fixed : **
  If "with type_check" was turned on, ed.ex would get a type_check failure
  when the Esc key was pressed. Thanks to Kenneth Orr.



!!CONTEXT:../docs/release/2.3.0b.txt
%%output = release_2.3.0b

== Version 2.3 Beta January 15, 2002

This release updates the Euphoria Interpreter,
the Euphoria To C Translator, and the Interpreter Source Code product,
for all platforms.

* You can now override a Euphoria built-in routine with your own variable or
  namespace identifier of the same name.  Previously this was only allowed for
  user-defined routines.  Besides giving programmers more freedom, it will allow
  RDS to add new built-in routines in the future without breaking existing code.
* The warning about having multiple global symbols with the same name
  in different source files has been removed. It was felt to be unnecessary
  since you'll be asked to supply a namespace identifier if you actually
  make an ambiguous reference to a global symbol.
* You can now have a trailing \ (or Linux /) on the end of all directory names
  in **EUINC**, and you can have blanks in the directory name.
* To eliminate confusion, the binder/shrouder will now delete the
  output file if a fatal error occurs during the bind or shroud.
* Numerous improvements and corrections were made to the documentation.
  Thanks to Igor Kachan.
* Old, pre-ANSI function definitions in the interpreter source code,
  have been updated to ANSI-style, which is more compatible with C++.
* **bug fixed : ** With DJGPP C, when compiling code produced by the Translator,
  or compiling the Interpreter source code, there was a memory allocation bug
  that could waste a bit of time, or, in rare cases, cause a crash.
* **bug fixed : ** On Windows, using the Interpreter, or a Translated program,
  you were sometimes required to hit Enter twice to exit from a console window.
  Thanks to Tone Skoda.
* **bug fixed: ** The Euphoria dir() function, as implemented for Lcc or Borland,
  did not handle directories properly when they had extra attributes set, such as
  READ_ONLY. Thanks to Euman, who encountered the problem, and then showed how to
  fix the Interpreter source code for dir().
* **bug fixed: ** You can now declare a namespace identifier with the same name
  as a built-in function, without causing a lot of errors. Thanks to Martin
  Stachon (although he recommended a different solution).
* **bug fixed -  Binder: ** Support for the new **EUINC** environment variable
  has now been added to the binder. Thanks to Ross Boyd.
* **bug fixed -  Binder: ** Appending resource files to a bound .exe didn't work
  correctly when bind -clear was used. Thanks to Wolfgang Fritz.
* **bug fixed -  Binder: ** When using the binder interactively, you would get a
  "variable not initialized" error when trying to substitute a different Windows
  icon. Thanks to Tony Steward.
* **bug fixed -  Binder: ** In some cases the keyword "constant" would be dropped from
  the shrouded output, when the previous line of input had a
  constant declaration ending in ']'. Thanks to Ross Boyd.
* **bug fixed -  Binder: ** When a general expression, (not just a string in
  quotes), was used as the argument to routine_id(), local routines that were
  potentially the target of that expression, might have their names changed
  (unless -clear was used), thus causing routine_id() to return -1 at run-time.
  Global routines were ok.
* **bug fixed -  Binder: ** The binder/shrouder kept going even though an include
  file was missing.  Thanks to Ross Boyd.
* **bug fixed -  Linux Binder:** The Linux search path bug for bound executables, supposedly fixed
  by the 2.3 alpha release, wasn't fixed properly. Fixed now.
  Thanks to Kenneth Rhodes.
* **bug fixed -  Linux Binder:** bindu -clear  and shroud -clear with a file
  containing DOS/Windows-style \r\n line terminators gave you errors "illegal
  character" when your shrouded program was run, and "not bound correctly" when
  your bound file was run.
* **bug fixed -  Interpreter Source:** The link command for building the DOS
  interpreter with WATCOM C, listed a non-existent .obj file.


!!CONTEXT:../docs/release/2.3.0a.txt
%%output = release_2.3.0a

== Version 2.3 Alpha November 30, 2001

This release updates the Euphoria Interpreter for WIN32, DOS32 and Linux.
It also updates the Euphoria To C Translator for all platforms,
and it introduces a new product - the Euphoria Interpreter Source Code.

* The registration incentives and prices have changed.
** The Interpreter product now has just one option: WIN32, DOS32 //and// Linux,
   formerly $59, for just $39.
** The Interpreter source code (minus a few registered features)
   is now available for $49. See the a href=license.htm>source license</a>
   and a href=register.htm>register.doc</a> for more details.
** The Translator continues to cost $29.
** When Public Domain users reach 300 statements, they will no longer
   lose the run-time error diagnostics. They will only lose the trace() facility.
* The Euphoria interpreter can now be built successfully by 6 different
  C compilers on 3 platforms.
* New //namespace qualifiers// eliminate naming conflicts between identical
  global symbols declared in different include files.  Also, local symbols will
  now override global symbols of the same name, rather than causing an error.
* The Complete Edition Interpreter product comes with a new 2-pass
  binder/shrouder that eliminates all unused routines and constants, resulting in
  smaller executable files. It also has an option to bind clear source, so you
  can get understandable error messages from your users.
* A new environment variable, EUINC, has been introduced.  If present, it
  specifies a list of additional directories that will be searched for include
  files. The directory containing the main file is always searched first, then
  the directories in EUINC, then euphoria\include.
* The Interpreter now supports a new trace mode, trace(3).  It logs all executed
  Euphoria statements to a file, so you'll be able to see the last statement that
  was executed at the time of any crash, as well as the 499 statements that
  preceded it.  This is particularly helpful in the case of machine-level crashes
  where Euphoria is unable to write an ex.err file.  Thanks to Matthew Lewis.
* The Euphoria interpreter can now pass Euphoria data - atoms and sequences, to
  .dll files coded in Euphoria and built by the Translator. Use the new E_ types
  in dll.e
* On Linux we added RTLD_GLOBAL on the dlopen() call. This lets you link
  successfully with more shared libraries.
* On Linux, when using the #! feature on the first line, to make your source file
  directly executable, you no longer need a .exu extension on your file.  Linux
  programmers often prefer to have no extension on their executable files.
* Windows callback routines written in Euphoria can now take 9 arguments (was 8).
  Thanks to Matt Lewis.
* In addition to C_DOUBLE (8-byte floating point), C_FLOAT (4-byte
  floating-point) is now supported for arguments and return values from C
  routines. Thanks to David Guy.
* Windows .dlls opened with open_dll() are now closed automatically when your
  program terminates. This avoids a tiny bit of memory leakage.  Thanks to Euman.
* safe.e has a new option to check just the edges of registered blocks and not
  complain if other blocks of memory are used.
* get_bytes() is 30% faster.
* allocate_string() was speeded up. Thanks to Yuku Sugianto.
* The mydata.ex demo program now uses an EDS database.
* **bug fixed -  Translator: ** When a global or local variable containing a
  sequence or floating-point number was assigned the result of a function, and at
  some point during the function call the global or local variable was
  overwritten, some corruption would take place, leading to a probable crash
  later in the program. Thanks to Sergio Gelli.
* **bug fixed -  Linux Interpreter: ** programs of more than a few thousand lines
  had a chance (maybe 20%) of having one of their statements crash whenever it
  was executed.
* **bug fixed - Interpreter: ** **s[i][j]...[k] = s** caused the interpreter to
  crash. i.e. an assignment of an entire sequence to an element of an element of
  itself using 2 or more levels of subscripting. Thanks to Henri Goffin.
* **bug fixed -  Linux binder: ** (Kenneth Rhodes)  Bound executable programs
  stored somewhere on the search path would not run properly unless they were in
  the current directory or unless you specified the full path to the executable.
* **bug fixed -  Binder: ** "with profile_time" in a bound or shrouded program would cause a crash
* **bug fixed -  DOS Interpreter: ** In image.e, put_screen_char() has been
  corrected to have: **if overflow > 0 then ...**
  instead of: ** if overflow then ...**
* **bug fixed -  Interpreter: ** A time optimization for slicing could in rare
  cases cause a lot of wasted space. The optimization has been adjusted to handle
  those cases.  Thanks to Brian Clausing.
* **bug fixed - safe.e: ** free() and free_low() were not actually freeing
  the block of memory, and on Linux free() could cause a segmentation violation.
  The same routines in **machine.e** were ok.
* **bug fixed - Translator for DJGPP: **A couple of minor differences from ex.exe
  in the display of text were corrected.
* **bug fixed - define_c_var():** works on WIN32 too. The documentation was corrected.



!!CONTEXT:../docs/release/euc.txt
%%output = release_euc

== Euphoria to C Translator Official June 5, 2001

* A couple of minor enhancements and bug fixes.


!!CONTEXT:../docs/release/euc-b2.txt
%%output = release_euc-b2

== Euphoria to C Translator Beta-2 May 8, 2001

* You can now use the translator to make a .dll file.



!!CONTEXT:../docs/release/euc-b1.txt
%%output = release_euc-b1

== Euphoria to C Translator Beta-1 February 15, 2001

* Some bugs were fixed. Smaller, faster C code is produced.



!!CONTEXT:../docs/release/euc-a3.txt
%%output = release_euc-a3

== Euphoria to C Translator Alpha-3 November 27, 2000

* Some bugs were fixed. Some new features were added. Borland C++ is now supported.



!!CONTEXT:../docs/release/euc-a3.txt
%%output = release_euc-a3

== Euphoria to C Translator Alpha-3 November 27, 2000

* Some bugs were fixed. Some new features were added. Borland C++ is now supported.



!!CONTEXT:../docs/release/euc-a2.txt
%%output = release_euc-a2

==  Euphoria to C Translator Alpha-2 October 26, 2000

* Support for the Lcc C compiler for Windows was added. DJGPP C (DOS)  is partially
  supported (no pixel graphics).



!!CONTEXT:../docs/release/euc-a1.txt
%%output = release_euc-a1

== Euphoria to C Translator Alpha September 6, 2000

* The first release of the translator. It supports Euphoria version 2.2.
  It relies on WATCOM C for DOS and Windows, and GNU C for Linux. Prime sieve
  runs 3.2x faster than with the interpreter. Shell sort runs 4.5 times faster.



!!CONTEXT:../docs/release/2.2.0.txt
%%output = release_2.2.0

== Version 2.2 WIN32+DOS32 January 14, 2000

* Better error messages are now issued from the interpreter, and from
the bind program, for some typical errors that users can make when
binding a program.
* The documentation has been improved in a few places.
* The **window.exw** demo program shows how to load the
Euphoria icon contained in exw.exe.
* Language War uses Jiri Babor's improved version of **putsxy.e**.

!!CONTEXT:../docs/release/2.2.0b.txt
%%output = release_2.2.0b

== Version 2.2 Beta WIN32+DOS32 December 23, 1999

Most of the new library routines developed for Euphoria 2.2 on
Linux, have now been ported to WIN32 and DOS32.
These are: sleep(), chdir(), flush(), lock_file(), unlock_file(),
crash_file(), get_screen_char() and put_screen_char(). For a
description of these routines refer to the Linux release notes below,
or <a href="library.htm">LIBRARY.DOC</a>.

Some cross-platform bug fixes and other miscellaneous improvements
were made during the Linux port. These bug fixes and improvements
have now been ported back to WIN32+DOS32. See the Linux release notes (below).

In addition, the following improvements have been made specifically
for WIN32 and DOS32:

* **exw.exe** now contains a Euphoria icon that is displayed
automatically by Windows. The icon was contributed by Gary Dumer.
Registered users may change this icon when they bind a program.
* **exw.exe** is now a compressed executable of just 73K (or so).
It's compressed using the UPX compression tool for .exe files.
* **ex.exe** has been updated with the latest release of
the CauseWay DOS extender. A problem where
CauseWay would sometimes limit you to 64Mb of memory under
some DOS configurations has been eliminated, and a few other minor
bugs were fixed.
* **bug fixed:**
The error traceback could sometimes crash or be misprinted when
a type_check failure occurred. It could only happen when 1 was added to
an expression, and the non-integer result of the expression
was assigned to a variable declared as integer.
* **bug fixed:**
If text_rows() was called as the first routine needing a WIN32 console
window, Euphoria would fail to set the new number of lines of
text on the console.

!!CONTEXT:../docs/release/2.2.0-linux.txt
%%output = release_2.2.0-linux

== Version 2.2 Linux November 22, 1999

* **All platforms: bug fixed:**
If a Euphoria routine called itself recursively from inside a
for-loop, and at one level of recursion the for-loop counted //up//
to an upper limit, and at another level of recursion the for-loop
counted //down// to a
lower limit, the for-loop would probably malfunction at one of the levels.
Thanks to Delroy Gayle.
* The documentation was improved in many places, especially with respect
to the Linux platform.

!!CONTEXT:../docs/release/2.2.0b-linux.txt
%%output = release_2.2.0b-linux

== Version 2.2 Beta Linux October 22, 1999

//Most of these features and bug fixes will also be made available
in Version 2.2 for **WIN32 + DOS32**//.

* **platform()** has been moved from misc.e into exu to eliminate
the function call overhead. platform() now takes zero time to compute.
The compiler simply plugs in the appropriate constant value.
*  **lock_file()**
 and **unlock_file()** have been added
 to allow multiple processes
 to share access to files. This can be important in CGI programming and
 other areas.
* **flush()** will force the contents of the memory buffer out to a file or device.
* **chdir()** will change to a new current directory and let you know if it
was successful.
* **sleep()** will suspend execution of your program for a number of seconds,
and let the operating system schedule another process.
* **put_screen_char()** will write a character and its attributes (colors etc.)
to the screen.
* **get_screen_char()** will read a character and its attributes from the screen.
* **save_text_image()** now works on Linux (as well as DOS32). It copies
a rectangular text image from the screen.
* **display_text_image()** now works under Linux (as well as DOS32).
It writes a rectangular text image to the screen.

* The "short-circuit" warning now gives the filename and line number of the
  possibly short-circuited call. Minor clarifications were made in some
  other error messages as well.
* Minor improvements were made to **ed** and **search**.
* A portability problem in **how2reg.ex** was fixed.
* **exu** is compressed better. It's actually a bit smaller now,
although functionality has been added to it.

!!CONTEXT:../docs/release/2.2.0a-linux.txt
%%output = release_2.2.0a-linux

==  Version 2.2 Alpha Linux August 24, 1999

//Many of these features and bug fixes will also be made available
in Version 2.2 for **WIN32 + DOS32**//.

*  The documentation has been brought up-to-date to include
  **Linux**-specific information for library
  routines and Euphoria in general.
*  There is now a Complete Edition for
  **Linux**, including
  **binding** and
  **shrouding**. See
  **register\register.doc**.
*  There is now **text mode** mouse support using
  **get_mouse()**. You must have **GPM
  server** running. It works in a text console or an **xterm** window.
*  **Linux:**
  **define_c_var(name)** will return the
  address of a global C variable in a shared library.
*  It was confirmed that you can call Euphoria routines from
  **Linux** C routines using exactly the same
  mechanism as in **WIN32** Euphoria.
  See **euphoria/demo/linux**.
*  An example of creating your own shared library routines and calling them from
  Euphoria was added. See
  **euphoria/demo/linux**.
*  **All platforms: crash_file(file_name)** will
  cause diagnostic messages to be written to **file_name** instead of
  **ex.err**. You can use
  **crash_file("/dev/null")** to get
  diagnostics on screen but not in a file.<br>
  **crash_file("")** means
  "no diagnostics" (to screen or ex.err).
*  **Trace** mode in **xterm** now detects
  the **F1/F2** keys.
*  **time()** now reports real "wall-clock" time,
  not CPU time.
*  **search**,
  **guru** and
  **cdguru** now place their output in your
  $HOME directory instead of the current directory.
*  **#!** is now restricted to just the first line of a file.
*  **All platforms:** In **ed**, the
  **Esc n**, **Esc d**, **Esc f** and **Esc r** commands will
  immediately redisplay your last choice. You can press
  **up-arrow/down-arrow** to
  see other choices, or clear the choice. If you start typing without
  editing, it will clear the choice and take your new input.
*  **free_console()** will set the terminal
  parameters back to normal. Normally, when running a Euphoria program the
  parameters are set the way that **curses** wants them and they are set
  back to normal when the program terminates.
  If your program needs to terminate
  in a strange way (other than calling abort()),
  **free_console()** should be called first.
*  **bug fixed: <font color="#006699">get()</font>
  ** now considers '\r' to be a whitespace character. This is important when
  reading DOS files.
*  **All platforms: bug fixed:** It was not
  immediately issuing a **type_check**
  failure when 1 was added to an integer variable that was set to the maximum
  value for an integer (1.07 billion). Thanks to Jeff Fielding.
*  **All platforms: bug fixed:** It was not
  always detecting an improperly-formed
  exponent on a floating-point number. Thanks to Lionel Wong.
*  **All platforms:** The performance of the storage allocator has been
  improved in certain cases. A bug that could cause the interpreter to
  crash when you are almost out of memory has been fixed.

!!CONTEXT:../docs/release/2.2.0pa4.txt
%%output = release_2.2.0pa4

==  Version 2.2 Pre Alpha #4 Linux July 15, 1999

* You can call C routines in **Linux**
  shared libraries (**.so** files). See
  **euphoria/demo/linux/callc.exu** for
  some examples.
* If your program does not output anything to the **xterm** window,
  **exu** will not issue the "Press Enter"
  prompt.
*  **All platforms: ed** now lets you recall
   previous top-line command text using **up-arrow** and **down-arrow**,
   similar to doskey in DOS and the shell history in Linux. This works with
   any strings that you type for **Esc n** (new file),
   **Esc d** (Linux command), **Esc f** (find string) or
   **Esc r** (replace string). In addition, you can now use
   **arrow keys**, **Home**, **End**, **Delete** etc. to edit
   strings before you press **Enter**.

!!CONTEXT:../docs/release/2.2.0pa3.txt
%%output = release_2.2.0pa3

== Version 2.2 Pre Alpha #3 Linux July 8, 1999

*  In an **xterm** window, **exu** will
  prompt you to hit **Enter** before it exits. Without this, **xterm**
  restores the screen so fast that you don't see any output or error messages.
*  An internal coding change was made to Euphoria's
  **rand()** function.
  (The algorithm has not changed.)
  Hopefully this will
  allow rand() to work on all distributions of
  **Linux**. Please let us know if
  rand() still fails.
*  **ed:** The **Esc h** command will
  display the Euphoria help files. This was broken in pre-alpha#2.
*  In an **xterm** window, Euphoria's
  **video_config()** now reports the correct
  number of lines and columns - this helps
  **ed** to work much better.
  **ed** will work with the initial size of
  window in effect when **ed** starts up.
*  **ed:** **F1**, **F2**, **F3**,
  **F4**, **Home**, **End**, and the **Delete** key work now in
  **xterm** (under Red Hat 5.2 at least). The other F-keys were already
  working. **PageUp/PageDown** and some other keys still don't work - feel
  free to add your own alternate keys.
*  **exu** is now even smaller - just 82K.

!!CONTEXT:../docs/release/2.2.0pa2.txt
%%output = release_2.2.0pa2

== Version 2.2 Pre Alpha #2 Linux July 6, 1999

* The **ncurses** library has been statically linked into
  **exu**.
* **exu** is now a compressed executable (97K).
* **bug fixed: <font color="#993333">ed</font>**
  can now edit files with upper case letters in the name.
* The fraction of a second delay when you press the **Esc** key in
  **ed** has been removed.

!!CONTEXT:../docs/release/2.2.0pa1.txt
%%output = release_2.2.0pa1

== Version 2.2 Pre Alpha #1 Linux July 1, 1999

* The first version of Euphoria for **Linux** was released.


!!CONTEXT:../docs/release/2.1.0.txt
%%output = release_2.1.0

== Version 2.1 WIN32 + DOS32 March 29, 1999

* Updates to the **trace** screen have been optimized. Unnecessary refreshes of
  the source code, and the variables on the trace screen, have been eliminated.
  When a refresh is necessary, it is now slightly faster. This makes a noticeable
  difference in **exw.exe**, and also in **ex.exe** in pixel-graphics modes. For
  **ex.exe** in text modes, it reduces screen flicker slightly.
* The **install** program no longer requires that your PATH be less than 128
  characters. It will simply warn you if it isn't. Newer versions of DOS allow
  for a longer PATH. Thanks to Steve Adams.
* An extra error check was added to **unregister_block()** in **safe.e**. Thanks
  to David Guy.


!!CONTEXT:../docs/release/2.1.0b.txt
%%output = release_2.1.0b

== Version 2.1 Beta March 5, 1999

* The rest of the files in the **euphoria\doc** directory have now been converted
  to HTML. Every **.doc** file in the **doc** directory now has a corresponding
  **.htm** file in the **euphoria\html** directory. Many improvements and
  clarifications were made to the documentation.
* You will now be warned when you have code that comes immediately after an
  **exit**, **return** or **abort()** statement. This code can never be executed.
  Suggested by Gabriel Boehme.
* **safe.e** no longer includes **graphics.e**. This eliminates possible naming
  conflicts when **safe.e** is substituted for **machine.e**.
* Using code supplied by David Guy, **safe.e** will now let you add or remove
  externally-allocated blocks of memory on the "safe address list". **See the new
  library routines:** **register_block()** and **unregister_block()**.
* **message_box()** now uses the **handle of the active window** rather than
  NULL. This forces the user to reply to your message before he can continue to
  interact with your program.  He won't be prevented from interacting with other
  programs. Thanks to Austin C.
* **get()** and **value()** have been sped up by a further 5% thanks to Gabriel
  Boehme.
* **exw.exe** has been made less likely to crash mysteriously when attacked by a
  virus.
* **sanity.ex** now checks your installation of Euphoria. You'll be warned if
  your PATH or EUDIR variables are not set, or your **ex.exe**, **exw.exe**,
  **pdex.exe**, or **pdexw.exe** files have been corrupted or not installed
  correctly in **euphoria\bin**.
* The security of **bound** and **scrambled** programs has been tightened some
  more. Thanks to Rusty Davis.
* To save space in **euphor21.zip**, the **install** program now //generates//
  the HTML and DOC files from a common source, using Junko Miura's
  **documentation generator**. In the process, the generator is deleted, but you
  can download it from the RDS site.
* When a **type_check** failure occurs you'll be warned if the type erroneously
  returned a //sequence// for it's "true/false" result. Previously, a sequence
  result was simply reported as a type_check failure. Suggested by Ralf
  Nieuwenhuijsen.
* The code for **demo\win32\winwire.exw** was cleaned up considerably.
* The **install** program will warn you to change your **autoexec.bat** file when
  you install a new release of Euphoria onto a //different// drive.



!!CONTEXT:../docs/release/2.1.0a.txt
%%output = release_2.1.0a

== Version 2.1 Alpha January 15, 1999

* We've made a number of changes to the packaging, pricing, and registration incentives for the Euphoria product:
** The Dual-Platform (DOS32+WIN32) package, formerly $53 has been reduced to $39 U.S., effective immediately.
** The Single-Platform (DOS32-only) package, formerly $32, has been discontinued.
** The printed manual has been discontinued. Instead, there is now an official HTML version of the manual,
   included with the Public Domain .zip file.
** All useful 3rd-party include files, such as **Win32Lib.ew** and many others, will be "stamped" by RDS with a
   code number that makes them **//free//**, just like the files in **euphoria\include**. They will not add to your
   statement count, provided you do not significantly modify them. This will also allow 3rd-party developers to get
   better diagnostic information from their users.
** **Binding**, **shrouding** and **profiling** will now be part of the Complete Edition only. These are features
   that beginners do not require, but serious users might find valuable.
* Short-form assignment operators ##+=##, ##-=##, ##*=##, ##/=##, and ##&=## have been added.
  For example, instead of saying:
  <eucode>
  count = count + 1
  </eucode>
  You can now say:
  <eucode>
  count += 1
  </eucode>
  Instead of saying:
  <eucode>
  matrix[row][column] = matrix[row][column] * 5.0
  </eucode>
  You can say:
  <eucode>
  matrix[row][column] *= 5.0
  </euuode>
  Instead of saying:
  <eucode>
  test_scores[start..finish] = test_scores[start..finish] / 100
  </eucode>
  You can say:
  <eucode>
  test_scores[start..finish] /= 100
  </eucode>
* Euphoria now uses "short-circuit" evaluation of ##and## and ##or## expressions
  in **if/elsif/while** conditions.  e.g. in an ##and## condition:
  <eucode>
  if A and B then ...
  </eucode>
  the interpreter will skip the evaluation of expression B whenever expression
  A is 0 (false), since it knows that the overall result must be false. In an
  ##or## condition:
  <eucode>
  while A or B do ...
  </eucode>
  the interpreter will skip the evaluation of expression B whenever
  expression A is non-zero (true), since it knows that the overall result
  must be true. \\
  \\
  Euphoria code written prior to version 2.1 may no longer work correctly if
  expression B contains a function with **//side-effects//** such as setting a
  global variable, doing I/O etc. In practice this kind of code is very rare,
  but just in case, a warning will now be issued if a function with
  side-effects might be short-circuited.  \\
  \\
  By skipping the evaluation of B, short-circuit evaluation is typically
  faster, and will allow you to write statements such as:
  <eucode>
  if atom(x) or length(x)=1 then ...
  </eucode>
  that would generate an error on older versions of Euphoria whenever x was an
  **atom**, since length() is not defined for atoms.
* Several new routines were added.
** Built-in to ex.exe/exw.exe:
*** profile() - turns **profiling** **on/off** so you can focus your **profile** and
    **profile_time** runs on particular events within your program."
*** system_exec() - gives you the exit code from calling a **.exe** or **.com** file, or another
    Euphoria program.
*** equal() - compares any 2 Euphoria objects for equality. equivalent to: compare(a,b) = 0  but
    more readable.
** **Added to various include files:**
*** walk_dir() - recursively goes through a directory and subdirectories, calling a routine that
    you supply.
*** reverse() - returns a sequence in reverse order.
*** sprint() - returns the string representation of any Euphoria object.
*** arcsin() - inverse trig function.
*** arccos() - inverse trig function.
*** get_bytes() - returns the next n bytes from a file.
*** prompt_number() - prompts the user to enter a number.
*** prompt_string() - prompts the user to enter a string.
*** instance() - **WIN32:** returns the instance handle of the program.
*** PI - the constant PI - 3.14159... was added to **misc.e**.
* The main Euphoria documentation can now be viewed locally with a Web browser.
  The plain-text files **refman.doc** and **library.doc** are still available in
  the **doc** subdirectory, but we now have **refman.htm** and **library.htm** in
  the new **html** subdirectory. We have developed a tool (written in Euphoria)
  that lets us easily maintain both an up-to-date HTML version, and an up-to-date
  plain-text version of **refman** and **library**.
* The documentation has also been clarified and expanded in many places.
* **WIN32:** you can create an **unlimited** number of Euphoria call-back
  routines, as long as each routine is a function with 0 to 8 parameters. In version 2.0
  you could only have one call-back routine and it had to have exactly 4 parameters.
* The ##xor## keyword has been added to complement: **and/or/not** and
  **xor_bits()** e.g.
  <eucode>
  if a xor b then...
  </eucode>
  ##xor## works on sequences too. It's similar to ##or##.
* The **dir(path)** library routine now officially supports the use of
  **wildcards *** and **?** in the path that you supply. This feature was always
  available, but wasn't documented until now. e.g.
  <eucode>
  info = dir("mydata\\*.d?t")
  </eucode>
* **optimization:** Subroutine call+return overhead was reduced by an average of
  30%. The speed-up occurs for all normal function/procedure/type calls,
  user-defined type-checks, call_proc()/call_func() calls using a **routine id**,
  and Windows call-backs. Only recursive calls cost the same as before.  Programs
  with a reasonably-high frequency of calls can easily be 10% faster overall
  because of this.
* **optimization:** Branch ##//straightening//## has been implemented. The
  compiler will optimize branches in the internal code such that a branch from
  A->B where location B contains a branch to location C, will be optimized to a
  direct branch from A->C. Even something like A->B->C->D can be straightened to
  A->D. This often occurs in while-loops that contain if-statements.
* **optimization:** In many cases, variable initialization checks are now
  replaced by "no-ops" after the first check is performed. Euphoria was already
  optimizing out many checks at compile-time.
* **optimization:** **get()** and **value()** are now much faster in most cases
  thanks to Jiri Babor and some further optimizations by RDS.  The new v2.1
  **ex.exe** with the new v2.1 **get.e** is:
  [quote]
  1.45x faster reading a sequence of f.p. numbers from a file and<br>
  2.25x faster when reading a sequence of integers from a file.
  [/quote]
* **optimization:** **power(x,2)** is converted internally to x*x which is faster
  in all cases, especially when x is a large integer or a f.p. number.
* **optimization:** Thanks to Jiri Babor, **int_to_bits()** is at least 15%
  faster in most cases.
* **optimization:**
  Plotting a long sequence of pixels in 16-color graphics modes is about 3% faster.
* **optimization:** **draw_line()** has been sped up by a few percent.
* **Language War** has had a major face-lift. It now runs in **pixel-graphics
  mode 18** (640 x 480 x 16 colors) instead of **text mode**. It also has
  ##//fine-grain//## parallelism, i.e. virtually anything can happen in parallel
  with anything else. Multiple torpedos, phasors etc can be drawn on the screen
  simultaneously, while ships are moving, commands are being entered, things are
  exploding etc. Even the timing needed for the PC speaker sound effects is
  handled by the **task scheduler**. There are **//no//** time-delay "busy" loops
  executed during the game. The galaxy scan now shows you a scaled picture of the
  whole galaxy, rather than just a bunch of numbers.
* The default print format for atoms was changed from "%g" to "%**.**10g".  This
  format is used by print(), **?**, the **trace** facility, and **ex.err** dumps.
  This allows large integers -9,999,999,999 to +9,999,999,999 to be printed as
  integers, rather than as scientific notation. It also provides about 10 digits
  of accuracy to be displayed on fractional numbers, rather than just 6. Art
  Adamson and others made it clear that more digits should be displayed.
* The state of all **with/without** settings is saved upon entering an **included
  file**, and restored at the end of the **included file**. An included file can
  change the settings, but they will be restored at the end of the included file.
  e.g. warnings might be turned off just within the included file (and any files
  it includes). As a result some programs now display warnings where none were
  seen before.
* Warnings are now displayed <_ba>//after//</_ba> your program finishes
  execution, so they won't be erased by clear_screen(), graphics_mode() etc.
  Some programs now show warnings where none were seen before.
* The security of scrambled code and bound code has been improved thanks to ideas
  contributed by Rusty Davis. When a bound program starts executing, a quick
  integrity check will be made to detect any corruption or tampering.  It's still
  ok to add data to the end of a **bound .exe** file, as long as your last line
  is ##abort(x)##.
* The **ed** editor now lets you view and edit beyond column 80.
* **ed** has a new command: **Esc m** (modifications). It will show the
  differences between the original file on disk and the current edit buffer. This
  can be very useful when you've forgotten what changes you've made, and you are
  wondering if it's safe to save them.
* The **trace** window now provides an upper case **Q** command which lets the
  program run to completion, ignoring any trace(1) commands. Lower case **q**
  lets it run to the next trace(1).
* **safe.e** (debug version of **machine.e**) has been enhanced. It will now
  automatically catch additional cases where data is illegally written just
  **//before//**, or just **//after//**, the boundaries of an allocated block of
  memory. This can be particularly useful in **WIN32** where Windows might
  overwrite one of your under-sized blocks. Without a tool such as **safe.e**,
  this type of bug could take hours or even days to track down.
* The **euphoria\tutorial** directory was created to hold several small tutorial
  programs.
* The limit on the number of open files was raised to 25 from 15.  Three of these
  files are 0,1,2: standard-input, standard-output and standard-error, so you can
  now have up to 22 of your own files open simultaneously. (As far as we know, no
  one ever exceeded the old limit, but it seemed wise to raise it.)
* When the user simply types ##ex## or ##exw## and is prompted for the name of
  the Euphoria **.ex** or **.exw** file to run, **command_line()** will now be
  updated to include the filename as the second command-line argument, just as if
  the user had originally typed: ##ex filename##.  Thanks to Mathew Hounsell for
  suggesting this.
* **mset.ex** now saves pictures in **.bmp** format. Previously it was using a
  non-standard, compressed format.
* **lines.ex** (**lines.bat**) now reports non-blank/non-comment lines as well.
  This is <_ba>//not//</_ba> the same as the "statement count" used by Euphoria
  for the diagnostic limit, but it's usually within +/- 10%, assuming you write
  one statement per line.
* Numeric literals greater than 1e308 (roughly) are now set to **+/-** ##inf##.
  They used to cause a compile-time error.



!!CONTEXT:../docs/release/2.0.0.txt
%%output = release_2.0.0

==  Version 2.0 March 25, 1998

* The install procedure has changed. The Euphoria .zip file now contains a large
  ##bundle.dat## file that contains over 100 files. This makes it easier for
  people to locate the important files: **readme.doc**, **install.bat**, etc.
  that they should look at before installing. The .zip file is also 35K smaller
  as a result.
* **shroud** will warn you to use **bind/bindw** if you try to create a shrouded
  source file with a name ending in "*.exe".



!!CONTEXT:../docs/release/2.0.0b.txt
%%output = release_2.0.0b

==  Version 2.0 Beta February 26, 1998

* The WIN32 interpreter, **exw.exe**, is now a **true WIN32 GUI** program. In 2.0
  alpha it was a WIN32 ##//console//## program that was always associated with a
  ##//console//## or DOS-window. A DOS-style console window will now be created
  only if your program needs one.  **exw** will automatically create a new
  console window the first time your program writes to the screen, reads from the
  keyboard, or calls any library routine that requires a console to work. The
  console will disappear automatically when your program finishes execution.
* A new library routine, **free_console()**, will immediately delete the console
  window if you currently have one.
* The Complete Edition of Euphoria now provides a **-scramble** option of
  **bind** and **shroud** to improve the security of programs that you
  distribute.
* You can now pass Euphoria **atoms** to C routines as 64-bit C double type
  floating-point arguments, and you can receive a floating-point result back from
  a C function.
* **exw.exe (beta)** runs 10 to 15% faster than **exw.exe (alpha)** (based on
  **sieve.ex**, **shell.ex**, etc.). The WATCOM C compiler was doing a bad job of
  optimizing a critical section of the interpreter when building exw.exe, but was
  producing excellent code when building **ex.exe**.  With some trivial changes
  to the interpreter C code, WATCOM now produces excellent code for both
  platforms.
* The average program now has 60K more memory available before having to use the
  swap file.
* The limit on the size of a single procedure, function or type has been
  eliminated.
* The limit on the size of a single top-level statement has been eliminated.
* The limit on the total number of include files that can make up a program has
  been increased to 256 from 150.
* Some **optimizations** were added. The following general forms of expression
  are now faster:
  <eucode>
    2 * x
    x * 2
    1 + x
  </eucode>
  where x can be any expression, and have type atom or sequence.
* There is a new documentation file, **perform.doc** with lots of tips for
  performance-obsessed programmers.
* If you call a C routine using **c_func()**, but you linked the C routine using
  **define_c_proc()** you will get an error message. Similarly, if you call it
  using **c_proc()**, but you linked it using **define_c_func()** you'll get an
  error message. This restriction was documented, but not actually enforced in
  2.0 alpha. Some programs written for the alpha release will have to be
  corrected.
* You will now see the actual name of the C or Euphoria routine that you were
  attempting to call, when you get an error message from **call_proc()**,
  **call_func()**, **c_proc()**, or **c_func()**.
* A new **-clear_routines** option of **bind** and **shroud** will leave the
  names of all routines unshrouded. This is necessary if your program calls
  **routine_id()**. You'll be warned if you use routine_id() and do not choose
  this option. (Registered users can use **-scramble** together with
  **-clear_routines** to restore a high level of shrouding.)
* If a name conflict arises with a global symbol, the **shrouder** will now warn
  you, and then choose a new name. It used to abort with a message.
* It is no longer possible to **trace** or **profile** shrouded code.
* A new demo program, **hash.ex**, was added to **euphoria\demo**.
* **freq.ex** was moved from **euphoria\bin** to **euphoria\demo** and renamed as
  **tree.ex**.
* A new documentation file, **bind.doc** describes all the features of
  **bind.bat** and **shroud.bat**. The previous description in **refman.doc** has
  been shrunk.
* The file **overview.doc** gives a quick overview of all documentation files.
* The description of **get_mouse()** in **library.doc** discusses the problem of
  320-wide graphics modes (you must divide the x coordinate value by 2).



!!CONTEXT:../docs/release/2.0.0a.txt
%%output = release_2.0.0a

== Version 2.0 Alpha November 5, 1997

* A **//new platform//** is now supported.  **exw.exe** will run Euphoria
  programs using the **WIN32** (Windows 32-bit) operating system. **ex.exe** will
  run programs using **DOS32** (extended DOS).  See **platform.doc** for further
  details.
* The following library routines have been introduced.
** For both DOS32 and WIN32:
*** ##platform()## - find out which platform you are executing on. (The
   PLATFORM constant is available in Euphoria 2.2 and later).
*** ##routine_id()## - get a small integer id number for a Euphoria procedure or
    function.
*** ##call_proc()## - call a Euphoria procedure by using its id.
*** ##call_func()## - call a Euphoria function by using its id.
*** ##custom_sort()## - sort a sequence using a compare function that you specify.
*** ##poke4()## - store a number into 4 bytes of memory.  poke4(address, value) is at least 10x
    faster than: poke(address, int_to_bytes(value)).  poke4() also works with
    sequences of values."
*** ##peek4s()## - read 4 bytes of memory as a signed integer (works on sequences too).
*** ##peek4u()## - read 4 bytes of memory as an unsigned integer (works on sequences too).
    peek4u(address) is 10x faster than: bytes_to_int(peek({address, 4})).
*** ##allocate_string()## - allocate and store a 0-terminated string in memory.
** For WIN32 only:
*** ##open_dll()## - open a Windows **.**dll file.
*** ##define_c_proc()## - define a C routine that will be called from Euphoria (no value returned).
*** ##define_c_func()## -define a C routine that will be called from Euphoria (a value will be
    returned).
*** ##call_c_proc()## - call a C routine from Euphoria (no value is returned).
*** ##call_c_func()## - call a C routine from Euphoria (a value is returned).
*** ##call_back()## - get a **//call-back address//**, so Windows can call your Euphoria routine when
    the user interacts with your window."
*** ##message_box()## - display a simple **Yes/No/Cancel** window.
* New Demo programs:
* **csort.ex**
* **email.exw**
* **window.exw**
* **winwire.exw**
* **dsearch.exw**
* New include files:
** ##safe.e## - debug version of **machine.e**"
** ##misc.e## - miscellaneous
** ##dll.e## - dll access
** ##msgbox.e## - Windows message box
* The following additional improvements have been made to the **DOS32** version:
** On Pentium and higher systems, floating-point calculations are now about 20%
   faster (and floating-point in **exw** is a further 20% faster than **ex** for
   2.0).
** **printf()** to the screen, and **print()** to the screen are both
   significantly faster in most cases.
** The **trace** screen is updated a bit faster.
** The **time profile** is more accurate regarding **getc()**.
** The **mset.ex** demo runs 30% faster.



!!CONTEXT:../docs/release/1.5.1.txt
%%output = release_1.5.1

== Version 1.5.1 (release a) June 13, 1997

* Many operations and library routines were optimized.
* **get_key()** is 100x faster when there is no key in the buffer.
* **get_all_palette()** is over 100x faster and this makes **save_screen()** much
  faster.
* The following routines have now been built directly into **ex.exe**, to avoid
  the overhead of calling machine_proc() or machine_func(): **pixel()**,
  **get_pixel()**, **mem_set()**, **mem_copy()**.
* **poke()** of a long sequence into memory, other than video memory, is 50% faster.
* **pixel()** is 4x faster in mode 19.
* **get_pixel()** is faster in all modes.
* **display_image()** is about 30% faster in most modes and up to 4x faster in
  mode 19, because <br>pixel() is faster.
* All arithmetic and bitwise operations applied to sequences of integers are now 29% faster.
* a **&** b (concatenation) is 15% faster in most cases, and is dramatically faster in the case
  where you grow a very long sequence by concatenating many small sequences onto it.
* **getc()** is 12% faster.
* **match()** is 8% faster in typical cases.
* **append()/prepend()** are 15% faster in many cases.
* **find()** of an integer within a sequence of integers is 64% faster.
* Formation of a 2-element sequence **{a,b}** is 11% faster.
* Internal copying of a shared sequence when it can no longer be shared is 15%
  faster.


!!CONTEXT:../docs/release/1.5.0.txt
%%output = release_1.5.0

== Version 1.5 March 21, 1997

* The following library routines were added. They are described fully
  in **library.doc**.
** **allow_break()**
** **check_break()**
** **mem_copy()**
** **mem_set()**
** **atom_to_float32()**
** **atom_to_float64()**
** **float32_to_atom()**
** **float64_to_atom()**
** **get_all_palette()**
** **save_bitmap()**
** **save_screen()**
** **arctan()**
** **and_bits()**
** **or_bits()**
** **xor_bits()**
** **not_bits()**
** **get_vector()**
** **set_vector()**
** **lock_memory()**
** **tick_rate()**
* **with profile_time** (time profiling for DOS32) was added.



!!CONTEXT:../docs/release/1.4.2.txt
%%output = release_1.4.2

== Version 1.4.2 (release b) October 1996

* **mset.ex** has a more visible selector box on it's grid. It has also been sped up.
* **ed.ex** now allows special characters greater than ASCII 127 to be entered by
  pressing the **Alt** key and typing digits on the numeric keypad.



!!CONTEXT:../docs/release/1.4.1.txt
%%output = release_1.4.1

== Version 1.4.1 (release a) July 1996

* **crash_message()** library routine was added.
* Programs **bound** by registered users will now produce run-time error
  diagnostics regardless of the size of the program.
* **shroud.bat** has a new option ##-full_keywords##.



!!CONTEXT:../docs/release/1.4.0.txt
%%output = release_1.4.0

== Version 1.4 May 1996

* You can now convert any Euphoria program into a **stand-alone .exe** file.
* The separate DOS4GW.EXE DOS extender file has been eliminated.
* Windows 95 long filename support.
* Support for DOS software interrupts.
* New utility programs: **key.ex**, **where.ex**, **ascii.ex**, **guru.ex**.
* New demo program: **dosint.ex**.
* New library routines: **set_rand()**, **use_vesa()**.
* You can peek or poke an entire sequence of bytes.
* Editor enhancements.
* Reduction in space overhead for sequences.



!!CONTEXT:../docs/release/1.3.0.txt
%%output = release_1.3.0

== Version 1.3 June 1995

* You can now edit multiple files using multiple edit windows.
* 20 new library routines were added.
* Graphics performance was greatly improved.



!!CONTEXT:../docs/release/1.2.0.txt
%%output = release_1.2.0

== Version 1.2 March 1994

* A problem that prevented Euphoria from running in a DOS prompt under Windows was eliminated.


!!CONTEXT:../docs/release/1.1.0.txt
%%output = release_1.1.0

== Version 1.1 January 1994

* Several language features and demo programs were added.



!!CONTEXT:../docs/release/1.0.0.txt
%%output = release_1.0.0

== Version 1.0 July 1993

Euphoria was first released after 3 years of research and development
and 6 months of Beta testing. Many of the ideas behind Euphoria came
from Robert Craig's Master's Thesis in Computer Science at the University
of Toronto. That thesis was strongly influenced by the work of John Backus
on functional programming (FP) languages.


%%output=key_index
= Index
<<INDEX search>>
