aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/doc/text
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/doc/text')
-rw-r--r--libslang/doc/text/cref.txt4870
-rw-r--r--libslang/doc/text/cslang.txt2989
-rw-r--r--libslang/doc/text/slang.txt5642
-rw-r--r--libslang/doc/text/slangfun.txt5943
4 files changed, 19444 insertions, 0 deletions
diff --git a/libslang/doc/text/cref.txt b/libslang/doc/text/cref.txt
new file mode 100644
index 0000000..fca54da
--- /dev/null
+++ b/libslang/doc/text/cref.txt
@@ -0,0 +1,4870 @@
+SLsmg_fill_region
+
+ SYNOPSIS
+ Fill a rectangular region with a character
+
+ USAGE
+ void SLsmg_fill_region (r, c, nr, nc, ch)
+
+ int r
+ int c
+ unsigned int nr
+ unsigned int nc
+ unsigned char ch
+
+
+ DESCRIPTION
+ The `SLsmg_fill_region' function may be used to a
+ rectangular region with the character `ch' in the current color.
+ The rectangle's upper left corner is at row `r' and column
+ `c', and spans `nr' rows and `nc' columns. The position
+ of the virtual cursor will be left at (`r', `c').
+
+ SEE ALSO
+ SLsmg_write_char, SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_set_char_set
+
+ SYNOPSIS
+ Turn on or off line drawing characters
+
+ USAGE
+ void SLsmg_set_char_set (int a);
+
+ DESCRIPTION
+ `SLsmg_set_char_set' may be used to select or deselect the line drawing
+ character set as the current character set. If `a' is non-zero,
+ the line drawing character set will be selected. Otherwise, the
+ standard character set will be selected.
+
+ NOTES
+ There is no guarantee that this function will actually enable the
+ use of line drawing characters. All it does is cause subsequent
+ characters to be rendered using the terminal's alternate character
+ set. Such character sets usually contain line drawing characters.
+
+ SEE ALSO
+ SLsmg_write_char, SLtt_get_terminfo
+--------------------------------------------------------------
+
+int SLsmg_Scroll_Hash_Border;
+
+ SYNOPSIS
+ Set the size of the border for the scroll hash
+
+ USAGE
+ int SLsmg_Scroll_Hash_Border = 0;
+
+ DESCRIPTION
+ This variable may be used to ignore the characters that occur at the
+ beginning and the end of a row when performing the hash calculation
+ to determine whether or not a line has scrolled. The default value
+ is zero which means that all the characters on a line will be used.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_suspend_smg
+
+ SYNOPSIS
+ Suspend screen management
+
+ USAGE
+ int SLsmg_suspend_smg (void)
+
+ DESCRIPTION
+ `SLsmg_suspend_smg' can be used to suspend the state of the
+ screen management facility during suspension of the program. Use of
+ this function will reset the display back to its default state. The
+ funtion `SLsmg_resume_smg' should be called after suspension.
+
+ It returns zero upon success, or -1 upon error.
+
+ This function is similar to `SLsmg_reset_smg' except that the
+ state of the display prior to calling `SLsmg_suspend_smg' is saved.
+
+ SEE ALSO
+ SLsmg_resume_smg, SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_resume_smg
+
+ SYNOPSIS
+ Resume screen management
+
+ USAGE
+ int SLsmg_resume_smg (void)
+
+ DESCRIPTION
+ `SLsmg_resume_smg' should be called after
+ `SLsmg_suspend_smg' to redraw the display exactly like it was
+ before `SLsmg_suspend_smg' was called. It returns zero upon
+ success, or -1 upon error.
+
+ SEE ALSO
+ SLsmg_suspend_smg
+--------------------------------------------------------------
+
+SLsmg_erase_eol
+
+ SYNOPSIS
+ Erase to the end of the row
+
+ USAGE
+ void SLsmg_erase_eol (void);
+
+ DESCRIPTION
+ `SLsmg_erase_eol' erases all characters from the current
+ position to the end of the line. The newly created space is given
+ the color of the current color. This function has no effect on the
+ position of the virtual cursor.
+
+ SEE ALSO
+ SLsmg_gotorc, SLsmg_erase_eos, SLsmg_fill_region
+--------------------------------------------------------------
+
+SLsmg_gotorc
+
+ SYNOPSIS
+ Move the virtual cursor
+
+ USAGE
+ void SLsmg_gotorc (int r, int c)
+
+ DESCRIPTION
+ The `SLsmg_gotorc' function moves the virtual cursor to the row
+ `r' and column `c'. The first row and first column is
+ specified by `r = 0' and `c = 0'.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_erase_eos
+
+ SYNOPSIS
+ Erase to the end of the screen
+
+ USAGE
+ void SLsmg_erase_eos (void);
+
+ DESCRIPTION
+ The `SLsmg_erase_eos' is like `SLsmg_erase_eol' except that
+ it erases all text from the current position to the end of the
+ display. The current color will be used to set the background of
+ the erased area.
+
+ SEE ALSO
+ SLsmg_erase_eol
+--------------------------------------------------------------
+
+SLsmg_reverse_video
+
+ SYNOPSIS
+ Set the current color to 1
+
+ USAGE
+ void SLsmg_reverse_video (void);
+
+ DESCRIPTION
+ This function is nothing more than `SLsmg_set_color(1)'.
+
+ SEE ALSO
+ SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_set_color (int)
+
+ SYNOPSIS
+ Set the current color
+
+ USAGE
+ void SLsmg_set_color (int c);
+
+ DESCRIPTION
+ `SLsmg_set_color' is used to set the current color. The
+ parameter `c' is really a color object descriptor. Actual
+ foreground and background colors as well as other visual attributes
+ may be associated with a color descriptor via the
+ `SLtt_set_color' function.
+
+ EXAMPLE
+ This example defines color `7' to be green foreground on black
+ background and then displays some text in this color:
+
+ SLtt_set_color (7, NULL, "green", "black");
+ SLsmg_set_color (7);
+ SLsmg_write_string ("Hello");
+ SLsmg_refresh ();
+
+
+ NOTES
+ It is important to understand that the screen managment routines
+ know nothing about the actual colors associated with a color
+ descriptor. Only the descriptor itself is used by the `SLsmg'
+ routines. The lower level `SLtt' interface converts the color
+ descriptors to actual colors. Thus
+
+ SLtt_set_color (7, NULL, "green", "black");
+ SLsmg_set_color (7);
+ SLsmg_write_string ("Hello");
+ SLtt_set_color (7, NULL, "red", "blue");
+ SLsmg_write_string ("World");
+ SLsmg_refresh ();
+
+ will result in `"hello"' displayed in red on blue and _not_
+ green on black.
+
+ SEE ALSO
+ SLtt_set_color, SLtt_set_color_object
+--------------------------------------------------------------
+
+SLsmg_normal_video
+
+ SYNOPSIS
+ Set the current color to 0
+
+ USAGE
+ void SLsmg_normal_video (void);
+
+ DESCRIPTION
+ `SLsmg_normal_video' sets the current color descriptor to `0'.
+
+ SEE ALSO
+ SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_printf
+
+ SYNOPSIS
+ Format a string on the virtual display
+
+ USAGE
+ void SLsmg_printf (char *fmt, ...)
+
+ DESCRIPTION
+ `SLsmg_printf' format a `printf' style variable argument
+ list and writes it on the virtual display. The virtual cursor will
+ be moved to the end of the string.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_vprintf
+--------------------------------------------------------------
+
+SLsmg_vprintf
+
+ SYNOPSIS
+ Format a string on the virtual display
+
+ USAGE
+ void SLsmg_vprintf (char *fmt, va_list ap)
+
+ DESCRIPTION
+ `SLsmg_vprintf' formats a string in the manner of _vprintf_
+ and writes the result to the display. The virtual cursor is
+ advanced to the end of the string.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_printf
+--------------------------------------------------------------
+
+SLsmg_write_string
+
+ SYNOPSIS
+ Write a character string on the display
+
+ USAGE
+ void SLsmg_write_string (char *s)
+
+ DESCRIPTION
+ The function `SLsmg_write_string' displays the string `s' on
+ the virtual display at the current position and moves the position
+ to the end of the string.
+
+ SEE ALSO
+ SLsmg_printf, SLsmg_write_nstring
+--------------------------------------------------------------
+
+SLsmg_write_nstring
+
+ SYNOPSIS
+ Write the first n characters of a string on the display
+
+ USAGE
+ void SLsmg_write_nstring (char *s, unsigned int n);
+
+ DESCRIPTION
+ `SLsmg_write_nstring' writes the first `n' characters of
+ `s' to this virtual display. If the length of the string
+ `s' is less than `n', the spaces will used until
+ `n' characters have been written. `s' can be `NULL', in
+ which case `n' spaces will be written.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_write_nchars
+--------------------------------------------------------------
+
+SLsmg_write_char
+
+ SYNOPSIS
+ Write a character to the virtual display
+
+ USAGE
+ void SLsmg_write_char (char ch);
+
+ DESCRIPTION
+ `SLsmg_write_char' writes the character `ch' to the virtual
+ display.
+
+ SEE ALSO
+ SLsmg_write_nchars, SLsmg_write_string
+--------------------------------------------------------------
+
+SLsmg_write_nchars
+
+ SYNOPSIS
+ Write n characters to the virtual display
+
+ USAGE
+ void SLsmg_write_nchars (char *s, unsigned int n);
+
+ DESCRIPTION
+ `SLsmg_write_nchars' writes at most `n' characters from the
+ string `s' to the display. If the length of `s' is less
+ than `n', the whole length of the string will get written.
+
+ This function differs from `SLsmg_write_nstring' in that
+ `SLsmg_write_nstring' will pad the string to write exactly
+ `n' characters. `SLsmg_write_nchars' does not perform any
+ padding.
+
+ SEE ALSO
+ SLsmg_write_nchars, SLsmg_write_nstring
+--------------------------------------------------------------
+
+SLsmg_write_wrapped_string
+
+ SYNOPSIS
+ Write a string to the display with wrapping
+
+ USAGE
+ void SLsmg_write_wrapped_string (s, r, c, nr, nc, fill)
+
+ char *s
+ int r, c
+ unsigned int nr, nc
+ int fill
+
+
+ DESCRIPTION
+ `SLsmg_write_wrapped_string' writes the string `s' to the
+ virtual display. The string will be confined to the rectangular
+ region whose upper right corner is at row `r' and column `c',
+ and consists of `nr' rows and `nc' columns. The string will
+ be wrapped at the boundaries of the box. If `fill' is non-zero,
+ the last line to which characters have been written will get padded
+ with spaces.
+
+ NOTES
+ This function does not wrap on word boundaries. However, it will
+ wrap when a newline charater is encountered.
+
+ SEE ALSO
+ SLsmg_write_string
+--------------------------------------------------------------
+
+SLsmg_cls
+
+ SYNOPSIS
+ Clear the virtual display
+
+ USAGE
+ void SLsmg_cls (void)
+
+ DESCRIPTION
+ `SLsmg_cls' erases the virtual display using the current color.
+ This will cause the physical display to get cleared the next time
+ `SLsmg_refresh' is called.
+
+ NOTES
+ This function is not the same as
+
+ SLsmg_gotorc (0,0); SLsmg_erase_eos ();
+
+ since these statements do not guarantee that the physical screen
+ will get cleared.
+
+ SEE ALSO
+ SLsmg_refresh, SLsmg_erase_eos
+--------------------------------------------------------------
+
+SLsmg_refresh
+
+ SYNOPSIS
+ Update physical screen
+
+ USAGE
+ void SLsmg_refresh (void)
+
+ DESCRIPTION
+ The `SLsmg_refresh' function updates the physical display to
+ look like the virtual display.
+
+ SEE ALSO
+ SLsmg_suspend_smg, SLsmg_init_smg, SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_touch_lines
+
+ SYNOPSIS
+ Mark lines on the virtual display for redisplay
+
+ USAGE
+ void SLsmg_touch_lines (int r, unsigned int nr)
+
+ DESCRIPTION
+ `SLsmg_touch_lines' marks the `nr' lines on the virtual
+ display starting at row `r' for redisplay upon the next call to
+ `SLsmg_refresh'.
+
+ NOTES
+ This function should rarely be called, if ever. If you find that
+ you need to call this function, then your application should be
+ modified to properly use the `SLsmg' screen management routines.
+ This function is provided only for curses compatibility.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_init_smg
+
+ SYNOPSIS
+ Initialize the var{SLsmg
+
+ USAGE
+ int SLsmg_init_smg (void)
+
+ DESCRIPTION
+ The `SLsmg_init_smg' function initializes the `SLsmg' screen
+ management routines. Specifically, this function allocates space
+ for the virtual display and calls `SLtt_init_video' to put the
+ terminal's physical display in the proper state. It is up to the
+ caller to make sure that the `SLtt' routines are initialized via
+ `SLtt_get_terminfo' before calling `SLsmg_init_smg'.
+
+ This function should also be called any time the size of the
+ physical display has changed so that it can reallocate a new virtual
+ display to match the physical display.
+
+ It returns zero upon success, or -1 upon failure.
+
+ SEE ALSO
+ SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_reset_smg
+
+ SYNOPSIS
+ Reset the var{SLsmg
+
+ USAGE
+ int SLsmg_reset_smg (void);
+
+ DESCRIPTION
+ `SLsmg_reset_smg' resets the `SLsmg' screen management
+ routines by freeing all memory allocated while it was active. It
+ also calls `SLtt_reset_video' to put the terminal's display in
+ it default state.
+
+ SEE ALSO
+ SLsmg_init_smg
+--------------------------------------------------------------
+
+SLsmg_char_at
+
+ SYNOPSIS
+ Get the character at the current position on the virtual display
+
+ USAGE
+ unsigned short SLsmg_char_at(void)
+
+ DESCRIPTION
+ The `SLsmg_char_at' function returns the character and its color
+ at the current position on the virtual display.
+
+ SEE ALSO
+ SLsmg_read_raw, SLsmg_write_char
+--------------------------------------------------------------
+
+SLsmg_set_screen_start
+
+ SYNOPSIS
+ Set the origin of the virtual display
+
+ USAGE
+ void SLsmg_set_screen_start (int *r, int *c)
+
+ DESCRIPTION
+ `SLsmg_set_screen_start' sets the origin of the virtual display
+ to the row `*r' and the column `*c'. If either `r' or `c'
+ is `NULL', then the corresponding value will be set to `0'.
+ Otherwise, the location specified by the pointers will be updated to
+ reflect the old origin.
+
+ See \tt{slang/demo/pager.c} for how this function may be used to
+ scroll horizontally.
+
+ SEE ALSO
+ SLsmg_init_smg
+--------------------------------------------------------------
+
+SLsmg_draw_hline
+
+ SYNOPSIS
+ Draw a horizontal line
+
+ USAGE
+ void SLsmg_draw_hline (unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_draw_hline' function draws a horizontal line of
+ length `len' on the virtual display. The position of the
+ virtual cursor is left at the end of the line.
+
+ SEE ALSO
+ SLsmg_draw_vline
+--------------------------------------------------------------
+
+SLsmg_draw_vline
+
+ SYNOPSIS
+ Draw a vertical line
+
+ USAGE
+ void SLsmg_draw_vline (unsigned int len);
+
+ DESCRIPTION
+ The `SLsmg_draw_vline' function draws a vertical line of
+ length `len' on the virtual display. The position of the
+ virtual cursor is left at the end of the line.
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLsmg_draw_object
+
+ SYNOPSIS
+ Draw an object from the alternate character set
+
+ USAGE
+ void SLsmg_draw_object (int r, int c, unsigned char obj)
+
+ DESCRIPTION
+ The `SLsmg_draw_object' function may be used to place the object
+ specified by `obj' at row `r' and column `c'. The
+ object is really a character from the alternate character set and
+ may be specified using one of the following constants:
+
+ SLSMG_HLINE_CHAR Horizontal line
+ SLSMG_VLINE_CHAR Vertical line
+ SLSMG_ULCORN_CHAR Upper left corner
+ SLSMG_URCORN_CHAR Upper right corner
+ SLSMG_LLCORN_CHAR Lower left corner
+ SLSMG_LRCORN_CHAR Lower right corner
+ SLSMG_CKBRD_CHAR Checkboard character
+ SLSMG_RTEE_CHAR Right Tee
+ SLSMG_LTEE_CHAR Left Tee
+ SLSMG_UTEE_CHAR Up Tee
+ SLSMG_DTEE_CHAR Down Tee
+ SLSMG_PLUS_CHAR Plus or Cross character
+
+
+ SEE ALSO
+ SLsmg_draw_vline, SLsmg_draw_hline, SLsmg_draw_box
+--------------------------------------------------------------
+
+SLsmg_draw_box
+
+ SYNOPSIS
+ Draw a box on the virtual display
+
+ USAGE
+ void SLsmg_draw_box (int r, int c, unsigned int dr, unsigned int dc)
+
+ DESCRIPTION
+ `SLsmg_draw_box' uses the `SLsmg_draw_hline' and
+ `SLsmg_draw_vline' functions to draw a rectangular box on the
+ virtual display. The box's upper left corner is placed at row
+ `r' and column `c'. The width and length of the box is
+ specified by `dc' and `dr', respectively.
+
+ SEE ALSO
+ SLsmg_draw_vline, SLsmg_draw_hline, SLsmg_draw_object
+--------------------------------------------------------------
+
+SLsmg_set_color_in_region
+
+ SYNOPSIS
+ Change the color of a specifed region
+
+ USAGE
+ void SLsmg_set_color_in_region (color, r, c, dr, dc)
+
+ int color;
+ int r, c;
+ unsigned int dr, dc;
+
+
+ DESCRIPTION
+ `SLsmg_set_color_in_region' may be used to change the color of a
+ rectangular region whose upper left corner is given by
+ (`r',`c'), and whose width and height is given by `dc'
+ and `dr', respectively. The color of the region is given by the
+ `color' parameter.
+
+ SEE ALSO
+ SLsmg_draw_box, SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_get_column
+
+ SYNOPSIS
+ Get the column of the virtual cursor
+
+ USAGE
+ int SLsmg_get_column(void);
+
+ DESCRIPTION
+ The `SLsmg_get_column' function returns the current column of
+ the virtual cursor on the virtual display.
+
+ SEE ALSO
+ SLsmg_get_row, SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_get_row
+
+ SYNOPSIS
+ Get the row of the virtual cursor
+
+ USAGE
+ int SLsmg_get_row(void);
+
+ DESCRIPTION
+ The `SLsmg_get_row' function returns the current row of the
+ virtual cursor on the virtual display.
+
+ SEE ALSO
+ SLsmg_get_column, SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_forward
+
+ SYNOPSIS
+ Move the virtual cursor forward n columns
+
+ USAGE
+ void SLsmg_forward (int n);
+
+ DESCRIPTION
+ The `SLsmg_forward' function moves the virtual cursor forward
+ `n' columns.
+
+ SEE ALSO
+ SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_write_color_chars
+
+ SYNOPSIS
+ Write characters with color descriptors to virtual display
+
+ USAGE
+ void SLsmg_write_color_chars (unsigned short *s, unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_write_color_chars' function may be used to write
+ `len' characters, each with a different color descriptor to the
+ virtual display. Each character and its associated color are
+ encoded as an `unsigned short' such that the lower eight bits
+ form the character and the next eight bits form the color.
+
+ SEE ALSO
+ SLsmg_char_at, SLsmg_write_raw
+--------------------------------------------------------------
+
+SLsmg_read_raw
+
+ SYNOPSIS
+ Read characters from the virtual display
+
+ USAGE
+ unsigned int SLsmg_read_raw (unsigned short *buf, unsigned int len)
+
+ DESCRIPTION
+ `SLsmg_read_raw' attempts to read `len' characters from the
+ current position on the virtual display into the buffer specified by
+ `buf'. It returns the number of characters actually read. This
+ number will be less than `len' if an attempt is made to read
+ past the right margin of the display.
+
+ NOTES
+ The purpose of the pair of functions, `SLsmg_read_raw' and
+ `SLsmg_write_raw', is to permit one to copy the contents of one
+ region of the virtual display to another region.
+
+ SEE ALSO
+ SLsmg_char_at, SLsmg_write_raw
+--------------------------------------------------------------
+
+SLsmg_write_raw
+
+ SYNOPSIS
+ Write characters directly to the virtual display
+
+ USAGE
+ unsigned int SLsmg_write_raw (unsigned short *buf, unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_write_raw' function attempts to write `len'
+ characters specified by `buf' to the display at the current
+ position. It returns the number of characters successfully written,
+ which will be less than `len' if an attempt is made to write
+ past the right margin.
+
+ NOTES
+ The purpose of the pair of functions, `SLsmg_read_raw' and
+ `SLsmg_write_raw', is to permit one to copy the contents of one
+ region of the virtual display to another region.
+
+ SEE ALSO
+ SLsmg_read_raw
+--------------------------------------------------------------
+
+SLallocate_load_type
+
+ SYNOPSIS
+ Allocate a SLang_Load_Type object
+
+ USAGE
+ SLang_Load_Type *SLallocate_load_type (char *name)
+
+ DESCRIPTION
+ The `SLallocate_load_type' function allocates and initializes
+ space for a `SLang_Load_Type' object and returns it. Upon
+ failure, the function returns `NULL'. The parameter `name'
+ must uniquely identify the object. For example, if the object
+ represents a file, then `name' could be the absolute path name
+ of the file.
+
+ SEE ALSO
+ SLdeallocate_load_type, SLang_load_object
+--------------------------------------------------------------
+
+SLdeallocate_load_type
+
+ SYNOPSIS
+ Free a SLang_Load_Type object
+
+ USAGE
+ void SLdeallocate_load_type (SLang_Load_Type *slt)
+
+ DESCRIPTION
+ This function frees the memory associated with a
+ `SLang_Load_Type' object that was acquired from a call to the
+ `SLallocate_load_type' function.
+
+ SEE ALSO
+ SLallocate_load_type, SLang_load_object
+--------------------------------------------------------------
+
+SLang_load_object
+
+ SYNOPSIS
+ Load an object into the interpreter
+
+ USAGE
+ int SLang_load_object (SLang_Load_Type *obj)
+
+ DESCRIPTION
+ The function `SLang_load_object' is a generic function that may
+ be used to loaded an object of type `SLang_Load_Type' into the
+ interpreter. For example, the functions `SLang_load_file' and
+ `SLang_load_string' are wrappers around this function to load a
+ file and a string, respectively.
+
+ SEE ALSO
+ SLang_load_file, SLang_load_string, SLallocate_load_type
+--------------------------------------------------------------
+
+SLclass_allocate_class
+
+ SYNOPSIS
+ Allocate a class for a new data type
+
+ USAGE
+ SLang_Class_Type *SLclass_allocate_class (char *name)
+
+ DESCRIPTION
+ The purpose of this function is to allocate and initialize space
+ that defines a new data type or class called `name'. If
+ successful, a pointer to the class is returned, or upon failure the
+ function returns `NULL'.
+
+ This function does not automatically create the new data type.
+ Callback functions must first be associated with the data type via
+ functions such as `SLclass_set_push_function', and the data
+ type must be registered with the interpreter via
+ `SLclass_register_class'. See the S-Lang library programmer's
+ guide for more information.
+
+ SEE ALSO
+ SLclass_register_class, SLclass_set_push_function
+--------------------------------------------------------------
+
+SLclass_register_class
+
+ SYNOPSIS
+ Register a new data type with the interpreter
+
+ USAGE
+ int SLclass_register_class (cl, type, sizeof_type, class_type)
+
+ SLang_Class_Type *cl
+ unsigned char type
+ unsigned int sizeof_type
+ unsigned char class_type
+
+
+ DESCRIPTION
+ The `SLclass_register_class' function is used to register a new
+ class or data type with the interpreter. If successful, the
+ function returns `0', or upon failure, it returns `-1'.
+
+ The first parameter, `cl', must have been previously obtained
+ via the `SLclass_allocate_class' function.
+
+ The second parameter, `type' specifies the data type of the new
+ class. It must be an unsigned character with value greater that
+ `127'. The values in the range `0-127' are reserved for
+ internal use by the library.
+
+ The size that the data type represents in bytes is specified by the
+ third parameter, `sizeof_type'. This value should not be
+ confused with the sizeof the structure that represents the data
+ type, unless the data type is of class `SLANG_CLASS_TYPE_VECTOR'
+ or `SLANG_CLASS_TYPE_SCALAR'. For pointer objects, the value
+ of this parameter is just `sizeof(void *)'.
+
+ The final parameter specifies the class type of the data type. It must
+ be one of the values:
+
+ SLANG_CLASS_TYPE_SCALAR
+ SLANG_CLASS_TYPE_VECTOR
+ SLANG_CLASS_TYPE_PTR
+ SLANG_CLASS_TYPE_MMT
+
+ The `SLANG_CLASS_TYPE_SCALAR' indicates that the new data type
+ is a scalar. Examples of scalars in `SLANG_INT_TYPE' and
+ `SLANG_DOUBLE_TYPE'.
+
+ Setting `class_type' to SLANG_CLASS_TYPE_VECTOR implies that the
+ new data type is a vector, or a 1-d array of scalar types. An
+ example of a data type of this class is the
+ `SLANG_COMPLEX_TYPE', which represents complex numbers.
+
+ `SLANG_CLASS_TYPE_PTR' specifies the data type is of a pointer
+ type. Examples of data types of this class include
+ `SLANG_STRING_TYPE' and `SLANG_ARRAY_TYPE'. Such types must
+ provide for their own memory management.
+
+ Data types of class `SLANG_CLASS_TYPE_MMT' are pointer types
+ except that the memory management, i.e., creation and destruction of
+ the type, is handled by the interpreter. Such a type is called a
+ _memory managed type_. An example of this data type is the
+ `SLANG_FILEPTR_TYPE'.
+
+ NOTES
+ See the \slang-c-programmers-guide for more information.
+
+ SEE ALSO
+ SLclass_allocate_class
+--------------------------------------------------------------
+
+SLclass_set_string_function
+
+ SYNOPSIS
+ Set a data type's string representation callback
+
+ USAGE
+ int SLclass_set_string_function (cl, sfun)
+
+ SLang_Class_Type *cl
+ char *(*sfun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ The `SLclass_set_string_function' routine is used to define a
+ callback function, `sfun', that will be used when a string
+ representation of an object of the data type represented by `cl'
+ is needed. `cl' must have already been obtained via a call to
+ `SLclass_allocate_class'. When called, `sfun' will be
+ passed two arguments: a unsigned char which represents the data
+ type, and the address of the object for which a string represetation
+ is required. The callback function must return a _malloced_
+ string.
+
+ Upon success, `SLclass_set_string_function' returns zero, or
+ upon error it returns -1.
+
+ EXAMPLE
+ A callback function that handles both `SLANG_STRING_TYPE' and
+ `SLANG_INT_TYPE' variables looks like:
+
+ char *string_and_int_callback (unsigned char type, VOID_STAR addr)
+ {
+ char buf[64];
+
+ switch (type)
+ {
+ case SLANG_STRING_TYPE:
+ return SLmake_string (*(char **)addr);
+
+ case SLANG_INTEGER_TYPE:
+ sprintf (buf, "%d", *(int *)addr);
+ return SLmake_string (buf);
+ }
+ return NULL;
+ }
+
+
+ NOTES
+ The default string callback simply returns the name of the data type.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_destroy_function
+
+ SYNOPSIS
+ Set the destroy method callback for a data type
+
+ USAGE
+ int SLclass_set_destroy_function (cl, destroy_fun)
+
+ SLang_Class_Type *cl
+ void (*destroy_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_destroy_function' is used to set the destroy
+ callback for a data type. The data type's class `cl' must have
+ been previously obtained via a call to `SLclass_allocate_class'.
+ When called, `destroy_fun' will be passed two arguments: a
+ unsigned char which represents the data type, and the address of the
+ object to be destroyed.
+
+ `SLclass_set_destroy_function' returns zero upon success, and
+ -1 upon failure.
+
+ EXAMPLE
+ The destroy method for `SLANG_STRING_TYPE' looks like:
+
+ static void string_destroy (unsigned char type, VOID_STAR ptr)
+ {
+ char *s = *(char **) ptr;
+ if (s != NULL) SLang_free_slstring (*(char **) s);
+ }
+
+
+ NOTES
+ Data types of class SLANG_CLASS_TYPE_SCALAR do not require a destroy
+ callback. However, other classes do.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_push_function
+
+ SYNOPSIS
+ Set the push callback for a new data type
+
+ USAGE
+ int SLclass_set_push_function (cl, push_fun)
+
+ SLang_Class_Type *cl
+ int (*push_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_push_function' is used to set the push callback
+ for a new data type specified by `cl', which must have been
+ previously obtained via `SLclass_allocate_class'.
+
+ The parameter `push_fun' is a pointer to the push callback. It
+ is required to take two arguments: an unsigned character
+ representing the data type, and the address of the object to be
+ pushed. It must return zero upon success, or -1 upon failure.
+
+ `SLclass_set_push_function' returns zero upon success, or -1
+ upon failure.
+
+ EXAMPLE
+ The push callback for `SLANG_COMPLEX_TYPE' looks like:
+
+ static int complex_push (unsigned char type, VOID_STAR ptr)
+ {
+ double *z = *(double **) ptr;
+ return SLang_push_complex (z[0], z[1]);
+ }
+
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_pop_function
+
+ SYNOPSIS
+ Set the pop callback for a new data type
+
+ USAGE
+ int SLclass_set_pop_function (cl, pop_fun)
+
+ SLang_Class_Type *cl
+ int (*pop_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_pop_function' is used to set the callback for
+ popping an object from the stack for a new data type specified by
+ `cl', which must have been previously obtained via
+ `SLclass_allocate_class'.
+
+ The parameter `pop_fun' is a pointer to the pop callback
+ function, which is required to take two arguments: an unsigned
+ character representing the data type, and the address of the object
+ to be popped. It must return zero upon success, or -1 upon
+ failure.
+
+ `SLclass_set_pop_function' returns zero upon success, or -1
+ upon failure.
+
+ EXAMPLE
+ The pop callback for `SLANG_COMPLEX_TYPE' looks like:
+
+ static int complex_push (unsigned char type, VOID_STAR ptr)
+ {
+ double *z = *(double **) ptr;
+ return SLang_pop_complex (&z[0], &z[1]);
+ }
+
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_get_datatype_name
+
+ SYNOPSIS
+ Get the name of a data type
+
+ USAGE
+ char *SLclass_get_datatype_name (unsigned char type)
+
+ DESCRIPTION
+ The `SLclass_get_datatype_name' function returns the name of the
+ data type specified by `type'. For example, if `type' is
+ `SLANG_INT_TYPE', the string `"Integer_Type"' will be
+ returned.
+
+ This function returns a pointer that should not be modified or freed.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLang_free_mmt
+
+ SYNOPSIS
+ Free a memory managed type
+
+ USAGE
+ void SLang_free_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ The `SLang_MMT_Type' function is used to free a memory managed
+ data type.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_create_mmt
+--------------------------------------------------------------
+
+SLang_object_from_mmt
+
+ SYNOPSIS
+ Get a pointer to the value of a memory managed type
+
+ USAGE
+ VOID_STAR SLang_object_from_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ The `SLang_object_from_mmt' function returns a pointer to the
+ actual object whose memory is being managed by the interpreter.
+
+ SEE ALSO
+ SLang_free_mmt, SLang_create_mmt
+--------------------------------------------------------------
+
+SLang_create_mmt
+
+ SYNOPSIS
+ Create a memory managed data type
+
+ USAGE
+ SLang_MMT_Type *SLang_create_mmt (unsigned char t, VOID_STAR ptr)
+
+ DESCRIPTION
+ The `SLang_create_mmt' function returns a pointer to a new
+ memory managed object. This object contains information necessary
+ to manage the memory associated with the pointer `ptr' which
+ represents the application defined data type of type `t'.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_push_mmt, SLang_free_mmt
+--------------------------------------------------------------
+
+SLang_push_mmt
+
+ SYNOPSIS
+ Push a memory managed type
+
+ USAGE
+ int SLang_push_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ This function is used to push a memory managed type onto the
+ interpreter stack. It returns zero upon success, or `-1' upon
+ failure.
+
+ SEE ALSO
+ SLang_create_mmt, SLang_pop_mmt
+--------------------------------------------------------------
+
+SLang_pop_mmt
+
+ SYNOPSIS
+ Pop a memory managed data type
+
+ USAGE
+ SLang_MMT_Type *SLang_pop_mmt (unsigned char t)
+
+ DESCRIPTION
+ The `SLang_pop_mmt' function may be used to pop a memory managed
+ type of type `t' from the stack. It returns a pointer to the
+ memory managed object upon success, or `NULL' upon failure. The
+ function `SLang_object_from_mmt' should be used to access the
+ actual pointer to the data type.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_push_mmt
+--------------------------------------------------------------
+
+SLang_inc_mmt
+
+ SYNOPSIS
+ Increment a memory managed type reference count
+
+ USAGE
+ void SLang_inc_mmt (SLang_MMT_Type *mmt);
+
+ DESCRIPTION
+ The `SLang_inc_mmt' function may be used to increment the
+ reference count associated with the memory managed data type given
+ by `mmt'.
+
+ SEE ALSO
+ SLang_free_mmt, SLang_create_mmt, SLang_pop_mmt, SLang_pop_mmt
+--------------------------------------------------------------
+
+SLang_vmessage
+
+ SYNOPSIS
+ Display a message to the message device
+
+ USAGE
+ void SLang_vmessage (char *fmt, ...)
+
+ DESCRIPTION
+ This function prints a `printf' style formatted variable
+ argument list to the message device. The default message device is
+ `stdout'.
+
+ SEE ALSO
+ SLang_verror
+--------------------------------------------------------------
+
+SLang_exit_error
+
+ SYNOPSIS
+ Exit the program and display an error message
+
+ USAGE
+ void SLang_exit_error (char *fmt, ...)
+
+ DESCRIPTION
+ The `SLang_exit_error' function terminates the program and
+ displays an error message using a `printf' type variable
+ argument list. The default behavior to this function is to write
+ the message to `stderr' and exit with the `exit' system
+ call.
+
+ If the function pointer `SLang_Exit_Error_Hook' is
+ non-NULL, the function to which it points will be called. This
+ permits an application to perform whatever cleanup is necessary.
+ This hook has the prototype:
+
+ void (*SLang_Exit_Error_Hook)(char *, va_list);
+
+
+ SEE ALSO
+ SLang_verror, exit
+--------------------------------------------------------------
+
+SLang_init_slang
+
+ SYNOPSIS
+ Initialize the interpreter
+
+ USAGE
+ int SLang_init_slang (void)
+
+ DESCRIPTION
+ The `SLang_init_slang' function must be called by all
+ applications that use the S-Lang interpreter. It initializes the
+ interpreter, defines the built-in data types, and adds a set of core
+ intrinsic functions.
+
+ The function returns `0' upon success, or `-1' upon failure.
+
+ SEE ALSO
+ SLang_init_slfile, SLang_init_slmath, SLang_init_slunix
+--------------------------------------------------------------
+
+SLang_init_slfile
+
+ SYNOPSIS
+ Initialize the interpreter file I/O intrinsics
+
+ USAGE
+ int SLang_init_slfile (void)
+
+ DESCRIPTION
+ This function initializes the interpreters file I/O intrinsic
+ functions. This function adds intrinsic functions such as
+ `fopen', `fclose', and `fputs' to the interpreter.
+ It returns `0' if successful, or `-1' upon error.
+
+ NOTES
+ Before this function can be called, it is first necessary to call
+ `SLang_init_slang'. It also adds
+ the preprocessor symbol `__SLFILE__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slunix, SLang_init_slmath
+--------------------------------------------------------------
+
+SLang_init_slmath
+
+ SYNOPSIS
+ Initialize the interpreter math intrinsics
+
+ USAGE
+ int SLang_init_slmath (void)
+
+ DESCRIPTION
+ The `SLang_init_slmath' function initializes the interpreter's
+ mathematical intrinsic functions and makes them available to the
+ language. The intrinsic functions include `sin', `cos',
+ `tan', etc... It returns `0' if successful, or `-1'
+ upon failure.
+
+ NOTES
+ This function must be called after `SLang_init_slang'. It adds
+ the preprocessor symbol `__SLMATH__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slfile, SLang_init_slunix
+--------------------------------------------------------------
+
+SLang_init_slunix
+
+ SYNOPSIS
+ Make available some unix system calls to the interpreter
+
+ USAGE
+ int SLang_init_slunix (void)
+
+ DESCRIPTION
+ The `SLang_init_slunix' function initializes the interpreter's
+ unix system call intrinsic functions and makes them available to the
+ language. Examples of functions made available by
+ `SLang_init_slunix' include `chmod', `chown', and
+ `stat_file'. It returns `0' if successful, or `-1'
+ upon failure.
+
+ NOTES
+ This function must be called after `SLang_init_slang'. It adds
+ the preprocessor symbol `__SLUNIX__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slfile, SLang_init_slmath
+--------------------------------------------------------------
+
+SLadd_intrin_fun_table
+
+ SYNOPSIS
+ Add a table of intrinsic functions to the interpreter
+
+ USAGE
+ int SLadd_intrin_fun_table(SLang_Intrin_Fun_Type *tbl, char *pp_name);
+
+ DESCRIPTION
+ The `SLadd_intrin_fun_table' function adds an array, or table, of
+ `SLang_Intrin_Fun_Type' objects to the interpreter. The first
+ parameter, `tbl' specifies the table to be added. The second
+ parameter `pp_name', if non-NULL will be added to the list of
+ preprocessor symbols.
+
+ This function returns -1 upon failure or zero upon success.
+
+ NOTES
+ A table should only be loaded one time and it is considered to be an
+ error on the part of the application if it loads a table more than
+ once.
+
+ SEE ALSO
+ SLadd_intrin_var_table, SLadd_intrinsic_function, SLdefine_for_ifdef
+--------------------------------------------------------------
+
+SLadd_intrin_var_table
+
+ SYNOPSIS
+ Add a table of intrinsic variables to the interpreter
+
+ USAGE
+ int SLadd_intrin_var_table (SLang_Intrin_Var_Type *tbl, char *pp_name);
+
+ DESCRIPTION
+ The `SLadd_intrin_var_table' function adds an array, or table, of
+ `SLang_Intrin_Var_Type' objects to the interpreter. The first
+ parameter, `tbl' specifies the table to be added. The second
+ parameter `pp_name', if non-NULL will be added to the list of
+ preprocessor symbols.
+
+ This function returns -1 upon failure or zero upon success.
+
+ NOTES
+ A table should only be loaded one time and it is considered to be an
+ error on the part of the application if it loads a table more than
+ once.
+
+ SEE ALSO
+ SLadd_intrin_var_table, SLadd_intrinsic_function, SLdefine_for_ifdef
+--------------------------------------------------------------
+
+SLang_load_file
+
+ SYNOPSIS
+ Load a file into the interpreter
+
+ USAGE
+ int SLang_load_file (char *fn)
+
+ DESCRIPTION
+ The `SLang_load_file' function opens the file whose name is
+ specified by `fn' and feeds it to the interpreter, line by line,
+ for execution. If `fn' is `NULL', the function will take
+ input from `stdin'.
+
+ If no error occurs, it returns `0'; otherwise,
+ it returns `-1', and sets `SLang_Error' accordingly. For
+ example, if it fails to open the file, it will return `-1' with
+ `SLang_Error' set to `SL_OBJ_NOPEN'.
+
+ NOTES
+ If the hook `SLang_Load_File_Hook' declared as
+
+ int (*SLang_Load_File_Hook)(char *);
+
+ is non-NULL, the function point to by it will be used to load the
+ file. For example, the jed editor uses this hook to load files
+ via its own routines.
+
+ SEE ALSO
+ SLang_load_object, SLang_load_string
+--------------------------------------------------------------
+
+SLang_restart
+
+ SYNOPSIS
+ Reset the interpreter after an error
+
+ USAGE
+ void SLang_restart (int full)
+
+ DESCRIPTION
+ The `SLang_restart' function should be called by the
+ application at top level if an error occurs. If the parameter
+ `full' is non-zero, any objects on the S-Lang run time stack
+ will be removed from the stack; otherwise, the stack will be left
+ intact. Any time the stack is believed to be trashed, this routine
+ should be called with a non-zero argument (e.g., if
+ `setjmp'/`longjmp' is called).
+
+ Calling `SLang_restart' does not reset the global variable
+ `SLang_Error' to zero. It is up to the application to reset
+ that variable to zero after calling `SLang_restart'.
+
+ EXAMPLE
+
+ while (1)
+ {
+ if (SLang_Error)
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+ (void) SLang_load_file (NULL);
+ }
+
+
+ SEE ALSO
+ SLang_init_slang, SLang_load_file
+--------------------------------------------------------------
+
+SLang_byte_compile_file
+
+ SYNOPSIS
+ Byte-compile a file for faster loading
+
+ USAGE
+ int SLang_byte_compile_file(char *fn, int reserved)
+
+ DESCRIPTION
+ The `SLang_byte_compile_file' function ``byte-compiles'' the
+ file `fn' for faster loading by the interpreter. This produces
+ a new file whose filename is equivalent to the one specified by
+ `fn', except that a `'c'' is appended to the name. For
+ example, if `fn' is set to `init.sl', then the new file
+ will have the name exmp{init.slc}. The meaning of the second
+ parameter, `reserved', is reserved for future use. For now, set
+ it to `0'.
+
+ The function returns zero upon success, or `-1' upon error and
+ sets SLang_Error accordingly.
+
+ SEE ALSO
+ SLang_load_file, SLang_init_slang
+--------------------------------------------------------------
+
+SLang_autoload
+
+ SYNOPSIS
+ Autoload a function from a file
+
+ USAGE
+ int SLang_autoload(char *funct, char *filename)
+
+ DESCRIPTION
+ The `SLang_autoload' function may be used to associate a
+ `slang' function name `funct' with the file `filename'
+ such that if `funct' has not already been defined when needed,
+ it will be loaded from `filename'.
+
+ `SLang_autoload' has no effect if `funct' has already been
+ defined. Otherwise it declares `funct' as a user-defined S-Lang
+ function. It returns `0' upon success, or `-1' upon error.
+
+ SEE ALSO
+ SLang_load_file, SLang_is_defined
+--------------------------------------------------------------
+
+SLang_load_string
+
+ SYNOPSIS
+ Interpret a string
+
+ USAGE
+ int SLang_load_string(char *str)
+
+ DESCRIPTION
+ The `SLang_load_string' function feeds the string specified by
+ `str' to the interpreter for execution. It returns zero upon
+ success, or `-1' upon failure.
+
+ SEE ALSO
+ SLang_load_file, SLang_load_object
+--------------------------------------------------------------
+
+SLdo_pop
+
+ SYNOPSIS
+ Delete an object from the stack
+
+ USAGE
+ int SLdo_pop(void)
+
+ DESCRIPTION
+ This function removes an object from the top of the interpeter's
+ run-time stack and frees any memory associated with it. It returns
+ zero upon success, or `-1' upon error (most likely due to a
+ stack-underflow).
+
+ SEE ALSO
+ SLdo_pop_n, SLang_pop_integer, SLang_pop_string
+--------------------------------------------------------------
+
+SLdo_pop_n
+
+ SYNOPSIS
+ Delete n objects from the stack
+
+ USAGE
+ int SLdo_pop_n (unsigned int n)
+
+ DESCRIPTION
+ The `SLdo_pop_n' function removes the top `n' objects from
+ the interpreter's run-time stack and frees all memory associated
+ with the objects. It returns zero upon success, or `-1' upon
+ error (most likely due to a stack-underflow).
+
+ SEE ALSO
+ SLdo_pop, SLang_pop_integer, SLang_pop_string
+--------------------------------------------------------------
+
+SLang_pop_integer
+
+ SYNOPSIS
+ Pop an integer off the stack
+
+ USAGE
+ int SLang_pop_integer (int *i)
+
+ DESCRIPTION
+ The `SLang_pop_integer' function removes an integer from the
+ top of the interpreter's run-time stack and returns its value via
+ the pointer `i'. If successful, it returns zero. However, if
+ the top stack item is not of type `SLANG_INT_TYPE', or the
+ stack is empty, the function will return `-1' and set
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_push_integer, SLang_pop_double
+--------------------------------------------------------------
+
+SLpop_string
+
+ SYNOPSIS
+ Pop a string from the stack
+
+ USAGE
+ int SLpop_string (char **strptr);
+
+ DESCRIPTION
+ The `SLpop_string' function pops a string from the stack and
+ returns it as a malloced pointer. It is up to the calling routine
+ to free this string via a call to `free' or `SLfree'. If
+ successful, `SLpop_string' returns zero. However, if the top
+ stack item is not of type `SLANG_STRING_TYPE', or the stack is
+ empty, the function will return `-1' and set
+ `SLang_Error' accordingly.
+
+ EXAMPLE
+
+ define print_string (void)
+ {
+ char *s;
+ if (-1 == SLpop_string (&s))
+ return;
+ fputs (s, stdout);
+ SLfree (s);
+ }
+
+
+ NOTES
+ This function should not be confused with `SLang_pop_slstring',
+ which pops a _hashed_ string from the stack.
+
+ SEE ALSO
+ SLang_pop_slstring. SLfree
+--------------------------------------------------------------
+
+SLang_pop_string
+
+ SYNOPSIS
+ Pop a string from the stack
+
+ USAGE
+ int SLang_pop_string(char **strptr, int *do_free)
+
+ DESCRIPTION
+ The `SLpop_string' function pops a string from the stack and
+ returns it as a malloced pointer via `strptr'. After the
+ function returns, the integer pointed to by the second parameter
+ will be set to a non-zero value if `*strptr' should be freed via
+ `free' or `SLfree'. If successful, `SLpop_string'
+ returns zero. However, if the top stack item is not of type
+ `SLANG_STRING_TYPE', or the stack is empty, the function will
+ return `-1' and set `SLang_Error' accordingly.
+
+ NOTES
+ This function is considered obsolete and should not be used by
+ applications. If one requires a malloced string for modification,
+ `SLpop_string' should be used. If one requires a constant
+ string that will not be modifed by the application,
+ `SLang_pop_slstring' should be used.
+
+ SEE ALSO
+ SLang_pop_slstring, SLpop_string
+--------------------------------------------------------------
+
+SLang_pop_slstring
+
+ SYNOPSIS
+ Pop a hashed string from the stack
+
+ USAGE
+ int SLang_pop_slstring (char **s_ptr)
+
+ DESCRIPTION
+ The `SLang_pop_slstring' function pops a hashed string from the
+ S-Lang run-time stack and returns it via `s_ptr'. It returns
+ zero if successful, or -1 upon failure. The resulting string
+ should be freed via a call to `SLang_free_slstring' after use.
+
+ EXAMPLE
+
+ void print_string (void)
+ {
+ char *s;
+ if (-1 == SLang_pop_slstring (&s))
+ return;
+ fprintf (stdout, "%s\n", s);
+ SLang_free_slstring (s);
+ }
+
+
+ NOTES
+ `SLang_free_slstring' is the preferred function for popping
+ strings. This is a result of the fact that the interpreter uses
+ hashed strings as the native representation for string data.
+
+ One must _never_ free a hashed string using `free' or
+ `SLfree'. In addition, one must never make any attempt to
+ modify a hashed string and doing so will result in memory
+ corruption.
+
+ SEE ALSO
+ SLang_free_slstring, SLpop_string
+--------------------------------------------------------------
+
+SLang_pop_double
+
+ SYNOPSIS
+ Pop a double from the stack
+
+ USAGE
+ int SLang_pop_double (double *dptr, int *iptr, int *conv)
+
+ DESCRIPTION
+ The `SLang_pop_double' function pops a double precision number
+ from the stack and returns it via `dptr'. If the number was
+ derived from an integer, `*conv' will be set to `1' upon
+ return, otherwise, `*conv' will be set to `0'. This
+ function returns 0 upon success, otherwise it returns -1 and sets
+ `SLang_Error' accordingly.
+
+ NOTES
+ If one does not care whether or not `*dptr' was derived from
+ an integer, `iptr' and `conv' may be passed as `NULL'
+ pointers.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_push_double
+--------------------------------------------------------------
+
+SLang_pop_complex
+
+ SYNOPSIS
+ Pop a complex number from the stack
+
+ USAGE
+ int SLang_pop_complex (double *re, double *im)
+
+ DESCRIPTION
+ `SLang_pop_complex' pops a complex number from the stack and
+ returns it via the parameters `re' and `im' as the real and
+ imaginary parts of the complex number, respectively. This function
+ automatically converts objects of type `SLANG_DOUBLE_TYPE' and
+ `SLANG_INT_TYPE' to `SLANG_COMPLEX_TYPE', if necessary.
+ It returns zero upon success, or -1 upon error setting
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_pop_double, SLang_push_complex
+--------------------------------------------------------------
+
+SLang_push_complex
+
+ SYNOPSIS
+ Push a complex number onto the stack
+
+ USAGE
+ int SLang_push_complex (double re, double im)
+
+ DESCRIPTION
+ `SLang_push_complex' may be used to push the complex number
+ whose real and imaginary parts are given by `re' and `im',
+ respectively. It returns zero upon success, or -1 upon error
+ setting `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_complex, SLang_push_double
+--------------------------------------------------------------
+
+SLang_push_double
+
+ SYNOPSIS
+ Push a double onto the stack
+
+ USAGE
+ int SLang_push_double(double d)
+
+ DESCRIPTION
+ `SLang_push_double' may be used to push the double precision
+ floating point number `d' onto the interpreter's run-time
+ stack. It returns zero upon success, or -1 upon error setting
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_double, SLang_push_integer
+--------------------------------------------------------------
+
+SLang_push_string
+
+ SYNOPSIS
+ Push a string onto the stack
+
+ USAGE
+ int SLang_push_string (char *s)
+
+ DESCRIPTION
+ `SLang_push_string' pushes a copy of the string specified by
+ `s' onto the interpreter's run-time stack. It returns zero
+ upon success, or -1 upon error setting `SLang_Error'
+ accordingly.
+
+ NOTES
+ If `s' is `NULL', this function pushes `NULL'
+ (`SLANG_NULL_TYPE') onto the stack.
+
+ SEE ALSO
+ SLang_push_malloced_string
+--------------------------------------------------------------
+
+SLang_push_integer
+
+ SYNOPSIS
+ Push an integer onto the stack
+
+ USAGE
+ int SLang_push_integer (int i)
+
+ DESCRIPTION
+ `SLang_push_integer' the integer `i' onto the interpreter's
+ run-time stack. It returns zero upon success, or -1 upon error
+ setting `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_push_double, SLang_push_string
+--------------------------------------------------------------
+
+SLang_push_malloced_string
+
+ SYNOPSIS
+ Push a malloced string onto the stack
+
+ USAGE
+ int SLang_push_malloced_string (char *s);
+
+ DESCRIPTION
+ `SLang_push_malloced_string' may be used to push a malloced
+ string onto the interpreter's run-time stack. It returns zero upon
+ success, or -1 upon error setting `SLang_Error' accordingly.
+
+ EXAMPLE
+ The following example illustrates that it is up to the calling
+ routine to free the string if `SLang_push_malloced_string' fails:
+
+ int push_hello (void)
+ {
+ char *s = malloc (6);
+ if (s == NULL) return -1;
+ strcpy (s, "hello");
+ if (-1 == SLang_push_malloced_string (s))
+ {
+ free (s);
+ return -1;
+ }
+ return 0;
+ }
+
+
+ EXAMPLE
+ The function `SLang_create_slstring' returns a hashed string.
+ Such a string may not be malloced and should not be passed to
+ `SLang_push_malloced_string'.
+
+ NOTES
+ If `s' is `NULL', this function pushes `NULL'
+ (`SLANG_NULL_TYPE') onto the stack.
+
+ SEE ALSO
+ SLang_push_string, SLmake_string
+--------------------------------------------------------------
+
+SLang_is_defined
+
+ SYNOPSIS
+ Check to see if the interpreter defines an object
+
+ USAGE
+ int SLang_is_defined (char *nm)
+
+ DESCRIPTION
+ The `SLang_is_defined' function may be used to determine
+ whether or not a variable or function whose name is given by
+ `em' has been defined. It returns zero if no such object has
+ been defined. Othewise it returns a non-zero value whose meaning
+ is given by the following table:
+
+ 1 intrinsic function (SLANG_INTRINSIC)
+ 2 user-defined slang function (SLANG_FUNCTION)
+ -1 intrinsic variable (SLANG_IVARIABLE)
+ -2 user-defined global variable (SLANG_GVARIABLE)
+
+
+ SEE ALSO
+ SLadd_intrinsic_function, SLang_run_hooks, SLang_execute_function
+--------------------------------------------------------------
+
+SLang_run_hooks
+
+ SYNOPSIS
+ Run a user-defined hook with arguments
+
+ USAGE
+ int SLang_run_hooks (char *fname, unsigned int n, ...)
+
+ DESCRIPTION
+ The `SLang_run_hooks' function may be used to execute a
+ user-defined function named `fname'. Before execution of the
+ function, the `n' string arguments specified by the variable
+ parameter list are pushed onto the stack. If the function
+ `fname' does not exist, `SLang_run_hooks' returns zero;
+ otherwise, it returns `1' upon successful execution of the
+ function, or -1 if an error occurred.
+
+ EXAMPLE
+ The jed editor uses `SLang_run_hooks' to setup the mode of a
+ buffer based on the filename extension of the file associated with
+ the buffer:
+
+ char *ext = get_filename_extension (filename);
+ if (ext == NULL) return -1;
+ if (-1 == SLang_run_hooks ("mode_hook", 1, ext))
+ return -1;
+ return 0;
+
+
+ SEE ALSO
+ SLang_is_defined, SLang_execute_function
+--------------------------------------------------------------
+
+SLang_execute_function
+
+ SYNOPSIS
+ Execute a user or intrinsic function
+
+ USAGE
+ int SLang_execute_function (char *fname)
+
+ DESCRIPTION
+ This function may be used to execute either a user-defined function
+ or an intrinisic function. The name of the function is specified
+ by `fname'. It returns zero if `fname' is not defined, or
+ `1' if the function was successfully executed, or -1 upon
+ error.
+
+ NOTES
+ The function `SLexecute_function' may be a better alternative
+ for some uses.
+
+ SEE ALSO
+ SLang_run_hooks, SLexecute_function, SLang_is_defined
+--------------------------------------------------------------
+
+SLang_verror
+
+ SYNOPSIS
+ Signal an error with a message
+
+ USAGE
+ void SLang_verror (int code, char *fmt, ...);
+
+ DESCRIPTION
+ The `SLang_verror' function sets `SLang_Error' to
+ `code' if `SLang_Error' is 0. It also displays the error
+ message implied by the `printf' variable argument list using
+ `fmt' as the format.
+
+ EXAMPLE
+
+ FILE *open_file (char *file)
+ {
+ char *file = "my_file.dat";
+ if (NULL == (fp = fopen (file, "w")))
+ SLang_verror (SL_INTRINSIC_ERROR, "Unable to open %s", file);
+ return fp;
+ }
+
+
+ SEE ALSO
+ SLang_vmessage, SLang_exit_error
+--------------------------------------------------------------
+
+SLang_doerror
+
+ SYNOPSIS
+ Signal an error
+
+ USAGE
+ void SLang_doerror (char *err_str)
+
+ DESCRIPTION
+ The `SLang_doerror' function displays the string `err_str'
+ to the error device and signals a S-Lang error.
+
+ NOTES
+ `SLang_doerror' is considered to obsolete. Applications should
+ use the `SLang_verror' function instead.
+
+ SEE ALSO
+ SLang_verror, SLang_exit_error
+--------------------------------------------------------------
+
+SLang_get_function
+
+ SYNOPSIS
+ Get a pointer to a slang function
+
+ USAGE
+ SLang_Name_Type *SLang_get_function (char *fname)
+
+ DESCRIPTION
+ This function returns a pointer to the internal S-Lang table entry
+ of a function whose name is given by `fname'. It returns
+ `NULL' upon failure. The value returned by this function can be
+ used `SLexecute_function' to call the function directly
+ from C.
+
+ SEE ALSO
+ SLexecute_function
+--------------------------------------------------------------
+
+SLexecute_function
+
+ SYNOPSIS
+ Execute a slang or intrinsic function
+
+ USAGE
+ int SLexecute_function (SLang_Name_Type *nt)
+
+ DESCRIPTION
+ The `SLexecute_function' allows an application to call the
+ S-Lang function specified by the `SLang_Name_Type' pointer
+ `nt'. This parameter must be non `NULL' and must have been
+ previously obtained by a call to `SLang_get_function'.
+
+ EXAMPLE
+ Consider the S-Lang function:
+
+ define my_fun (x)
+ {
+ return x^2 - 2;
+ }
+
+ Suppose that it is desired to call this function many times with
+ different values of x. There are at least two ways to do this.
+ The easiest way is to use `SLang_execute_function' by passing
+ the string `"my_fun"'. A better way that is much faster is to
+ use `SLexecute_function':
+
+ int sum_a_function (char *fname, double *result)
+ {
+ double sum, x, y;
+ SLang_Name_Type *nt;
+
+ if (NULL == (nt = SLang_get_function (fname)))
+ return -1;
+
+ sum = 0;
+ for (x = 0; x < 10.0; x += 0.1)
+ {
+ SLang_start_arg_list ();
+ if (-1 == SLang_push_double (x))
+ return -1;
+ SLang_end_arg_list ();
+ if (-1 == SLexecute_function (nt))
+ return -1;
+ if (-1 == SLang_pop_double (&y, NULL, NULL))
+ return -1;
+
+ sum += y;
+ }
+ return sum;
+ }
+
+ Although not necessary in this case, `SLang_start_arg_list' and
+ `SLang_end_arg_list' were used to provide the function with
+ information about the number of parameters passed to it.
+
+ SEE ALSO
+ SLang_get_function, SLang_start_arg_list, SLang_end_arg_list
+--------------------------------------------------------------
+
+SLang_peek_at_stack
+
+ SYNOPSIS
+ Find the type of object on the top of the stack
+
+ USAGE
+ int SLang_peek_at_stack (void)
+
+ DESCRIPTION
+ The `SLang_peek_at_stack' function is useful for determining the
+ data type of the object at the top of the stack. It returns the
+ data type, or -1 upon a stack-underflow error. It does not remove
+ anything from the stack.
+
+ SEE ALSO
+ SLang_pop_string, SLang_pop_integer
+--------------------------------------------------------------
+
+SLmake_string
+
+ SYNOPSIS
+ Duplicate a string
+
+ USAGE
+ char *SLmake_string (char *s)
+
+ DESCRIPTION
+ The `SLmake_string' function creates a new copy of the string
+ `s', via `malloc', and returns it. Upon failure it returns
+ `NULL'. Since the resulting string is malloced, it should be
+ freed when nolonger needed via a call to either `free' or
+ `SLfree'.
+
+ NOTES
+ `SLmake_string' should not be confused with the function
+ `SLang_create_slstring', which performs a similar function.
+
+ SEE ALSO
+ SLmake_nstring, SLfree, SLmalloc, SLang_create_slstring
+--------------------------------------------------------------
+
+SLmake_nstring
+
+ SYNOPSIS
+ Duplicate a substring
+
+ USAGE
+ char *SLmake_nstring (char *s, unsigned int n)
+
+ DESCRIPTION
+ This function is like `SLmake_nstring' except that it creates a
+ null terminated string formed from the first `n' characters of
+ `s'. Upon failure, it returns `NULL', otherwise it returns
+ the new string. When nolonger needed, the returned string should be
+ freed with either `free' or `SLfree'.
+
+ SEE ALSO
+ SLmake_nstring, SLfree, SLang_create_nslstring
+--------------------------------------------------------------
+
+SLang_create_nslstring
+
+ SYNOPSIS
+ Created a hashed substring
+
+ USAGE
+ char *SLang_create_nslstring (char *s, unsigned int n)
+
+ DESCRIPTION
+ `SLang_create_nslstring' is like `SLang_create_slstring'
+ except that only the first `n' characters of `s' are used to
+ perform the string. Upon error, it returns `NULL', otherwise it
+ returns the hashed substring. Such a string must be freed by the
+ function `SLang_free_slstring'.
+
+ NOTES
+ Do not use `free' or `SLfree' to free the string returned by
+ `SLang_create_slstring' or `SLang_create_nslstring'. Also
+ it is important that no attempt is made to modify the hashed string
+ returned by either of these functions. If one needs to modify a
+ string, the functions `SLmake_string' or `SLmake_nstring'
+ should be used instead.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_slstring, SLmake_nstring
+--------------------------------------------------------------
+
+SLang_create_slstring
+
+ SYNOPSIS
+ Create a hashed string
+
+ USAGE
+ char *SLang_create_slstring (char *s)
+
+ DESCRIPTION
+ The `SLang_create_slstring' creates a copy of `s' and
+ returns it as a hashed string. Upon error, the function returns
+ `NULL', otherwise it returns the hashed string. Such a string
+ must only be freed via the `SLang_free_slstring' function.
+
+ NOTES
+ Do not use `free' or `SLfree' to free the string returned by
+ `SLang_create_slstring' or `SLang_create_nslstring'. Also
+ it is important that no attempt is made to modify the hashed string
+ returned by either of these functions. If one needs to modify a
+ string, the functions `SLmake_string' or `SLmake_nstring'
+ should be used instead.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_nslstring, SLmake_string
+--------------------------------------------------------------
+
+SLang_free_slstring
+
+ SYNOPSIS
+ Free a hashed string
+
+ USAGE
+ void SLang_free_slstring (char *s)
+
+ DESCRIPTION
+ The `SLang_free_slstring' function is used to free a hashed
+ string such as one returned by `SLang_create_slstring',
+ `SLang_create_nslstring', or `SLang_create_static_slstring'.
+ If `s' is `NULL', the routine does nothing.
+
+ SEE ALSO
+ SLang_create_slstring, SLang_create_nslstring, SLang_create_static_slstring
+--------------------------------------------------------------
+
+SLang_concat_slstrings
+
+ SYNOPSIS
+ Concatenate two strings to produce a hashed string
+
+ USAGE
+ char *SLang_concat_slstrings (char *a, char *b)
+
+ DESCRIPTION
+ The `SLang_concat_slstrings' function concatenates two strings,
+ `a' and `b', and returns the result as a hashed string.
+ Upon failure, `NULL' is returned.
+
+ NOTES
+ A hashed string can only be freed using `SLang_free_slstring'.
+ Never use either `free' or `SLfree' to free a hashed string,
+ otherwise memory corruption will result.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_slstring
+--------------------------------------------------------------
+
+SLang_create_static_slstring
+
+ SYNOPSIS
+ Create a hashed string
+
+ USAGE
+ char *SLang_create_static_slstring (char *s_literal)
+
+ DESCRIPTION
+ The `SLang_create_static_slstring' creates a hashed string from
+ the string literal `s_literal' and returns the result. Upon
+ failure it returns `NULL'.
+
+ EXAMPLE
+
+ char *create_hello (void)
+ {
+ return SLang_create_static_slstring ("hello");
+ }
+
+
+ NOTES
+ This function should only be used with string literals.
+
+ SEE ALSO
+ SLang_create_slstring, SLang_create_nslstring
+--------------------------------------------------------------
+
+SLmalloc
+
+ SYNOPSIS
+ Allocate some memory
+
+ USAGE
+ char *SLmalloc (unsigned int nbytes)
+
+ DESCRIPTION
+ This function uses `malloc' to allocate `nbytes' of memory.
+ Upon error it returns `NULL'; otherwise it returns a pointer to
+ the allocated memory. One should use `SLfree' to free the
+ memory after used.
+
+ SEE ALSO
+ SLfree, SLrealloc, SLcalloc
+--------------------------------------------------------------
+
+SLcalloc
+
+ SYNOPSIS
+ Allocate some memory
+
+ USAGE
+ char *SLcalloc (unsigned int num_elem, unsigned int elem_size)
+
+ DESCRIPTION
+ This function uses `calloc' to allocate memory for
+ `num_elem' objects with each of size `elem_size' and returns
+ the result. In addition, the newly allocated memory is zeroed.
+ Upon error it returns `NULL'; otherwise it returns a pointer to
+ the allocated memory. One should use `SLfree' to free the
+ memory after used.
+
+ SEE ALSO
+ SLmalloc, SLrealloc, SLfree
+--------------------------------------------------------------
+
+SLfree
+
+ SYNOPSIS
+ Free some allocated memory
+
+ USAGE
+ void SLfree (char *ptr)
+
+ DESCRIPTION
+ The `SLfree' function uses `free' to deallocate the memory
+ specified by `ptr', which may be `NULL' in which case the
+ function does nothing.
+
+ NOTES
+ Never use this function to free a hashed string returned by one of
+ the family of `slstring' functions, e.g.,
+ `SLang_pop_slstring'.
+
+ SEE ALSO
+ SLmalloc, SLcalloc, SLrealloc, SLmake_string
+--------------------------------------------------------------
+
+SLrealloc
+
+ SYNOPSIS
+ Resize a dynamic memory block
+
+ USAGE
+ char *SLrealloc (char *ptr, unsigned int new_size)
+
+ DESCRIPTION
+ The `SLrealloc' uses the `realloc' function to resize the
+ memory block specified by `ptr' to the new size `new_size'.
+ If `ptr' is `NULL', the function call is equivalent to
+ `SLmalloc(new_size)'. Similarly, if `new_size' is zero,
+ the function call is equivalent to `SLfree(ptr)'.
+
+ If the function fails, or if `new_size' is zero, `NULL' is
+ returned. Otherwise a pointer is returned to the (possibly moved)
+ new block of memory.
+
+ SEE ALSO
+ SLfree, SLmalloc, SLcalloc
+--------------------------------------------------------------
+
+SLcurrent_time_string
+
+ SYNOPSIS
+ Get the current time as a string
+
+ USAGE
+ char *SLcurrent_time_string (void)
+
+ DESCRIPTION
+ The `SLcurrent_time_string' function uses the C library function
+ `ctime' to obtain a string representation of the
+ current date and time in the form
+
+ "Wed Dec 10 12:50:28 1997"
+
+ However, unlike the `ctime' function, a newline character is not
+ present in the string.
+
+ The returned value points to a statically allocated memory block
+ which may get overwritten on subsequent function calls.
+
+ SEE ALSO
+ SLmake_string
+--------------------------------------------------------------
+
+SLatoi
+
+ SYNOPSIS
+ Convert a text string to an integer
+
+ USAGE
+ int SLatoi(unsigned char *str
+
+ DESCRIPTION
+ `SLatoi' parses the string `str' to interpret it as an
+ integer value. Unlike `atoi', `SLatoi' can also parse
+ strings containing integers expressed in
+ hexidecimal (e.g., `"0x7F"') and octal (e.g., `"012"'.)
+ notation.
+
+ SEE ALSO
+ SLang_guess_type
+--------------------------------------------------------------
+
+SLang_pop_fileptr
+
+ SYNOPSIS
+ Pop a file pointer
+
+ USAGE
+ int SLang_pop_fileptr (SLang_MMT_Type **mmt, FILE **fp)
+
+ DESCRIPTION
+ `SLang_pop_fileptr' pops a file pointer from the S-Lang
+ run-time stack. It returns zero upon success, or -1 upon failure.
+
+ A S-Lang file pointer (SLANG_FILEPTR_TYPE) is actually a memory
+ managed object. For this reason, `SLang_pop_fileptr' also
+ returns the memory managed object via the argument list. It is up
+ to the calling routine to call `SLang_free_mmt' to free the
+ object.
+
+ EXAMPLE
+ The following example illustrates an application defined intrinsic
+ function that writes a user defined double precision number to a
+ file. Note the use of `SLang_free_mmt':
+
+ int write_double (void)
+ {
+ double t;
+ SLang_MMT_Type *mmt;
+ FILE *fp;
+ int status;
+
+ if (-1 == SLang_pop_double (&d, NULL, NULL))
+ return -1;
+ if (-1 == SLang_pop_fileptr (&mmt, &fp))
+ return -1;
+
+ status = fwrite (&d, sizeof (double), 1, fp);
+ SLang_free_mmt (mmt);
+ return status;
+ }
+
+ This function can be used by a S-Lang function as follows:
+
+ define write_some_values ()
+ {
+ variable fp, d;
+
+ fp = fopen ("myfile.dat", "wb");
+ if (fp == NULL)
+ error ("file failed to open");
+ for (d = 0; d < 10.0; d += 0.1)
+ {
+ if (-1 == write_double (fp, d))
+ error ("write failed");
+ }
+ if (-1 == fclose (fp))
+ error ("fclose failed");
+ }
+
+
+ SEE ALSO
+ SLang_free_mmt, SLang_pop_double
+--------------------------------------------------------------
+
+SLadd_intrinsic_function
+
+ SYNOPSIS
+ Add a new intrinsic function to the interpreter
+
+ USAGE
+ int SLadd_intrinsic_function (name, f, type, nargs, ...)
+
+ char *name
+ FVOID_STAR f
+ unsigned char type
+ unsigned int nargs
+
+
+ DESCRIPTION
+ The `SLadd_intrinsic_function' function may be used to add a new
+ intrinsic function. The S-Lang name of the function is specified by
+ `name' and the actual function pointer is given by `f', cast
+ to `FVOID_STAR'. The third parameter, `type' specifies the
+ return type of the function and must be one of the following values:
+
+ SLANG_VOID_TYPE (returns nothing)
+ SLANG_INT_TYPE (returns int)
+ SLANG_DOUBLE_TYPE (returns double)
+ SLANG_STRING_TYPE (returns char *)
+
+ The `nargs' parameter specifies the number of parameters to pass
+ to the function. The variable argument list following `nargs'
+ must consists of `nargs' integers which specify the data type of
+ each argument.
+
+ The function returns zero upon success or -1 upon failure.
+
+ EXAMPLE
+ The jed editor uses this function to change the `system'
+ intrinsic function to the following:
+
+ static int jed_system (char *cmd)
+ {
+ if (Jed_Secure_Mode)
+ {
+ msg_error ("Access denied.");
+ return -1;
+ }
+ return SLsystem (cmd);
+ }
+
+ After initializing the interpreter with `SLang_init_slang',
+ jed calls `SLadd_intrinsic_function' to substitute the above
+ definition for the default S-Lang definition:
+
+ if (-1 == SLadd_intrinsic_function ("system", (FVOID_STAR)jed_system,
+ SLANG_INT_TYPE, 1,
+ SLANG_STRING_TYPE))
+ return -1;
+
+
+ SEE ALSO
+ SLadd_intrinsic_variable, SLadd_intrinsic_array
+--------------------------------------------------------------
+
+SLadd_intrinsic_variable
+
+ SYNOPSIS
+ Add an intrinsic variable to the interpreter
+
+ USAGE
+ int SLadd_intrinsic_variable (name, addr, type, rdonly)
+
+ char *name
+ VOID_STAR type
+ unsigned char type
+ int rdonly
+
+
+ DESCRIPTION
+ The `SLadd_intrinsic_variable' function adds an intrinsic
+ variable called `name' to the interpeter. The second parameter
+ `addr' specifies the address of the variable (cast to
+ `VOID_STAR'). The third parameter, `type', specifies the
+ data type of the variable. If the fourth parameter, `rdonly',
+ is non-zero, the variable will interpreted by the interpreter as
+ read-only.
+
+ If successful, `SLadd_intrinsic_variable' returns zero,
+ otherwise it returns -1.
+
+ EXAMPLE
+ Suppose that `My_Global_Int' is a global variable (at least not
+ a local one):
+
+ int My_Global_Int;
+
+ It can be added to the interpreter via the function call
+
+ if (-1 == SLadd_intrinsic_variable ("MyGlobalInt",
+ (VOID_STAR)&My_Global_Int,
+ SLANG_INT_TYPE, 0))
+ exit (1);
+
+
+ NOTES
+ The current implementation requires all pointer type intrinsic
+ variables to be read-only. For example,
+
+ char *My_Global_String;
+
+ is of type `SLANG_STRING_TYPE', and must be declared as
+ read-only. Finally, not that
+
+ char My_Global_Char_Buf[256];
+
+ is _not_ a `SLANG_STRING_TYPE' object. This difference is
+ very important because internally the interpreter dereferences the
+ address passed to it to get to the value of the variable.
+
+ SEE ALSO
+ SLadd_intrinsic_function, SLadd_intrinsic_array
+--------------------------------------------------------------
+
+SLclass_add_unary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_unary_op (unsigned char,int (*) (int, unsigned char, VOID_STAR, unsigned int, VOID_STAR), int (*) (int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_app_unary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_app_unary_op (unsigned char, int (*) (int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*) (int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_binary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_binary_op (unsigned char, unsigned char,int (*)(int, unsigned char, VOID_STAR, unsigned int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*) (int, unsigned char, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_math_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_math_op (unsigned char,int (*)(int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*)(int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_typecast
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_typecast (unsigned char, unsigned char int (*)_PROTO((unsigned char, VOID_STAR, unsigned int,unsigned char, VOID_STAR)),int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLang_init_tty
+
+ SYNOPSIS
+ Initialize the terminal keyboard interface
+
+ USAGE
+ int SLang_init_tty (int intr_ch, int no_flow_ctrl, int opost)
+
+ DESCRIPTION
+ `SLang_init_tty' initializes the terminal for single character
+ input. If the first parameter `intr_ch' is in the range 0-255,
+ it will be used as the interrupt character, e.g., under Unix this
+ character will generate a `SIGINT' signal. Otherwise, if it is
+ `-1', the interrupt character will be left unchanged.
+
+ If the second parameter `no_flow_ctrl' is non-zero, flow control
+ (`XON'/`XOFF') processing will be
+ enabled.
+
+ If the last parmeter `opost' is non-zero, output processing by the
+ terminal will be enabled. If one intends to use this function in
+ conjunction with the S-Lang screen management routines
+ (`SLsmg'), this paramete shold be set to zero.
+
+ `SLang_init_tty' returns zero upon success, or -1 upon error.
+
+ NOTES
+ Terminal I/O is a complex subject. The S-Lang interface presents a
+ simplification that the author has found useful in practice. For
+ example, the only special character processing that
+ `SLang_init_tty' enables is that of the `SIGINT' character,
+ and the generation of other signals via the keyboard is disabled.
+ However, generation of the job control signal `SIGTSTP' is possible
+ via the `SLtty_set_suspend_state' function.
+
+ Under Unix, the integer variable `SLang_TT_Read_FD' is used to
+ specify the input descriptor for the terminal. If
+ `SLang_TT_Read_FD' represents a terminal device as determined
+ via the `isatty' system call, then it will be used as the
+ terminal file descriptor. Otherwise, the terminal device
+ `/dev/tty' will used as the input device. The default value of
+ `SLang_TT_Read_FD' is -1 which causes `/dev/tty' to be
+ used. So, if you prefer to use `stdin' for input, then set
+ `SLang_TT_Read_FD' to `fileno(stdin)' _before_ calling
+ `SLang_init_tty'.
+
+ If the variable `SLang_TT_Baud_Rate' is zero when this function
+ is called, the function will attempt to determine the baud rate by
+ querying the terminal driver and set `SLang_TT_Baud_Rate' to
+ that value.
+
+ SEE ALSO
+ SLang_reset_tty, SLang_getkey, SLtty_set_suspend_state
+--------------------------------------------------------------
+
+SLang_reset_tty
+
+ SYNOPSIS
+ Reset the terminal
+
+ USAGE
+ void SLang_reset_tty (void)
+
+ DESCRIPTION
+ `SLang_reset_tty' resets the terminal interface back to the
+ state it was in before `SLang_init_tty' was called.
+
+ SEE ALSO
+ SLang_init_tty
+--------------------------------------------------------------
+
+SLtty_set_suspend_state
+
+ SYNOPSIS
+ Enable or disable keyboard suspension
+
+ USAGE
+ void SLtty_set_suspend_state (int s)
+
+ DESCRIPTION
+ The `SLtty_set_suspend_state' function may be used to enable or
+ disable keyboard generation of the `SIGTSTP' job control signal.
+ If `s' is non-zero, generation of this signal via the terminal
+ interface will be enabled, otherwise it will be disabled.
+
+ This function should only be called after the terminal driver has be
+ initialized via `SLang_init_tty'. The `SLang_init_tty'
+ always disables the generation of `SIGTSTP' via the keyboard.
+
+ SEE ALSO
+ SLang_init_tty
+--------------------------------------------------------------
+
+SLang_getkey
+
+ SYNOPSIS
+ Read a character from the keyboard
+
+ USAGE
+ unsigned int SLang_getkey (void);
+
+ DESCRIPTION
+ The `SLang_getkey' reads a single character from the terminal
+ and returns it. The terminal must first be initialized via a call
+ to `SLang_init_tty' before this function can be called. Upon
+ success, `SLang_getkey' returns the character read from the
+ terminal, otherwise it returns `SLANG_GETKEY_ERROR'.
+
+ SEE ALSO
+ SLang_init_tty, SLang_input_pending, SLang_ungetkey
+--------------------------------------------------------------
+
+SLang_ungetkey_string
+
+ SYNOPSIS
+ Unget a key string
+
+ USAGE
+ int SLang_ungetkey_string (unsigned char *buf, unsigned int n)
+
+ DESCRIPTION
+ The `SLang_ungetkey_string' function may be used to push the
+ `n' characters pointed to by `buf' onto the buffered input
+ stream that `SLgetkey' uses. If there is not enough room for
+ the characters, -1 is returned and none are buffered. Otherwise,
+ it returns zero.
+
+ NOTES
+ The difference between `SLang_buffer_keystring' and
+ `SLang_ungetkey_string' is that the `SLang_buffer_keystring'
+ appends the characters to the end of the getkey buffer, whereas
+ `SLang_ungetkey_string' inserts the characters at the beginning
+ of the input buffer.
+
+ SEE ALSO
+ SLang_ungetkey, SLang_getkey
+--------------------------------------------------------------
+
+SLang_buffer_keystring
+
+ SYNOPSIS
+ Append a keystring to the input buffer
+
+ USAGE
+ int SLang_buffer_keystring (unsigned char *b, unsigned int len)
+
+ DESCRIPTION
+ `SLang_buffer_keystring' places the `len' characters
+ specified by `b' at the _end_ of the buffer that
+ `SLang_getkey' uses. Upon success it returns 0; otherwise, no
+ characters are buffered and it returns -1.
+
+ NOTES
+ The difference between `SLang_buffer_keystring' and
+ `SLang_ungetkey_string' is that the `SLang_buffer_keystring'
+ appends the characters to the end of the getkey buffer, whereas
+ `SLang_ungetkey_string' inserts the characters at the beginning
+ of the input buffer.
+
+ SEE ALSO
+ SLang_getkey, SLang_ungetkey, SLang_ungetkey_string
+--------------------------------------------------------------
+
+SLang_ungetkey
+
+ SYNOPSIS
+ Push a character back onto the input buffer
+
+ USAGE
+ int SLang_ungetkey (unsigned char ch)
+
+ DESCRIPTION
+ `SLang_ungetkey' pushes the character `ch' back onto the
+ `SLgetkey' input stream. Upon success, it returns zero,
+ otherwise it returns 1.
+
+ EXAMPLE
+ This function is implemented as:
+
+ int SLang_ungetkey (unsigned char ch)
+ {
+ return SLang_ungetkey_string(&ch, 1);
+ }
+
+
+ SEE ALSO
+ SLang_getkey, SLang_ungetkey_string
+--------------------------------------------------------------
+
+SLang_flush_input
+
+ SYNOPSIS
+ Discard all keyboard input waiting to be read
+
+ USAGE
+ void SLang_flush_input (void)
+
+ DESCRIPTION
+ `SLang_flush_input' discards all input characters waiting to be
+ read by the `SLang_getkey' function.
+
+ SEE ALSO
+ SLang_getkey
+--------------------------------------------------------------
+
+SLang_input_pending
+
+ SYNOPSIS
+ Check to see if input is pending
+
+ USAGE
+ int SLang_input_pending (int tsecs)
+
+ DESCRIPTION
+ `SLang_input_pending' may be used to see if an input character
+ is available to be read without causing `SLang_getkey' to block.
+ It will wait up to `tsecs' tenths of a second if no characters
+ are immediately available for reading. If `tsecs' is less than
+ zero, then `SLang_input_pending' will wait `-tsecs'
+ milliseconds for input, otherwise `tsecs' represents `1/10'
+ of a second intervals.
+
+ NOTES
+ Not all systems support millisecond resolution.
+
+ SEE ALSO
+ SLang_getkey
+--------------------------------------------------------------
+
+SLang_set_abort_signal
+
+ SYNOPSIS
+ Set the signal to trap SIGINT
+
+ USAGE
+ void SLang_set_abort_signal (void (*f)(int));
+
+ DESCRIPTION
+ `SLang_set_abort_signal' sets the function that gets
+ triggered when the user presses the interrupt key (`SIGINT') to
+ the function `f'. If `f' is `NULL' the default handler
+ will get installed.
+
+ EXAMPLE
+ The default interrupt handler on a Unix system is:
+
+ static void default_sigint (int sig)
+ {
+ SLKeyBoard_Quit = 1;
+ if (SLang_Ignore_User_Abort == 0) SLang_Error = SL_USER_BREAK;
+ SLsignal_intr (SIGINT, default_sigint);
+ }
+
+
+ NOTES
+ For Unix programmers, the name of this function may appear
+ misleading since it is associated with `SIGINT' and not
+ `SIGABRT'. The origin of the name stems from the original intent
+ of the function: to allow the user to abort the running of a S-Lang
+ interpreter function.
+
+ SEE ALSO
+ SLang_init_tty, SLsignal_intr
+--------------------------------------------------------------
+
+SLkm_define_key
+
+ SYNOPSIS
+ Define a key in a keymap
+
+ USAGE
+ int SLkm_define_key (char *seq, FVOID_STAR f, SLKeyMap_List_Type *km)
+
+ DESCRIPTION
+ `SLkm_define_key' associates the key sequence `seq' with the
+ function pointer `f' in the keymap specified by `km'. Upon
+ success, it returns zero, otherwise it returns a negative integer
+ upon error.
+
+ SEE ALSO
+ SLkm_define_keysym, SLang_define_key
+--------------------------------------------------------------
+
+SLang_define_key
+
+ SYNOPSIS
+ Define a key in a keymap
+
+ USAGE
+ int SLang_define_key(char *seq, char *fun, SLKeyMap_List_Type *km)
+
+ DESCRIPTION
+ `SLang_define_key' associates the key sequence `seq' with
+ the function whose name is `fun' in the keymap specified by
+ `km'.
+
+ SEE ALSO
+ SLkm_define_keysym, SLkm_define_key
+--------------------------------------------------------------
+
+SLkm_define_keysym
+
+ SYNOPSIS
+ Define a keysym in a keymap
+
+ USAGE
+ int SLkm_define_keysym (seq, ks, km)
+
+ char *seq;
+ unsigned int ks;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ `SLkm_define_keysym' associates the key sequence `seq' with
+ the keysym `ks' in the keymap `km'. Keysyms whose value is
+ less than or equal to `0x1000' is reserved by the library and
+ should not be used.
+
+ SEE ALSO
+ SLkm_define_key, SLang_define_key
+--------------------------------------------------------------
+
+SLang_undefine_key
+
+ SYNOPSIS
+ Undefined a key from a keymap
+
+ USAGE
+ void SLang_undefine_key(char *seq, SLKeyMap_List_Type *km);
+
+ DESCRIPTION
+ `SLang_undefine_key' removes the key sequence `seq' from the
+ keymap `km'.
+
+ SEE ALSO
+ SLang_define_key
+--------------------------------------------------------------
+
+SLang_create_keymap
+
+ SYNOPSIS
+ Create a new keymap
+
+ USAGE
+ SLKeyMap_List_Type *SLang_create_keymap (name, km)
+
+ char *name;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ `SLang_create_keymap' creates a new keymap called `name' by
+ copying the key definitions from the keymap `km'. If `km'
+ is `NULL', the newly created keymap will be empty and it is up
+ to the calling routine to initialize it via the
+ `SLang_define_key' and `SLkm_define_keysym' functions.
+ `SLang_create_keymap' returns a pointer to the new keymap, or
+ `NULL' upon failure.
+
+ SEE ALSO
+ SLang_define_key, SLkm_define_keysym
+--------------------------------------------------------------
+
+SLang_do_key
+
+ SYNOPSIS
+ Read a keysequence and return its keymap entry
+
+ USAGE
+ SLang_Key_Type *SLang_do_key (kml, getkey)
+
+ SLKeyMap_List_Type *kml;
+ int (*getkey)(void);
+
+
+ DESCRIPTION
+ The `SLang_do_key' function reads characters using the function
+ specified by the `getkey' function pointer and uses the
+ key sequence to return the appropriate entry in the keymap specified
+ by `kml'.
+
+ `SLang_do_key' returns `NULL' if the key sequence is not
+ defined by the keymap, otherwise it returns a pointer to an object
+ of type `SLang_Key_Type', which is defined in `slang.h' as
+
+ #define SLANG_MAX_KEYMAP_KEY_SEQ 14
+ typedef struct SLang_Key_Type
+ {
+ struct SLang_Key_Type *next;
+ union
+ {
+ char *s;
+ FVOID_STAR f;
+ unsigned int keysym;
+ }
+ f;
+ unsigned char type; /* type of function */
+ #define SLKEY_F_INTERPRET 0x01
+ #define SLKEY_F_INTRINSIC 0x02
+ #define SLKEY_F_KEYSYM 0x03
+ unsigned char str[SLANG_MAX_KEYMAP_KEY_SEQ + 1];/* key sequence */
+ }
+ SLang_Key_Type;
+
+
+ The `type' field specifies which field of the union `f'
+ should be used. If `type' is `SLKEY_F_INTERPRET', then
+ `f.s' is a string that should be passed to the interpreter for
+ evaluation. If `type' is `SLKEY_F_INTRINSIC', then
+ `f.f' refers to function that should be called. Otherwise,
+ `type' is `SLKEY_F_KEYSYM' and `f.keysym' represents the
+ value of the keysym that is associated with the key sequence.
+
+ SEE ALSO
+ SLkm_define_keysym, SLkm_define_key
+--------------------------------------------------------------
+
+SLang_find_key_function
+
+ SYNOPSIS
+ Obtain a function pointer associated with a keymap
+
+ USAGE
+ FVOID_STAR SLang_find_key_function (fname, km);
+
+ char *fname;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ The `SLang_find_key_function' routine searches through the
+ `SLKeymap_Function_Type' list of functions associated with the
+ keymap `km' for the function with name `fname'.
+ If a matching function is found, a pointer to the function will
+ be returned, otherwise `SLang_find_key_function' will return
+ `NULL'.
+
+ SEE ALSO
+ SLang_create_keymap, SLang_find_keymap
+--------------------------------------------------------------
+
+SLang_find_keymap
+
+ SYNOPSIS
+ Find a keymap
+
+ USAGE
+ SLKeyMap_List_Type *SLang_find_keymap (char *keymap_name);
+
+ DESCRIPTION
+ The `SLang_find_keymap' function searches through the list of
+ keymaps looking for one whose name is `keymap_name'. If a
+ matching keymap is found, the function returns a pointer to the
+ keymap. It returns `NULL' if no such keymap exists.
+
+ SEE ALSO
+ SLang_create_keymap, SLang_find_key_function
+--------------------------------------------------------------
+
+SLang_process_keystring
+
+ SYNOPSIS
+ Un-escape a key-sequence
+
+ USAGE
+ char *SLang_process_keystring (char *kseq);
+
+ DESCRIPTION
+ The `SLang_process_keystring' function converts an escaped key
+ sequence to its raw form by converting two-character combinations
+ such as `^A' to the _single_ character `Ctrl-A' (ASCII
+ 1). In addition, if the key sequence contains constructs such as
+ `^(XX)', where `XX' represents a two-character termcap
+ specifier, the termcap escape sequence will be looked up and
+ substituted.
+
+ Upon success, `SLang_process_keystring' returns a raw
+ key-sequence whose first character represents the total length of
+ the key-sequence, including the length specifier itself. It returns
+ `NULL' upon failure.
+
+ EXAMPLE
+ Consider the following examples:
+
+ SLang_process_keystring ("^X^C");
+ SLang_process_keystring ("^[[A");
+
+ The first example will return a pointer to a buffer of three characters
+ whose ASCII values are given by `{3,24,3}'. Similarly, the
+ second example will return a pointer to the four characters
+ `{4,27,91,65}'. Finally, the result of
+
+ SLang_process_keystring ("^[^(ku)");
+
+ will depend upon the termcap/terminfo capability `"ku"', which
+ represents the escape sequence associated with the terminal's UP
+ arrow key. For an ANSI terminal whose UP arrow produces
+ `"ESC [ A"', the result will be `5,27,27,91,65'.
+
+ NOTES
+ `SLang_process_keystring' returns a pointer to a static area
+ that will be overwritten on subsequent calls.
+
+ SEE ALSO
+ SLang_define_key, SLang_make_keystring
+--------------------------------------------------------------
+
+SLang_make_keystring
+
+ SYNOPSIS
+ Make a printable key sequence
+
+ USAGE
+ char *SLang_make_keystring (unsigned char *ks);
+
+ DESCRIPTION
+ The `SLang_make_keystring' function takes a raw key sequence
+ `ks' and converts it to a printable form by converting
+ characters such as ASCII 1 (ctrl-A) to `^A'. That is, it
+ performs the opposite function of `SLang_process_keystring'.
+
+ NOTES
+ This function returns a pointer to a static area that will be
+ overwritten on the next call to `SLang_make_keystring'.
+
+ SEE ALSO
+ SLang_process_keystring
+--------------------------------------------------------------
+
+SLextract_list_element
+
+ SYNOPSIS
+ Extract a substring of a delimited string
+
+ USAGE
+ int SLextract_list_element (dlist, nth, delim, buf, buflen)
+
+ char *dlist;
+ unsigned int nth;
+ char delim;
+ char *buf;
+ unsigned int buflen;
+
+
+ DESCRIPTION
+ `SLextract_list_element' may be used to obtain the `nth'
+ element of a list of strings, `dlist', that are delimited by the
+ character `delim'. The routine copies the `nth' element of
+ `dlist' to the buffer `buf' whose size is `buflen'
+ characters. It returns zero upon success, or -1 if `dlist'
+ does not contain an `nth' element.
+
+ EXAMPLE
+ A delimited list of strings may be turned into an array of strings
+ as follows. For conciseness, all malloc error checking has been
+ omitted.
+
+ int list_to_array (char *list, char delim, char ***ap)
+ {
+ unsigned int nth;
+ char **a;
+ char buf[1024];
+
+ /* Determine the size of the array */
+ nth = 0;
+ while (0 == SLextract_list_element (list, nth, delim, buf, sizeof(buf)))
+ nth++;
+
+ ap = (char **) SLmalloc ((nth + 1) * sizeof (char **));
+ nth = 0;
+ while (0 == SLextract_list_element (list, nth, delim, buf, sizeof(buf)))
+ {
+ a[nth] = SLmake_string (buf);
+ nth++;
+ }
+ a[nth] = NULL;
+ *ap = a;
+ return 0;
+ }
+
+
+ SEE ALSO
+ SLmalloc, SLmake_string
+--------------------------------------------------------------
+
+SLprep_open_prep
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLprep_open_prep (SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLprep_close_prep
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLprep_close_prep (SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLprep_line_ok
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLprep_line_ok (char *, SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLdefine_for_ifdef
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLdefine_for_ifdef (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_init_readline (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_init_readline (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_read_line (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_read_line (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_rline_insert (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_rline_insert (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLrline_redraw (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLrline_redraw (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_flush_output (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_flush_output (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_scroll_region(int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_scroll_region(int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reset_scroll_region(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reset_scroll_region(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reverse_video (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reverse_video (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_bold_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_bold_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_begin_insert(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_begin_insert(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_end_insert(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_end_insert(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_del_eol(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_del_eol(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_goto_rc (int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_goto_rc (int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_delete_nlines(int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_delete_nlines(int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_delete_char(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_delete_char(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_erase_line(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_erase_line(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_normal_video(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_normal_video(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_cls(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_cls(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_beep(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_beep(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reverse_index(int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reverse_index(int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_smart_puts(unsigned short *, unsigned short *, int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_smart_puts(unsigned short *, unsigned short *, int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_write_string (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_write_string (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_putchar(char);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_putchar(char);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_init_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_init_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_reset_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_reset_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_get_terminfo(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_get_terminfo(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_get_screen_size (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_get_screen_size (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_set_cursor_visibility (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_set_cursor_visibility (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_initialize (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_initialize (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_enable_cursor_keys(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_enable_cursor_keys(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_term_vtxxx(int *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_term_vtxxx(int *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_esc (int, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_esc (int, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_wide_width(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_wide_width(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_narrow_width(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_narrow_width(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_set_mouse_mode (int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_set_mouse_mode (int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_alt_char_set (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_alt_char_set (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_write_to_status_line (char *, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_write_to_status_line (char *, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_disable_status_line (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_disable_status_line (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tgetstr (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tgetstr (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tgetnum (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tgetnum (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tgetflag (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tgetflag (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tigetent (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tigetent (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tigetstr (char *, char **);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tigetstr (char *, char **);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tigetnum (char *, char **);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tigetnum (char *, char **);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLtt_Char_Type SLtt_get_color_object (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLtt_Char_Type SLtt_get_color_object (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_object (int, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_object (int, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color (int, char *, char *, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color (int, char *, char *, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_mono (int, char *, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_mono (int, char *, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_add_color_attribute (int, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_add_color_attribute (int, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_define_keysym (char *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_define_keysym (char *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_init (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_init (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_getkey (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_getkey (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_find_top (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_find_top (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_find_line_num (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_find_line_num (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_pageup (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_pageup (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_pagedown (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_pagedown (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsig_block_signals (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsig_block_signals (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsig_unblock_signals (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsig_unblock_signals (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsystem (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsystem (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLadd_at_handler (long *, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLadd_at_handler (long *, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLang_define_case(int *, int *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLang_define_case(int *, int *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLang_init_case_tables (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLang_init_case_tables (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned char *SLang_regexp_match(unsigned char *, unsigned int, SLRegexp_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned char *SLang_regexp_match(unsigned char *, unsigned int, SLRegexp_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_regexp_compile (SLRegexp_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_regexp_compile (SLRegexp_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLregexp_quote_string (char *, char *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLregexp_quote_string (char *, char *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsearch_init (char *, int, int, SLsearch_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsearch_init (char *, int, int, SLsearch_Type *);
+
+ DESCRIPTION
+ ??
+ /* This routine must first be called before any search can take place.
+ * The second parameter specifies the direction of the search: greater than
+ * zero for a forwrd search and less than zero for a backward search. The
+ * third parameter specifies whether the search is case sensitive or not.
+ * The last parameter is a pointer to a structure that is filled by this
+ * function and it is this structure that must be passed to SLsearch.
+ */
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *);
+
+ DESCRIPTION
+ ??
+ /* To use this routine, you must first call 'SLsearch_init'. Then the first
+ * two parameters p1 and p2 serve to define the region over which the search
+ * is to take place. The third parameter is the structure that was previously
+ * initialized by SLsearch_init.
+ *
+ * The routine returns a pointer to the match if found otherwise it returns
+ * NULL.
+ */
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLcomplex_abs
+
+ SYNOPSIS
+ Returns the norm of a complex number
+
+ USAGE
+ double SLcomplex_abs (double *z)
+
+ DESCRIPTION
+ The `SLcomplex_abs' function returns the absolute value or the
+ norm of the complex number given by `z'.
+
+ SEE ALSO
+ SLcomplex_times
+--------------------------------------------------------------
+
+double *SLcomplex_times (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_times (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_divide (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_divide (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sin (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sin (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_cos (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_cos (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_tan (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_tan (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_asin (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_asin (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_acos (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_acos (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_atan (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_atan (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_exp (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_exp (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_log (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_log (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_log10 (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_log10 (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sqrt (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sqrt (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sinh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sinh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_cosh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_cosh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_tanh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_tanh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_pow (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_pow (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double SLmath_hypot (double x, double y);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double SLmath_hypot (double x, double y);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_acosh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_acosh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_atanh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_atanh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_malloc (unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_malloc (unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_calloc (unsigned long, unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_calloc (unsigned long, unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_realloc (char *, unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_realloc (char *, unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLdebug_free (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLdebug_free (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmalloc_dump_statistics (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmalloc_dump_statistics (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLstrcpy(register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLstrcpy(register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLstrcmp(register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLstrcmp(register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLstrncpy(char *, register char *, register int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLstrncpy(char *, register char *, register int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmemset (char *, char, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmemset (char *, char, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLexpand_escaped_string (register char *, register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLexpand_escaped_string (register char *, register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmake_lut (unsigned char *, unsigned char *, unsigned char);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmake_lut (unsigned char *, unsigned char *, unsigned char);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_guess_type (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_guess_type (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
diff --git a/libslang/doc/text/cslang.txt b/libslang/doc/text/cslang.txt
new file mode 100644
index 0000000..18eab6a
--- /dev/null
+++ b/libslang/doc/text/cslang.txt
@@ -0,0 +1,2989 @@
+ S-Lang Library C Programmer's Guide, V1.4.9
+ John E. Davis, davis@space.mit.edu
+ Mar 23, 2003
+ ____________________________________________________________
+
+ Table of Contents
+
+ Preface
+
+ 1. A Brief History of S-Lang
+ 2. Acknowledgements
+ 2. Introduction
+ 2. Interpreter Interface
+ 3. Embedding the Interpreter
+ 4. Calling the Interpreter
+ 4.1 Loading Files
+ 4.2 Loading Strings
+
+ 5. Intrinsic Functions
+ 5.1 Restrictions on Intrinsic Functions
+ 5.2 Adding a New Intrinsic
+ 5.3 More Complicated Intrinsics
+
+ 6. Intrinsic Variables
+ 7. Aggregate Data Objects
+ 7.1 Arrays
+ 7.2 Structures
+ 7.2.1 Interpreter Structures
+ 7.2.2 Intrinsic Structures
+ 7.2.2 Keyboard Interface
+
+ 8. Initializing the Keyboard Interface
+ 9. Resetting the Keyboard Interface
+ 10. Initializing the SLkp Routines
+ 11. Setting the Interrupt Handler
+ 12. Reading Keyboard Input with SLang_getkey
+ 13. Reading Keyboard Input with SLkp_getkey
+ 14. Buffering Input
+ 15. Global Variables
+ 15. Screen Management
+ 16. Initialization
+ 17. Resetting SLsmg
+ 18. Handling Screen Resize Events
+ 19. SLsmg Functions
+ 19.1 Positioning the cursor
+ 19.2 Writing to the Display
+ 19.3 Erasing the Display
+ 19.4 Setting Character Attributes
+ 19.5 Lines and Alternate Character Sets
+ 19.6 Miscellaneous Functions
+
+ 20. Variables
+ 21. Hints for using SLsmg
+ 21. Signal Functions
+ 21. Searching Functions
+ 22. Regular Expressions
+ 23. Simple Searches
+ 24. Initialization
+ 25. SLsearch
+ 25. Copyright
+ A. The GNU Public License
+ B. The Artistic License
+
+
+ ______________________________________________________________________
+
+ 1. Preface
+
+
+
+ S-Lang is an interpreted language that was designed from the start to
+ be easily embedded into a program to provide it with a powerful
+ extension language. Examples of programs that use S-Lang as an
+ extension language include the jed text editor, the slrn newsreader,
+ and sldxe (unreleased), a numerical computation program. For this
+ reason, S-Lang does not exist as a separate application and many of
+ the examples in this document are presented in the context of one of
+ the above applications.
+
+ S-Lang is also a programmer's library that permits a programmer to
+ develop sophisticated platform-independent software. In addition to
+ providing the S-Lang extension language, the library provides
+ facilities for screen management, keymaps, low-level terminal I/O,
+ etc. However, this document is concerned only with the extension
+ language and does not address these other features of the S-Lang
+ library. For information about the other components of the library,
+ the reader is referred to the The S-Lang Library Reference.
+
+
+ 1.1. A Brief History of S-Lang
+
+
+
+ I first began working on S-Lang sometime during the fall of 1992. At
+ that time I was writing a text editor (jed), which I wanted to endow
+ with a macro language. It occured to me that an application-
+ independent language that could be embedded into the editor would
+ prove more useful because I could envision embedding it into other
+ programs. As a result, S-Lang was born.
+
+ S-Lang was originally a stack language that supported a postscript-
+ like syntax. For that reason, I named it S-Lang, where the S was
+ supposed to emphasize its stack-based nature. About a year later, I
+ began to work on a preparser that would allow one to write using a
+ more traditional infix syntax making it easier to use for those
+ unfamiliar with stack based languages. Currently, the syntax of the
+ language resembles C, nevertheless some postscript-like features still
+ remain, e.g., the `%' character is still used as a comment delimiter.
+
+
+
+ 1.2. Acknowledgements
+
+
+
+ Since I first released S-Lang, I have received a lot feedback about
+ the library and the language from many people. This has given me the
+ opportunity and pleasure to interact with several people to make the
+ library portable and easy to use. In particular, I would like to
+ thank the following individuals:
+
+ Luchesar Ionkov <lionkov@sf.cit.bg> for his comments and criticisms of
+ the syntax of the language. He was the person who made me realize
+ that the low-level byte-code engine should be totally type-
+ independent. He also improved the tokenizer and preparser and
+ impressed upon me that the language needed a grammar.
+
+ Mark Olesen <olesen@weber.me.queensu.ca> for his many patches to
+ various aspects of the library and his support on AIX. He also
+ contributed a lot to the pre-processing (SLprep) routines.
+
+ John Burnell <j.burnell@irl.cri.nz> for the OS/2 port of the video and
+ keyboard routines. He also made value suggestions regarding the
+ interpreter interface.
+
+ Darrel Hankerson <hankedr@mail.auburn.edu> for cleaning up and
+ unifying some of the code and the makefiles.
+
+ Dominik Wujastyk <ucgadkw@ucl.ac.uk> who was always willing to test
+ new releases of the library.
+
+ Michael Elkins <me@muddcs.cs.hmc.edu> for his work on the curses
+ emulation.
+
+ Ulli Horlacher <framstag@belwue.de> and Oezguer Kesim <kesim@math.fu-
+ berlin.de> for the S-Lang newsgroup and mailing list.
+
+ Hunter Goatley, Andy Harper <Andy.Harper@kcl.ac.uk>, and Martin P.J.
+ Zinser <zinser@decus.decus.de> for their VMS support.
+
+ Dave Sims <sims@usa.acsys.com> and Chin Huang <cthuang@vex.net> for
+ Windows 95 and Windows NT support.
+
+ Lloyd Zusman <ljz@asfast.com> and Rich Roth <rich@on-the-net.com> for
+ creating and maintaining www.s-lang.org.
+
+ I am also grateful to many other people who send in bug-reports and
+ bug-fixes, for without such community involvement, S-Lang would not be
+ as well-tested and stable as it is. Finally, I would like to thank my
+ wife for her support and understanding while I spent long weekend
+ hours developing the library.
+
+
+
+ 2. Introduction
+
+
+
+ S-Lang is a C programmer's library that includes routines for the
+ rapid development of sophisticated, user friendly, multi-platform
+ applications. The S-Lang library includes the following:
+
+
+ o Low level tty input routines for reading single characters at a
+ time.
+
+ o Keymap routines for defining keys and manipulating multiple
+ keymaps.
+
+ o A high-level keyprocessing interface (SLkp) for handling function
+ and arrow keys.
+
+ o High level screen management routines for manipulating both
+ monochrome and color terminals. These routines are very efficient.
+ (SLsmg)
+
+ o Low level terminal-independent routines for manipulating the
+ display of a terminal. (SLtt)
+
+ o Routines for reading single line input with line editing and recall
+ capabilities. (SLrline)
+
+ o Searching functions: both ordinary searches and regular expression
+ searches. (SLsearch)
+
+ o An embedded stack-based language interpreter with a C-like syntax.
+
+
+ The library is currently available for OS/2, MSDOS, Unix, and VMS
+ systems. For the most part, the interface to library routines has
+ been implemented in such a way that it appears to be platform
+ independent from the point of view of the application. In addition,
+ care has been taken to ensure that the routines are ``independent'' of
+ one another as much as possible. For example, although the keymap
+ routines require keyboard input, they are not tied to S-Lang's
+ keyboard input routines--- one can use a different keyboard getkey
+ routine if one desires. This also means that linking to only part of
+ the S-Lang library does not pull the whole library into the
+ application. Thus, S-Lang applications tend to be relatively small in
+ comparison to programs that use libraries with similar capabilities.
+
+
+
+ 3. Interpreter Interface
+
+
+
+ The S-Lang library provides an interpreter that when embedded into an
+ application, makes the application extensible. Examples of programs
+ that embed the interpreter include the jed editor and the slrn
+ newsreader.
+
+ Embedding the interpreter is easy. The hard part is to decide what
+ application specific built-in or intrinsic functions should be
+ provided by the application. The S-Lang library provides some pre-
+ defined intrinsic functions, such as string processing functions, and
+ simple file input-output routines. However, the basic philosophy
+ behind the interpreter is that it is not a standalone program and it
+ derives much of its power from the application that embeds it.
+
+
+ 3.1. Embedding the Interpreter
+
+
+
+ Only one function needs to be called to embed the S-Lang interpreter
+ into an application: SLang_init_slang. This function initializes the
+ interpreter's data structures and adds some intrinsic functions:
+
+
+ if (-1 == SLang_init_slang ())
+ exit (EXIT_FAILURE);
+
+
+
+ This function does not provide file input output intrinsic nor does it
+ provide mathematical functions. To make these as well as some posix
+ system calls available use
+
+
+ if ((-1 == SLang_init_slang ()) /* basic interpreter functions */
+ || (-1 == SLang_init_slmath ()) /* sin, cos, etc... */
+ || (-1 == SLang_init_stdio ()) /* stdio file I/O */
+ || (-1 == SLang_init_posix_dir ()) /* mkdir, stat, etc. */
+ || (-1 == SLang_init_posix_process ()) /* getpid, umask, etc. */
+ )
+ exit (EXIT_FAILURE);
+
+
+
+ If you intend to enable all intrinsic functions, then it is simpler to
+ initialize the interpreter via
+
+
+ if (-1 == SLang_init_all ())
+ exit (EXIT_FAILURE);
+
+
+
+ See the \slang-run-time-library for more information about the intrin-
+ sic functions.
+
+
+
+ 3.2. Calling the Interpreter
+
+
+
+ There are several ways of calling the interpreter. The two most
+ common method is to load a file containing S-Lang code, or to load a
+ string.
+
+
+ 3.2.1. Loading Files
+
+ The SLang_load_file and SLns_load_file functions may be used to
+ interpret a file. Both these functions return zero if successful, or
+ -1 upon failure. If either of these functions fail, the interpreter
+ will accept no more code unless the error state is cleared. This is
+ done by calling SLang_restart function to set the interpreter to its
+ default state, and setting SLang_Error to 0, e.g.,
+
+
+ if (-1 == SLang_load_file ("site.sl"))
+ {
+ /* Clear the error and rest the interpreter */
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+ When a file is loaded via SLang_load_file, any non-public variables
+ and functions defined in the file will be placed into a namespace that
+ is local to the file itself. The SLns_load_file function may be used
+ to load a file using a specified namespace, e.g.,
+
+
+ if (-1 == SLns_load_file ("site.sl", "NS"))
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+ will load site.sl into a namespace called NS. If such a namespace
+ does not exist, then it will be created.
+
+ Both the SLang_load_file and SLns_load_file functions search for files
+ along an application-specified search path. This path may be set
+ using the SLpath_set_load_path function, as well as from interpeted
+ code via the set_slang_load_path function. By default, no search path
+ is defined.
+
+ Files are searched as follows: If the name begins with the equivalent
+ of "./" or "../", then it is searched for with respect to the current
+ directory, and not along the load-path. If no such file exists, then
+ an error will be generated. Otherwise, the file is searched for in
+ each of the directories of the load-path by concatenating the path
+ element with the specified file name. The first such file found to
+ exist by this process will be loaded. If a matching file still has
+ not been found, and the file name lacks an extension, then the path is
+ searched with ".sl" and ".slc" appended to the filename. If two such
+ files are found (one ending with ".sl" and the other with ".slc"),
+ then the more recent of the two will be used. If no matching file has
+ been found by this process, then the search will cease and an error
+ generated.
+ The search path is a delimiter separated list of directories that
+ specify where the interpreter looks for files. By default, the value
+ of the delimiter is OS-dependent following the convention of the
+ underlying OS. For example, on Unix the delimiter is represented by a
+ colon, on DOS/Windows it is a semi-colon, and on VMS it is a space.
+ The SLpath_set_delimiter and SLpath_get_delimiter may be used to set
+ and query the delimiter's value, respectively.
+
+
+ 3.2.2. Loading Strings
+
+ There are several other mechanisms for interacting with the
+ interpreter. For example, the SLang_load_string function loads a
+ string into the interpreter and interprets it:
+
+
+ if (-1 == SLang_load_string ("message (\"hello\");"))
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+ Similarly, the SLns_load_string function may be used to load a string
+ into a specified namespace.
+
+ Typically, an interactive application will load a file via
+ SLang_load_file and then go into a loop that consists of reading lines
+ of input and sending them to the interpreter, e.g.,
+
+
+ while (EOF != fgets (buf, sizeof (buf), stdin))
+ {
+ if (-1 == SLang_load_string (buf))
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+ Finally, some applications such as jed and slrn use another method of
+ interacting with the interpreter. They read key sequences from the
+ keyboard and map those key sequences to interpreter functions via the
+ S-Lang keymap interface.
+
+
+
+ 3.3. Intrinsic Functions
+
+
+
+ An intrinsic function is simply a function that is written in C and is
+ made available to the interpreter as a built-in function. For this
+ reason, the words `intrinsic' and `built-in' are often used
+ interchangeably.
+
+ Applications are expected to add application specific functions to the
+ interpreter. For example, jed adds nearly 300 editor-specific
+ intrinsic functions. The application designer should think carefully
+ about what intrinsic functions to add to the interpreter.
+
+
+ 3.3.1. Restrictions on Intrinsic Functions
+
+
+
+ When implementing intrinsic functions, it is necessary to follow a few
+ rules to cooperate with the interpreter.
+
+ The C version of an intrinsic function takes only pointer arguments.
+ This is because when the interpreter calls an intrinsic function, it
+ passes values to the function by reference and not by value. For
+ example, intrinsic with the declarations:
+
+
+ int intrinsic_0 (void);
+ int intrinsic_1 (char *s);
+ void intrinsic_2 (char *s, int *i);
+ void intrinsic_3 (int *i, double *d, double *e);
+
+
+
+ are all valid. However,
+
+
+ int invalid_1 (char *s, int len);
+
+
+
+ is not valid since the len parameter is not a pointer.
+
+ The return value of an intrinsic function must be one of the following
+ types: void, char, short, int, long, double, char *, as well as
+ unsigned versions of the integer types. A function such as
+
+
+ int *invalid (void);
+
+
+
+ is not permitted since int* is not a valid return-type for an intrin-
+ sic function. Any other type of value can be passed back to the
+ interpreter by explicitly pushing the object onto the interpreter's
+ stack via the appropriate "push" function.
+
+ The current implementation limits the number of arguments of an
+ intrinsic function to 7. The "pop" functions can be used to allow the
+ function to take an arbitrary number as seen from an interpreter
+ script.
+
+ Another restriction is that the intrinsic function should regard all
+ its parameters as pointers to constant objects and make no attempt to
+ modify the value to which they point. For example,
+
+
+ void truncate (char *s)
+ {
+ s[0] = 0;
+ }
+
+
+
+ is illegal since the function modifies the string s.
+
+ 3.3.2. Adding a New Intrinsic
+
+
+
+ There are two basic mechanisms for adding an intrinsic function to the
+ interpreter: SLadd_intrinsic_function and SLadd_intrin_fun_table.
+ Functions may be added to a specified namespace via
+ SLns_add_intrinsic_function and SLns_add_intrin_fun_table functions.
+
+ As an specific example, consider a function that will cause the
+ program to exit via the exit C library function. It is not possible
+ to make this function an intrinsic because it does not meet the
+ specifications for an intrinsic function that were described earlier.
+ However, one can call exit from a function that is suitable, e.g.,
+
+
+ void intrin_exit (int *code)
+ {
+ exit (*code);
+ }
+
+
+
+ This function may be made available to the interpreter as an intrinsic
+ via the SLadd_intrinsic_function routine:
+
+
+ if (-1 == SLadd_intrinsic_function ("exit", (FVOID_STAR) intrin_exit,
+ SLANG_VOID_TYPE, 1,
+ SLANG_INT_TYPE))
+ exit (EXIT_FAILURE);
+
+
+
+ This statement basically tells the interpreter that intrin_exit is a
+ function that returns nothing and takes a single argument: a pointer
+ to an integer (SLANG_INT_TYPE). A user can call this function from
+ within the interpreter via
+
+
+ message ("Calling the exit function");
+ exit (0);
+
+
+
+ After printing a message, this will cause the intrin_exit function to
+ execute, which in turn calls exit.
+
+ The most convenient mechanism for adding new intrinsic functions is to
+ create a table of SLang_Intrin_Fun_Type objects and add the table via
+ the SLadd_intrin_fun_table function. The table will look like:
+
+
+
+ SLang_Intrin_Fun_Type My_Intrinsics [] =
+ {
+ /* table entries */
+ MAKE_INTRINSIC_N(...),
+ MAKE_INTRINSIC_N(...),
+ .
+ .
+ MAKE_INTRINSIC_N(...),
+ SLANG_END_INTRIN_FUN_TABLE
+ };
+
+
+
+ Construction of the table entries may be facilitated using a set of
+ MAKE_INTRINSIC macros defined in slang.h. The main macro is called
+ MAKE_INTRINSIC_N and takes 11 arguments:
+
+
+ MAKE_INTRINSIC_N(name, funct-ptr, return-type, num-args,
+ arg-1-type, arg-2-type, ... arg-7-type)
+
+
+
+ Here name is the name of the intrinsic function that the interpreter
+ is to give to the function. func-ptr is a pointer to the intrinsic
+ function taking num-args and returning ret-type. The final 7 argu-
+ ments specifiy the argument types. For example, the intrin_exit
+ intrinsic described above may be added to the table using
+
+
+ MAKE_INTRINSIC_N("exit", intrin_exit, SLANG_VOID_TYPE, 1,
+ SLANG_INT_TYPE, 0,0,0,0,0,0)
+
+
+
+ While MAKE_INTRINSIC_N is the main macro for constructing table
+ entries, slang.h defines other macros that may prove useful. In
+ particular, an entry for the intrin_exit function may also be created
+ using any of the following forms:
+
+
+ MAKE_INTRINSIC_1("exit", intrin_exit, SLANG_VOID_TYPE, SLANG_INT_TYPE)
+ MAKE_INTRINSIC_I("exit", intrin_exit, SLANG_VOID_TYPE)
+
+
+
+ See slang.h for related macros. You are also encouraged to look at,
+ e.g., slang/src/slstd.c for a more extensive examples.
+
+ The table may be added via the SLadd_intrin_fun_table function, e.g.,
+
+
+ if (-1 == SLadd_intrin_fun_table (My_Intrinsics, NULL))
+ {
+ /* an error occurred */
+ }
+
+
+
+ Please note that there is no need to load a given table more than
+ once, and it is considered to be an error on the part of the
+ application it adds the same table multiple times. For performance
+ reasons, no checking is performed by the library to see if a table has
+ already been added.
+
+ Earlier it was mentioned that intrinsics may be added to a specified
+ namespace. To this end, one must first get a pointer to the namespace
+ via the SLns_create_namespace function. The following example
+ illustrates how this function is used to add the My_Intrinsics table
+ to a namespace called my:
+
+
+ SLang_NameSpace_Type *ns = SLns_create_namespace ("my");
+ if (ns == NULL)
+ return -1;
+
+ return SLns_add_intrin_fun_table (ns, My_Intrinsics, "__MY__"));
+
+
+
+ 3.3.3. More Complicated Intrinsics
+
+
+ The intrinsic functions described in the previous example were
+ functions that took a fixed number of arguments. In this section we
+ explore more complex intrinsics such as those that take a variable
+ number of arguments.
+
+ Consider a function that takes two double precision numbers and
+ returns the lesser:
+
+
+ double intrin_min (double *a, double *b)
+ {
+ if (*a < *b) return *a;
+ return *b;
+ }
+
+
+
+ This function may be added to a table of intrinsics using
+
+
+ MAKE_INTRINSIC_2("vmin", intrin_min, SLANG_DOUBLE_TYPE,
+ SLANG_DOUBLE_TYPE, SLANG_DOUBLE_TYPE)
+
+
+
+ It is useful to extend this function to take an arbitray number of
+ arguments and return the lesser. Consider the following variant:
+
+
+
+ double intrin_min_n (int *num_ptr)
+ {
+ double min_value, x;
+ unsigned int num = (unsigned int) *num_ptr;
+
+ if (-1 == SLang_pop_double (&min_value, NULL, NULL))
+ return 0.0;
+ num--;
+
+ while (num > 0)
+ {
+ num--;
+ if (-1 == SLang_pop_double (&x, NULL, NULL))
+ return 0.0;
+ if (x < min_value) min_value = x;
+ }
+ return min_value;
+ }
+
+
+
+ Here the number to compare is passed to the function and the actual
+ numbers are removed from the stack via the SLang_pop_double function.
+ A suitable table entry for it is
+
+
+ MAKE_INTRINSIC_I("vmin", intrin_min_n, SLANG_DOUBLE_TYPE)
+
+
+
+ This function would be used in an interpreter script via a statement
+ such as
+
+
+ variable xmin = vmin (x0, x1, x2, x3, x4, 5);
+
+
+
+ which computes the smallest of 5 values.
+
+ The problem with this intrinsic function is that the user must
+ explicitly specify how many numbers to compare. It would be more
+ convenient to simply use
+
+
+ variable xmin = vmin (x0, x1, x2, x3, x4);
+
+
+
+ An intrinsic function can query the value of the variable
+ SLang_Num_Function_Args to obtain the necessary information:
+
+
+
+ double intrin_min (void)
+ {
+ double min_value, x;
+
+ unsigned int num = SLang_Num_Function_Args;
+
+ if (-1 == SLang_pop_double (&min_value, NULL, NULL))
+ return 0.0;
+ num--;
+
+ while (num > 0)
+ {
+ num--;
+ if (-1 == SLang_pop_double (&x, NULL, NULL))
+ return 0.0;
+ if (x < min_value) min_value = x;
+ }
+ return min_value;
+ }
+
+
+
+ This may be declared as an intrinsic using:
+
+
+ MAKE_INTRINSIC_0("vmin", intrin_min, SLANG_DOUBLE_TYPE)
+
+
+
+ 3.4. Intrinsic Variables
+
+
+
+ It is possible to access an application's global variables from within
+ the interpreter. The current implementation supports the access of
+ variables of type int, char *, and double.
+
+ There are two basic methods of making an intrinsic variable available
+ to the interpreter. The most straight forward method is to use the
+ function SLadd_intrinsic_variable:
+
+
+ int SLadd_intrinsic_variable (char *name, VOID_STAR addr,
+ unsigned char data_type,
+ int read_only);
+
+
+
+ For example, suppose that I is an integer variable, e.g.,
+
+
+ int I;
+
+
+
+ One can make it known to the interpreter as I_Variable via a statement
+ such as
+
+
+ if (-1 == SLadd_intrinsic_variable ("I_Variable", &I,
+ SLANG_INT_TYPE, 0))
+ exit (EXIT_FAILURE);
+
+
+
+ Similarly, if S is declared as
+
+
+ char *S;
+
+
+
+ then
+
+
+ if (-1 == SLadd_intrinsic_variable ("S_Variable", &S,
+ SLANG_STRING_TYPE, 1))
+ exit (EXIT_FAILURE);
+
+
+
+ makes S available as a read-only variable with the name S_Variable.
+ Note that if a pointer variable is made available to the interpreter,
+ its value is managed by the interpreter and not the application. For
+ this reason, it is recommended that such variables be declared as
+ read-only.
+
+ It is important to note that if S were declared as an array of
+ characters, e.g.,
+
+
+ char S[256];
+
+
+
+ then it would not be possible to make it directly available to the
+ interpreter. However, one could create a pointer to it, i.e.,
+
+
+ char *S_Ptr = S;
+
+
+
+ and make S_Ptr available as a read-only variable.
+
+ One should not make the mistake of trying to use the same address for
+ different variables as the following example illustrates:
+
+
+
+ int do_not_try_this (void)
+ {
+ static char *names[3] = {"larry", "curly", "moe"};
+ unsigned int i;
+
+ for (i = 0; i < 3; i++)
+ {
+ int value;
+ if (-1 == SLadd_intrinsic_variable (names[i], (VOID_STAR) &value,
+ SLANG_INT_TYPE, 1))
+ return -1;
+ }
+ return 0;
+ }
+
+
+
+ Not only does this piece of code create intrinsic variables that use
+ the same address, it also uses the address of a local variable that
+ will go out of scope.
+
+ The most convenient method for adding many intrinsic variables to the
+ interpreter is to create an array of SLang_Intrin_Var_Type objects and
+ then add the array via SLadd_intrin_var_table. For example, the array
+
+
+ static SLang_Intrin_Var_Type Intrin_Vars [] =
+ {
+ MAKE_VARIABLE("I_Variable", &I, SLANG_INT_TYPE, 0),
+ MAKE_VARIABLE("S_Variable", &S_Ptr, SLANG_STRING_TYPE, 1),
+ SLANG_END_TABLE
+ };
+
+
+
+ may be added via
+
+
+ if (-1 == SLadd_intrin_var_table (Intrin_Vars, NULL))
+ exit (EXIT_FAILURE);
+
+
+
+ It should be rather obvious that the arguments to the MAKE_VARIABLE
+ macro correspond to the parameters of the SLadd_intrinsic_variable
+ function.
+
+ Finally, variables may be added to a specific namespace via the
+ SLns_add_intrin_var_table and SLns_add_intrinsic_variable functions.
+
+
+
+ 3.5. Aggregate Data Objects
+
+
+ An aggregate data object is an object that can contain more than one
+ data value. The S-Lang interpreter supports several such objects:
+ arrays, structure, and associative arrays. In the following sections,
+ information about interacting with these objects is given.
+
+
+
+ 3.5.1. Arrays
+
+
+ An intrinsic function may interact with an array in several different
+ ways. For example, an intrinsic may create an array and return it.
+ The basic functions for manipulating arrays include:
+
+
+ SLang_create_array
+ SLang_pop_array_of_type
+ SLang_push_array
+ SLang_free_array
+ SLang_get_array_element
+ SLang_set_array_element
+
+
+
+ The use of these functions will be illustrated via a few simple exam-
+ ples.
+
+ The first example shows how to create an return an array of strings to
+ the interpreter. In particular, the names of the four seasons of the
+ year will be returned:
+
+
+ void months_of_the_year (void)
+ {
+ static char *seasons[4] =
+ {
+ "Spring", "Summer", "Autumn", "Winter"
+ };
+ SLang_Array_Type *at;
+ int i, four;
+
+ four = 4;
+ at = SLang_create_array (SLANG_STRING_TYPE, 0, NULL, &four, 1);
+ if (at == NULL)
+ return;
+
+ /* Now set the elements of the array */
+ for (i = 0; i < 4; i++)
+ {
+ if (-1 == SLang_set_array_element (at, &i, &seasons[i]))
+ {
+ SLang_free_array (at);
+ return;
+ }
+ }
+
+ (void) SLang_push_array (at, 0);
+ SLang_free_array (at);
+ }
+
+
+
+ This example illustrates several points. First of all, the SLang_cre-
+ ate_array function was used to create a 1 dimensional array of 4
+ strings. Since this function could fail, its return value was
+ checked. Then the SLang_set_array_element function was used to set
+ the elements of the newly created array. Note that the address con-
+ taining the value of the array element was passed and not the value of
+ the array element itself. That is,
+
+
+ SLang_set_array_element (at, &i, seasons[i])
+
+
+
+ was not used. The return value from this function was also checked
+ because it too could also fail. Finally, the array was pushed onto
+ the interpreter's stack and then it was freed. It is important to
+ understand why it was freed. This is because arrays are reference-
+ counted. When the array was created, it was returned with a reference
+ count of 1. When it was pushed, the reference count was bumped up to
+ 2. Then since it was nolonger needed by the function,
+ SLang_free_array was called to decrement the reference count back to
+ 1. For convenience, the second argument to SLang_push_array deter-
+ mines whether or not it is to also free the array. So, instead of the
+ two function calls:
+
+
+ (void) SLang_push_array (at, 0);
+ SLang_free_array (at);
+
+
+
+ it is preferable to combine them as
+
+
+ (void) SLang_push_array (at, 1);
+
+
+
+ The second example returns a diagonal array of a specified size to the
+ stack. A diagonal array is a 2-d array with all elements zero except
+ for those along the diagonal, which have a value of one:
+
+
+ void make_diagonal_array (int n)
+ {
+ SLang_Array_Type *at;
+ int dims[2];
+ int i, one;
+
+ dims[0] = dims[1] = n;
+ at = SLang_create_array (SLANG_INT_TYPE, 0, NULL, dims, 2);
+ if (at == NULL)
+ return;
+
+ one = 1;
+ for (i = 0; i < n; i++)
+ {
+ dims[0] = dims[1] = i;
+ if (-1 == SLang_set_array_element (at, dims, &one))
+ {
+ SLang_free_array (at);
+ return;
+ }
+ }
+
+ (void) SLang_push_array (at, 1);
+ }
+
+
+
+ In this example, only the diagonal elements of the array were set.
+ This is bacause when the array was created, all its elements were set
+ to zero.
+
+ Now consider an example that acts upon an existing array. In
+ particular, consider one that computes the trace of a 2-d matrix,
+ i.e., the sum of the diagonal elements:
+
+
+ double compute_trace (void)
+ {
+ SLang_Array_Type *at;
+ double trace;
+ int dims[2];
+
+ if (-1 == SLang_pop_array_of_type (&at, SLANG_DOUBLE_TYPE))
+ return 0.0;
+
+ /* We want a 2-d square matrix. If the matrix is 1-d and has only one
+ element, then return that element. */
+ trace = 0.0;
+ if (((at->num_dims == 1) && (at->dims[0] == 1))
+ || ((at->num_dims == 2) && (at->dims[0] == at->dims[1])))
+ {
+ double dtrace;
+ int n = at->dims[0];
+
+ for (i = 0; i < n; i++)
+ {
+ dims[0] = dims[1] = i;
+ (void) SLang_get_array_element (at, &dims, &dtrace);
+ trace += dtrace;
+ }
+ }
+ else SLang_verror (SL_TYPE_MISMATCH, "Expecting a square matrix");
+
+ SLang_free_array (at);
+ return trace;
+ }
+
+
+
+ In this example, SLang_pop_array_of_type was used to pop an array of
+ doubles from the stack. This function will make implicit typecasts in
+ order to return an array of the requested type.
+
+
+
+ 3.5.2. Structures
+
+
+
+ For the purposes of this section, we shall differentiate structures
+ according to whether or not they correspond to an application defined
+ C structure. Those that do are called intrinsic structures, and those
+ do not are called S-Lang interpreter structures.
+
+
+ 3.5.2.1. Interpreter Structures
+
+
+ The following simple example shows one method that may be used to
+ create and return a structure with a string and integer field to the
+ interpreter's stack:
+
+ int push_struct_example (char *string_value, int int_value)
+ {
+ char *field_names[2];
+ unsigned char field_types[2];
+ VOID_STAR field_values[2];
+
+ field_names[0] = "string_field";
+ field_types[0] = SLANG_STRING_TYPE;
+ field_values[0] = &string_value;
+
+ field_names[1] = "int_field";
+ field_types[1] = SLANG_INT_TYPE;
+ field_values[1] = &int_value;
+
+ if (-1 == SLstruct_create_struct (2, field_names,
+ field_types, field_values))
+ return -1;
+ return 0;
+ }
+
+
+
+ Here, SLstruct_create_struct is used to push a structure with the
+ specified field names and values onto the interpreter's stack.
+
+ A simpler mechanism exists provided that one has already defined a C
+ structure with a description of how the structure is laid out. For
+ example, consider a C structure defined by
+
+
+ typedef struct
+ {
+ char *s;
+ int i;
+ }
+ SI_Type;
+
+
+
+ Its layout may be specified via a table of SLang_CStruct_Field_Type
+ entries:
+
+
+ SLang_CStruct_Field_Type SI_Type_Layout [] =
+ {
+ MAKE_CSTRUCT_FIELD(SI_Type, s, "string_field", SLANG_STRING_TYPE, 0),
+ MAKE_CSTRUCT_FIELD(SI_Type, i, "int_field", SLANG_INT_TYPE, 0),
+ SLANG_END_CSTRUCT_TABLE
+ };
+
+
+
+ Here, MAKE_CSTRUCT_FIELD is a macro taking 5 arguments:
+
+
+ MAKE_CSTRUCT_FIELD(C-structure-type,
+ C-field-name,
+ slang-field-name,
+ slang-data-type,
+ is-read-only)
+
+
+
+ The first argument is the structure type, the second is the name of a
+ field of the structure, the third is a string that specifies the name
+ of the corresponding field of the S-Lang structure, the fourth argu-
+ ment specifies the field's type, and the last argument specifies
+ whether or not the field should be regarded as read-only.
+
+ Once the layout of the structure has been specified, pushing a S-Lang
+ version of the structure is trival:
+
+
+ int push_struct_example (char *string_value, int int_value)
+ {
+ SI_Type si;
+
+ si.s = string_value;
+ si.i = int_value;
+ return SLang_push_cstruct ((VOID_STAR)&si, SI_Type_Layout);
+ }
+
+
+
+ This mechanism of structure creation also permits a S-Lang structure
+ to be passed to an intrinsic function through the use of the
+ SLang_pop_cstruct routine, e.g.,
+
+
+ void print_si_struct (void)
+ {
+ SI_Type si;
+ if (-1 == SLang_pop_cstruct ((VOID_STAR)&si, SI_Type_Layout))
+ return;
+ printf ("si.i=%d", si.i);
+ printf ("si.s=%s", si.s);
+ SLang_free_cstruct ((VOID_STAR)&si, SI_Type_Layout);
+ }
+
+
+
+ Assuming print_si_struct exists as an intrinsic function, the S-Lang
+ code
+
+
+ variable s = struct {string_field, int_field};
+ s.string_field = "hello";
+ s.int_field = 20;
+ print_si_struct (s);
+
+
+
+ would result in the display of
+
+
+ si.i=20;
+ si.s=hello
+
+
+
+ Note that the SLang_free_cstruct function was called after the con-
+ tents of si were nolonger needed. This was necessary because
+ SLang_pop_cstruct allocated memory to set the char *s field of si.
+ Calling SLang_free_cstruct frees up such memory.
+
+ Now consider the following:
+
+
+ typedef struct
+ {
+ pid_t pid;
+ gid_t group;
+ }
+ X_t;
+
+
+
+ How should the layout of this structure be defined? One might be
+ tempted to use:
+
+
+ SLang_CStruct_Field_Type X_t_Layout [] =
+ {
+ MAKE_CSTRUCT_FIELD(X_t, pid, "pid", SLANG_INT_TYPE, 0),
+ MAKE_CSTRUCT_FIELD(X_t, group, "group", SLANG_INT_TYPE, 0),
+ SLANG_END_CSTRUCT_TABLE
+ };
+
+
+
+ However, this assumes pid_t and gid_t have been typedefed as ints.
+ But what if gid_t is a short? In such a case, using
+
+
+ MAKE_CSTRUCT_FIELD(X_t, group, "group", SLANG_SHORT_TYPE, 0),
+
+
+
+ would be the appropriate entry for the group field. Of course, one
+ has no way of knowing how gid_t is declared on other systems. For
+ this reason, it is preferable to use the MAKE_CSTRUCT_INT_FIELD macro
+ in cases involving integer valued fields, e.g.,
+
+
+ SLang_CStruct_Field_Type X_t_Layout [] =
+ {
+ MAKE_CSTRUCT_INT_FIELD(X_t, pid, "pid", 0),
+ MAKE_CSTRUCT_INT_FIELD(X_t, group, "group", 0),
+ SLANG_END_CSTRUCT_TABLE
+ };
+
+
+
+ Before leaving this section, it is important to mention that access to
+ character array fields is not permitted via this interface. That is,
+ a structure such as
+
+
+ typedef struct
+ {
+ char name[32];
+ }
+ Name_Type;
+
+
+
+ is not supported since char name[32] is not a SLANG_STRING_TYPE
+ object. Always keep in mind that a SLANG_STRING_TYPE object is a char
+ *.
+
+
+ 3.5.2.2. Intrinsic Structures
+
+
+ Here we show how to make intrinsic structures available to the
+ interpreter.
+
+ The simplest interface is to structure pointers and not to the actual
+ structures themselves. The latter would require the interpreter to be
+ involved with the creation and destruction of the structures. Dealing
+ with the pointers themselves is far simpler.
+
+ As an example, consider an object such as
+
+
+ typedef struct _Window_Type
+ {
+ char *title;
+ int row;
+ int col;
+ int width;
+ int height;
+ } Window_Type;
+
+
+
+ which defines a window object with a title, size (width, height), and
+ location (row, col).
+
+ We can make variables of type Window_Type available to the interpreter
+ via a table as follows:
+
+
+ static SLang_IStruct_Field_Type Window_Type_Field_Table [] =
+ {
+ MAKE_ISTRUCT_FIELD(Window_Type, title, "title", SLANG_STRING_TYPE, 1),
+ MAKE_ISTRUCT_FIELD(Window_Type, row, "row", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, col, "col", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, width, "width", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, height, "height", SLANG_INT_TYPE, 0),
+ SLANG_END_ISTRUCT_TABLE
+ };
+
+
+
+ More precisely, this defines the layout of the Window_Type structure.
+ Here, the title has been declared as a read-only field. Using
+
+
+ MAKE_ISTRUCT_FIELD(Window_Type, title, "title", SLANG_STRING_TYPE, 0),
+
+
+
+ would allow read-write access.
+
+ Now suppose that My_Window is a pointer to a Window_Type object, i.e.,
+
+
+
+ Window_Type *My_Window;
+
+
+
+ We can make this variable available to the interpreter via the
+ SLadd_istruct_table function:
+
+
+ if (-1 == SLadd_istruct_table (Window_Type_Field_Table,
+ (VOID_STAR) &My_Window,
+ "My_Win"))
+ exit (1);
+
+
+
+ This creates a S-Lang interpreter variable called My_Win whose value
+ corresponds to the My_Win structure. This would permit one to access
+ the fields of My_Window via S-Lang statements such as
+
+
+ define set_width_and_height (w,h)
+ {
+ My_Win.width = w;
+ My_Win.height = h;
+ }
+
+
+
+ It is extremely important to understand that the interface described
+ in this section does not allow the interpreter to create new instances
+ of Window_Type objects. The interface merely defines an association
+ or correspondence between an intrinsic structure pointer and a S-Lang
+ variable. For example, if the value of My_Window is NULL, then My_Win
+ would also be NULL.
+
+ One should be careful in allowing read/write access to character
+ string fields. If read/write access is allowed, then the application
+ should always use the SLang_create_slstring and SLang_free_slstring
+ functions to set the character string field of the structure.
+
+
+
+ 4. Keyboard Interface
+
+
+
+ S-Lang's keyboard interface has been designed to allow an application
+ to read keyboard input from the user in a system-independent manner.
+ The interface consists of a set of low routines for reading single
+ character data as well as a higher level interface (SLkp) which
+ utilize S-Lang's keymap facility for reading multi-character
+ sequences.
+
+ To initialize the interface, one must first call the function
+ SLang_init_tty. Before exiting the program, the function
+ SLang_reset_tty must be called to restore the keyboard interface to
+ its original state. Once initialized, the low-level SLang_getkey
+ function may be used to read simgle keyboard characters from the
+ terminal. An application using the higher-level SLkp interface will
+ read charcters using the SLkp_getkey function.
+
+ In addition to these basic functions, there are also functions to
+ ``unget'' keyboard characters, flush the input, detect pending-input
+ with a timeout, etc. These functions are defined below.
+
+
+
+ 4.1. Initializing the Keyboard Interface
+
+
+
+ The function SLang_init_tty must be called to initialize the terminal
+ for single character input. This puts the terminal in a mode usually
+ referred to as ``raw'' mode.
+
+ The prototype for the function is:
+
+
+ int SLang_init_tty (int abort_char, int flow_ctrl, int opost);
+
+
+
+ It takes three parameters that are used to specify how the terminal is
+ to be initialized.
+
+ The first parameter, abort_char, is used to specify the interrupt
+ character (SIGINT). Under MSDOS, this value corresponds to the scan
+ code of the character that will be used to generate the interrupt.
+ For example, under MSDOS, 34 should be used to make Ctrl-G generate an
+ interrupt signal since 34 is the scan code for G. On other systems,
+ the value of abort_char will simply be the ascii value of the control
+ character that will be used to generate the interrupt signal, e.g., 7
+ for Ctrl-G. If -1 is passed, the interrupt character will not be
+ changed.
+
+ Pressing the interrupt character specified by the first argument will
+ generate a signal (SIGINT) that may or not be caught by the
+ application. It is up to the application to catch this signal. S-
+ Lang provides the function Slang_set_abort_signal to make it easy to
+ facilitate this task.
+
+ The second parameter is used to specify whether or not flow control
+ should be used. If this parameter is zero, flow control is enabled
+ otherwise it is disabled. Disabling flow control is necessary to pass
+ certain characters to the application (e.g., Ctrl-S and Ctrl-Q). For
+ some systems such as MSDOS, this parameter is meaningless.
+
+ The third parameter, opost, is used to turn output processing on or
+ off. If opost is zero, output processing is not turned on otherwise,
+ output processing is turned on.
+
+ The SLang_init_tty function returns -1 upon failure. In addition,
+ after it returns, the S-Lang global variable SLang_TT_Baud_Rate will
+ be set to the baud rate of the terminal if this value can be
+ determined.
+
+ Example:
+
+
+ if (-1 == SLang_init_tty (7, 0, 0)) /* For MSDOS, use 34 as scan code */
+ {
+ fprintf (stderr, "Unable to initialize the terminal.\n");
+ exit (1);
+ }
+ SLang_set_abort_signal (NULL);
+
+
+
+ Here the terminal is initialized such that flow control and output
+ processing are turned off. In addition, the character Ctrl-G (-- For
+ MSDOS systems, use the scan code 34 instead of 7 for Ctrl-G--) has
+ been specified to be the interrupt character. The function
+ SLang_set_abort_signal is used to install the default S-Lang interrupt
+ signal handler.
+
+
+
+ 4.2. Resetting the Keyboard Interface
+
+
+
+ The function SLang_reset_tty must be called to reset the terminal to
+ the state it was in before the call to SLang_init_tty. The prototype
+ for this function is:
+
+
+ void SLang_reset_tty (void);
+
+
+
+ Usually this function is only called before the program exits. How-
+ ever, if the program is suspended it should also be called just before
+ suspension.
+
+
+
+ 4.3. Initializing the SLkp Routines
+
+
+
+ Extra initialization of the higher-level SLkp functions are required
+ because they are layered on top of the lower level routines. Since
+ the SLkp_getkey function is able to process function and arrow keys in
+ a terminal independent manner, it is necessary to call the
+ SLtt_get_terminfo function to get information about the escape
+ character sequences that the terminal's function keys send. Once that
+ information is available, the SLkp_init function can construct the
+ proper keymaps to process the escape sequences.
+
+ This part of the initialization process for an application using this
+ interface will look something like:
+
+
+
+ SLtt_get_terminfo ();
+ if (-1 == SLkp_init ())
+ {
+ SLang_doerror ("SLkp_init failed.");
+ exit (1);
+ }
+ if (-1 == SLang_init_tty (-1, 0, 1))
+ {
+ SLang_doerror ("SLang_init_tty failed.");
+ exit (1);
+ }
+
+
+
+ It is important to check the return status of the SLkp_init function
+ which can failed if it cannot allocate enough memory for the keymap.
+
+
+
+ 4.4. Setting the Interrupt Handler
+
+
+
+ The function SLang_set_abort_signal may be used to associate an
+ interrupt handler with the interrupt character that was previously
+ specified by the SLang_init_tty function call. The prototype for this
+ function is:
+
+
+ void SLang_set_abort_signal (void (*)(int));
+
+
+
+ This function returns nothing and takes a single parameter which is a
+ pointer to a function taking an integer value and returning void. If
+ a NULL pointer is passed, the default S-Lang interrupt handler will be
+ used. The S-Lang default interrupt handler under Unix looks like:
+
+
+ static void default_sigint (int sig)
+ {
+ SLsignal_intr (SIGINT, default_sigint);
+ SLKeyBoard_Quit = 1;
+ if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
+ }
+
+
+
+ It simply sets the global variable SLKeyBoard_Quit to one and if the
+ variable SLang_Ignore_User_Abort is non-zero, SLang_Error is set to
+ indicate a user break condition. (The function SLsignal_intr is simi-
+ lar to the standard C signal function except that it will interrupt
+ system calls. Some may not like this behavior and may wish to call
+ this SLang_set_abort_signal with a different handler.)
+ Although the function expressed above is specific to Unix, the
+ analogous routines for other operating systems are equivalent in
+ functionality even though the details of the implementation may vary
+ drastically (e.g., under MSDOS, the hardware keyboard interrupt int 9h
+ is hooked).
+
+
+
+ 4.5. Reading Keyboard Input with SLang_getkey
+
+
+
+ After initializing the keyboard via SLang_init_tty, the S-Lang
+ function SLang_getkey may be used to read characters from the terminal
+ interface. In addition, the function SLang_input_pending may be used
+ to determine whether or not keyboard input is available to be read.
+
+ These functions have prototypes:
+
+
+ unsigned int SLang_getkey (void);
+ int SLang_input_pending (int tsecs);
+
+
+
+ The SLang_getkey function returns a single character from the termi-
+ nal. Upon failure, it returns 0xFFFF. If the interrupt character
+ specified by the SLang_init_tty function is pressed while this func-
+ tion is called, the function will return the value of the interrupt
+ character and set the S-Lang global variable SLKeyBoard_Quit to a non-
+ zero value. In addition, if the default S-Lang interrupt handler has
+ been specified by a NULL argument to the SLang_set_abort_signal func-
+ tion, the global variable SLang_Error will be set to USER_BREAK unless
+ the variable SLang_Ignore_User_Abort is non-zero.
+
+ The SLang_getkey function waits until input is available to be read.
+ The SLang_input_pending function may be used to determine whether or
+ not input is ready. It takes a single parameter that indicates the
+ amount of time to wait for input before returning with information
+ regarding the availability of input. This parameter has units of one
+ tenth (1/10) of a second, i.e., to wait one second, the value of the
+ parameter should be 10. Passing a value of zero causes the function
+ to return right away. SLang_input_pending returns a positive integer
+ if input is available or zero if input is not available. It will
+ return -1 if an error occurs.
+
+ Here is a simple example that reads keys from the terminal until one
+ presses Ctrl-G or until 5 seconds have gone by with no input:
+
+
+
+ #include <stdio.h>
+ #include "slang.h"
+ int main ()
+ {
+ int abort_char = 7; /* For MSDOS, use 34 as scan code */
+ unsigned int ch;
+
+ if (-1 == SLang_init_tty (abort_char, 0, 1))
+ {
+ fprintf (stderr, "Unable to initialize the terminal.\n");
+ exit (-1);
+ }
+ SLang_set_abort_signal (NULL);
+ while (1)
+ {
+ fputs ("\nPress any key. To quit, press Ctrl-G: ", stdout);
+ fflush (stdout);
+ if (SLang_input_pending (50) == 0) /* 50/10 seconds */
+ {
+ fputs ("Waited too long! Bye\n", stdout);
+ break;
+ }
+
+ ch = SLang_getkey ();
+ if (SLang_Error == USER_BREAK)
+ {
+ fputs ("Ctrl-G pressed! Bye\n", stdout);
+ break;
+ }
+ putc ((int) ch, stdout);
+ }
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+ 4.6. Reading Keyboard Input with SLkp_getkey
+
+
+
+ Unlike the low-level function SLang_getkey, the SLkp_getkey function
+ can read a multi-character sequence associated with function keys.
+ The SLkp_getkey function uses SLang_getkey and S-Lang's keymap
+ facility to process escape sequences. It returns a single integer
+ which describes the key that was pressed:
+
+
+ int SLkp_getkey (void);
+
+
+
+ That is, the SLkp_getkey function simple provides a mapping between
+ keys and integers. In this context the integers are called keysyms.
+
+ For single character input such as generated by the a key on the
+ keyboard, the function returns the character that was generated, e.g.,
+ 'a'. For single characters, SLkp_getkey will always return an keysym
+ whose value ranges from 0 to 256. For keys that generate multiple
+ character sequences, e.g., a function or arrow key, the function
+ returns an keysym whose value is greater that 256. The actual values
+ of these keysyms are represented as macros defined in the slang.h
+ include file. For example, the up arrow key corresponds to the keysym
+ whose value is SL_KEY_UP.
+
+ Since it is possible for the user to enter a character sequence that
+ does not correspond to any key. If this happens, the special keysym
+ SL_KEY_ERR will be returned.
+
+ Here is an example of how SLkp_getkey may be used by a file viewer:
+
+
+ switch (SLkp_getkey ())
+ {
+ case ' ':
+ case SL_KEY_NPAGE:
+ next_page ();
+ break;
+ case 'b':
+ case SL_KEY_PPAGE:
+ previous_page ();
+ break;
+ case '\r':
+ case SL_KEY_DOWN:
+ next_line ();
+ break;
+ .
+ .
+ case SL_KEY_ERR:
+ default:
+ SLtt_beep ();
+ }
+
+
+
+ Unlike its lower-level counterpart, SLang_getkey, there do not yet
+ exist any functions in the library that are capable of ``ungetting''
+ keysyms. In particular, the SLang_ungetkey function will not work.
+
+
+
+ 4.7. Buffering Input
+
+
+
+ S-Lang has several functions pushing characters back onto the input
+ stream to be read again later by SLang_getkey. It should be noted
+ that none of the above functions are designed to push back keysyms
+ read by the SLkp_getkey function. These functions are declared as
+ follows:
+
+
+ void SLang_ungetkey (unsigned char ch);
+ void SLang_ungetkey_string (unsigned char *buf, int buflen);
+ void SLang_buffer_keystring (unsigned char *buf, int buflen);
+
+
+
+ SLang_ungetkey is the most simple of the three functions. It takes a
+ single character a pushes it back on to the input stream. The next
+ call to SLang_getkey will return this character. This function may be
+ used to peek at the character to be read by first reading it and then
+ putting it back.
+ SLang_ungetkey_string has the same function as SLang_ungetkey except
+ that it is able to push more than one character back onto the input
+ stream. Since this function can push back null (ascii 0) characters,
+ the number of characters to push is required as one of the parameters.
+
+ The last of these three functions, SLang_buffer_keystring can handle
+ more than one charater but unlike the other two, it places the
+ characters at the end of the keyboard buffer instead of at the
+ beginning.
+
+ Note that the use of each of these three functions will cause
+ SLang_input_pending to return right away with a non-zero value.
+
+ Finally, the S-Lang keyboard interface includes the function
+ SLang_flush_input with prototype
+
+
+ void SLang_flush_input (void);
+
+
+
+ It may be used to discard all input.
+
+ Here is a simple example that looks to see what the next key to be
+ read is if one is available:
+
+
+ int peek_key ()
+ {
+ int ch;
+ if (SLang_input_pending (0) == 0) return -1;
+ ch = SLang_getkey ();
+ SLang_ungetkey (ch);
+ return ch;
+ }
+
+
+
+ 4.8. Global Variables
+
+
+ Although the following S-Lang global variables have already been
+ mentioned earlier, they are gathered together here for completeness.
+
+ int SLang_Ignore_User_Abort; If non-zero, pressing the interrupt
+ character will not result in SLang_Error being set to USER_BREAK.
+
+ volatile int SLKeyBoard_Quit; This variable is set to a non-zero value
+ when the interrupt character is pressed. If the interrupt character is
+ pressed when SLang_getkey is called, the interrupt character will be
+ returned from SLang_getkey.
+
+ int SLang_TT_Baud_Rate; On systems which support it, this variable is
+ set to the value of the terminal's baud rate after the call to
+ SLang_init_tty.
+
+
+
+ 5. Screen Management
+
+
+
+ The S-Lang library provides two interfaces to terminal independent
+ routines for manipulating the display on a terminal. The highest
+ level interface, known as the SLsmg interface is discussed in this
+ section. It provides high level screen management functions more
+ manipulating the display in an optimal manner and is similar in spirit
+ to the curses library. The lowest level interface, or the SLtt
+ interface, is used by the SLsmg routines to actually perform the task
+ of writing to the display. This interface is discussed in another
+ section. Like the keyboard routines, the SLsmg routines are platform
+ independent and work the same on MSDOS, OS/2, Unix, and VMS.
+
+ The screen management, or SLsmg, routines are initialized by function
+ SLsmg_init_smg. Once initialized, the application uses various SLsmg
+ functions to write to a virtual display. This does not cause the
+ physical terminal display to be updated immediately. The physical
+ display is updated to look like the virtual display only after a call
+ to the function SLsmg_refresh. Before exiting, the application using
+ these routines is required to call SLsmg_reset_smg to reset the
+ display system.
+
+ The following subsections explore S-Lang's screen management system in
+ greater detail.
+
+
+ 5.1. Initialization
+
+
+ The function SLsmg_init_smg must be called before any other SLsmg
+ function can be used. It has the simple prototype:
+
+
+ int SLsmg_init_smg (void);
+
+
+
+ It returns zero if successful or -1 if it cannot allocate space for
+ the virtual display.
+
+ For this routine to properly initialize the virtual display, the
+ capabilities of the terminal must be known as well as the size of the
+ physical display. For these reasons, the lower level SLtt routines
+ come into play. In particular, before the first call to
+ SLsmg_init_smg, the application is required to call the function
+ SLtt_get_terminfo before calling SLsmg_init_smg.
+
+ The SLtt_get_terminfo function sets the global variables
+ SLtt_Screen_Rows and SLtt_Screen_Cols to the values appropriate for
+ the terminal. It does this by calling the SLtt_get_screen_size
+ function to query the terminal driver for the appropriate values for
+ these variables. From this point on, it is up to the application to
+ maintain the correct values for these variables by calling the
+ SLtt_get_screen_size function whenever the display size changes, e.g.,
+ in response to a SIGWINCH signal. Finally, if the application is going
+ to read characters from the keyboard, it is also a good idea to
+ initialize the keyboard routines at this point as well.
+
+
+ 5.2. Resetting SLsmg
+
+
+
+ Before the program exits or suspends, the function SLsmg_reset_tty
+ should be called to shutdown the display system. This function has
+ the prototype
+
+
+ void SLsmg_reset_smg (void);
+
+
+
+ This will deallocate any memory allocated for the virtual screen and
+ reset the terminal's display.
+
+ Basically, a program that uses the SLsmg screen management functions
+ and S-Lang's keyboard interface will look something like:
+
+
+ #include "slang.h"
+ int main ()
+ {
+ SLtt_get_terminfo ();
+ SLang_init_tty (-1, 0, 0);
+ SLsmg_init_smg ();
+
+ /* do stuff .... */
+
+ SLsmg_reset_smg ();
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+ If this program is compiled and run, all it will do is clear the
+ screen and position the cursor at the bottom of the display. In the
+ following sections, other SLsmg functions will be introduced which may
+ be used to make this simple program do much more.
+
+
+ 5.3. Handling Screen Resize Events
+
+ The function SLsmg_reinit_smg is designed to be used in conjunction
+ with resize events.
+
+ Under Unix-like operating systems, when the size of the display
+ changes, the application will be sent a SIGWINCH signal. To properly
+ handle this signal, the SLsmg routines must be reinitialized to use
+ the new display size. This may be accomplished by calling
+ SLtt_get_screen_size to get the new size, followed by SLsmg_reinit_smg
+ to reinitialize the SLsmg interface to use the new size. Keep in mind
+ that these routines should not be called from within the signal
+ handler. The following code illustrates the main ideas involved in
+ handling such events:
+
+
+
+ static volatile int Screen_Size_Changed;
+ static sigwinch_handler (int sig)
+ {
+ Screen_Size_Changed = 1;
+ SLsignal (SIGWINCH, sigwinch_handler);
+ }
+
+ int main (int argc, char **argv)
+ {
+ SLsignal (SIGWINCH, sigwinch_handler);
+ SLsmg_init_smg ();
+ .
+ .
+ /* Now enter main loop */
+ while (not_done)
+ {
+ if (Screen_Size_Changed)
+ {
+ SLtt_get_screen_size ();
+ SLsmg_reinit_smg ();
+ redraw_display ();
+ }
+ .
+ .
+ }
+ return 0;
+ }
+
+
+
+ 5.4. SLsmg Functions
+
+
+
+ In the previous sections, functions for initializing and shutting down
+ the SLsmg routines were discussed. In this section, the rest of the
+ SLsmg functions are presented. These functions act only on the
+ virtual display. The physical display is updated when the
+ SLsmg_refresh function is called and not until that time. This
+ function has the simple prototype:
+
+
+ void SLsmg_refresh (void);
+
+
+
+ 5.4.1. Positioning the cursor
+
+
+ The SLsmg_gotorc function is used to position the cursor at a given
+ row and column. The prototype for this function is:
+
+
+ void SLsmg_gotorc (int row, int col);
+
+
+
+ The origin of the screen is at the top left corner and is given the
+ coordinate (0, 0), i.e., the top row of the screen corresponds to row
+ = 0 and the first column corresponds to col = 0. The last row of the
+ screen is given by row = SLtt_Screen_Rows - 1.
+
+ It is possible to change the origin of the coordinate system by using
+ the function SLsmg_set_screen_start with prototype:
+
+
+ void SLsmg_set_screen_start (int *r, int *c);
+
+
+
+ This function takes pointers to the new values of the first row and
+ first column. It returns the previous values by modifying the values
+ of the integers at the addresses specified by the parameter list. A
+ NULL pointer may be passed to indicate that the origin is to be set to
+ its initial value of 0. For example,
+
+
+ int r = 10;
+ SLsmg_set_screen_start (&r, NULL);
+
+
+
+ sets the origin to (10, 0) and after the function returns, the vari-
+ able r will have the value of the previous row origin.
+
+
+ 5.4.2. Writing to the Display
+
+
+ SLsmg has several routines for outputting text to the virtual display.
+ The following points should be understood:
+
+ o The text is output at the position of the cursor of the virtual
+ display and the cursor is advanced to the position that corresponds
+ to the end of the text.
+
+
+ o Text does not wrap at the boundary of the display--- it is
+ trucated. This behavior seems to be more useful in practice since
+ most programs that would use screen management tend to be line
+ oriented.
+
+
+ o Control characters are displayed in a two character sequence
+ representation with ^ as the first character. That is, Ctrl-X is
+ output as ^X.
+
+
+ o The newline character does not cause the cursor to advance to the
+ next row. Instead, when a newline character is encountered when
+ outputting text, the output routine will return. That is,
+ outputting a string containing a newline character will only
+ display the contents of the string up to the newline character.
+
+
+ Although the some of the above items might appear to be too
+ restrictive, in practice this is not seem to be the case. In fact,
+ the design of the output routines was influenced by their actual use
+ and modified to simplify the code of the application utilizing them.
+
+ void SLsmg_write_char (char ch); Write a single character to the
+ virtual display.
+
+
+ void SLsmg_write_nchars (char *str, int len); Write len characters
+ pointed to by str to the virtual display.
+
+ void SLsmg_write_string (char *str); Write the null terminated string
+ given by pointer str to the virtual display. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_write_nstring (char *str, int n); Write the null terminated
+ string given by pointer str to the virtual display. At most, only n
+ characters are written. If the length of the string is less than n,
+ then the string will be padded with blanks. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_printf (char *fmt, ...); This function is similar to printf
+ except that it writes to the SLsmg virtual display.
+
+ void SLsmg_vprintf (char *, va_list); Like SLsmg_printf but uses a
+ variable argument list.
+
+
+ 5.4.3. Erasing the Display
+
+
+ The following functions may be used to fill portions of the display
+ with blank characters. The attributes of blank character are the
+ current attributes. (See below for a discussion of character
+ attributes)
+
+ void SLsmg_erase_eol (void); Erase line from current position to the
+ end of the line.
+
+ void SLsmg_erase_eos (void); Erase from the current position to the
+ end of the screen.
+
+ void SLsmg_cls (void); Clear the entire virtual display.
+
+
+ 5.4.4. Setting Character Attributes
+
+
+ Character attributes define the visual characteristics the character
+ possesses when it is displayed. Visual characteristics include the
+ foreground and background colors as well as other attributes such as
+ blinking, bold, and so on. Since SLsmg takes a different approach to
+ this problem than other screen management libraries an explanation of
+ this approach is given here. This approach has been motivated by
+ experience with programs that require some sort of screen management.
+
+ Most programs that use SLsmg are composed of specific textual objects
+ or objects made up of line drawing characters. For example, consider
+ an application with a menu bar with drop down menus. The menus might
+ be enclosed by some sort of frame or perhaps a shadow. The basic idea
+ is to associate an integer to each of the objects (e.g., menu bar,
+ shadow, current menu item, etc.) and create a mapping from the integer
+ to the set of attributes. In the terminology of SLsmg, the integer is
+ simply called an object.
+
+ For example, the menu bar might be associated with the object 1, the
+ drop down menu could be object 2, the shadow could be object 3, and so
+ on.
+
+ The range of values for the object integer is restricted from 0 up to
+ and including 255 on all systems except MSDOS where the maximum
+ allowed integer is 15 (-- This difference is due to memory constraints
+ imposed by MSDOS. This restriction might be removed in a future
+ version of the library.--) . The object numbered zero should not be
+ regarding as an object at all. Rather it should be regarded as all
+ other objects that have not explicitly been given an object number.
+ SLsmg, or more precisely SLtt, refers to the attributes of this
+ special object as the default or normal attributes.
+
+ The SLsmg routines know nothing about the mapping of the color to the
+ attributes associated with the color. The actual mapping takes place
+ at a lower level in the SLtt routines. Hence, to map an object to the
+ actual set of attributes requires a call to any of the following SLtt
+ routines:
+
+
+ void SLtt_set_color (int obj, char *name, char *fg, char *bg);
+ void SLtt_set_color_object (int obj, SLtt_Char_Type attr);
+ void SLtt_set_mono (int obj, char *, SLtt_Char_Type attr);
+
+
+
+ Only the first of these routines will be discussed briefly here. The
+ latter two functions allow more fine control over the object to
+ attribute mapping (such as assigning a ``blink'' attribute to the
+ object). For a more full explanation on all of these routines see the
+ section about the SLtt interface.
+
+ The SLtt_set_color function takes four parameters. The first
+ parameter, obj, is simply the integer of the object for which
+ attributes are to be assigned. The second parameter is currently
+ unused by these routines. The third and forth parameters, fg and bg,
+ are the names of the foreground and background color to be used
+ associated with the object. The strings that one can use for the
+ third and fourth parameters can be any one of the 16 colors:
+
+
+ "black" "gray"
+ "red" "brightred"
+ "green" "brightgreen"
+ "brown" "yellow"
+ "blue" "brightblue"
+ "magenta" "brightmagenta"
+ "cyan" "brightcyan"
+ "lightgray" "white"
+
+
+
+ The value of the foreground parameter fg can be anyone of these six-
+ teen colors. However, on most terminals, the background color will
+ can only be one of the colors listed in the first column (-- This is
+ also true on the Linux console. However, it need not be the case and
+ hopefully the designers of Linux will someday remove this restric-
+ tion.--) .
+
+ Of course not all terminals are color terminals. If the S-Lang global
+ variable SLtt_Use_Ansi_Colors is non-zero, the terminal is assumed to
+ be a color terminal. The SLtt_get_terminfo will try to determine
+ whether or not the terminal supports colors and set this variable
+ accordingly. It does this by looking for the capability in the
+ terminfo/termcap database. Unfortunately many Unix databases lack
+ this information and so the SLtt_get_terminfo routine will check
+ whether or not the environment variable COLORTERM exists. If it
+ exists, the terminal will be assumed to support ANSI colors and
+ SLtt_Use_Ansi_Colors will be set to one. Nevertheless, the
+ application should provide some other mechanism to set this variable,
+ e.g., via a command line parameter.
+
+ When the SLtt_Use_Ansi_Colors variable is zero, all objects with
+ numbers greater than one will be displayed in inverse video (-- This
+ behavior can be modified by using the SLtt_set_mono function call.--)
+ .
+
+ With this background, the SLsmg functions for setting the character
+ attributes can now be defined. These functions simply set the object
+ attributes that are to be assigned to subsequent characters written to
+ the virtual display. For this reason, the new attribute is called the
+ current attribute.
+
+ void SLsmg_set_color (int obj); Set the current attribute to those of
+ object obj.
+
+ void SLsmg_normal_video (void); This function is equivalent to
+ SLsmg_set_color (0).
+
+ void SLsmg_reverse_video (void); This function is equivalent to
+ SLsmg_set_color (1). On monochrome terminals, it is equivalent to
+ setting the subsequent character attributes to inverse video.
+
+ Unfortunately there does not seem to be a standard way for the
+ application or, in particular, the library to determine which color
+ will be used by the terminal for the default background. Such
+ information would be useful in initializing the foreground and
+ background colors associated with the default color object (0). FOr
+ this reason, it is up to the application to provide some means for the
+ user to indicate what these colors are for the particular terminal
+ setup. To facilitate this, the SLtt_get_terminfo function checks for
+ the existence of the COLORFGBG environment variable. If this variable
+ exists, its value will be used to initialize the colors associated
+ with the default color object. Specifically, the value is assumed to
+ consist of a foreground color name and a background color name
+ separated by a semicolon. For example, if the value of COLORTERM is
+ lightgray;blue, the default color object will be initialized to
+ represent a lightgray foreground upon a blue background.
+
+
+ 5.4.5. Lines and Alternate Character Sets
+
+ The S-Lang screen management library also includes routines for
+ turning on and turning off alternate character sets. This is
+ especially useful for drawing horizontal and vertical lines.
+
+ void SLsmg_set_char_set (int flag); If flag is non-zero, subsequent
+ write functions will use characters from the alternate character set.
+ If flag is zero, the default, or, ordinary character set will be used.
+
+ void SLsmg_draw_hline (int len); Draw a horizontal line from the
+ current position to the column that is len characters to the right.
+
+ void SLsmg_draw_vline (int len); Draw a horizontal line from the
+ current position to the row that is len rows below.
+
+ void SLsmg_draw_box (int r, int c, int dr, int dc); Draw a box whose
+ upper right corner is at row r and column c. The box spans dr rows
+ and dc columns. The current position will be left at row r and column
+ c.
+
+
+ 5.4.6. Miscellaneous Functions
+
+
+ void SLsmg_touch_lines (int r, int n); Mark screen rows numbered r, r
+ + 1, ... r + (n - 1) as modified. When SLsmg_refresh is called, these
+ rows will be completely redrawn.
+ unsigned short SLsmg_char_at(void); Returns the character and its
+ attributes object number at the current cursor position. The
+ character itself occupies the lower byte and the object attributes
+ number forms the upper byte. The object returned by this function
+ call should not be written back out via any of the functions that
+ write characters or character strings.
+
+
+
+ 5.5. Variables
+
+
+
+ The following S-Lang global variables are used by the SLsmg interface.
+ Some of these have been previously discussed.
+
+ int SLtt_Screen_Rows; int SLtt_Screen_Cols; The number of rows and
+ columns of the physical display. If either of these numbers changes,
+ the functions SLsmg_reset_smg and SLsmg_init_smg should be called
+ again so that the SLsmg routines can re-adjust to the new size.
+
+ int SLsmg_Tab_Width; Set this variable to the tab width that will be
+ used when expanding tab characters. The default is 8.
+
+ int SLsmg_Display_Eight_Bit This variable determines how characters
+ with the high bit set are to be output. Specifically, a character
+ with the high bit set with a value greater than or equal to this value
+ is output as is; otherwise, it will be output in a 7-bit
+ representation. The default value for this variable is 128 for MSDOS
+ and 160 for other systems (ISO-Latin).
+
+ int SLtt_Use_Ansi_Colors; If this value is non-zero, the terminal is
+ assumed to support ANSI colors otherwise it is assumed to be
+ monochrome. The default is 0.
+
+ int SLtt_Term_Cannot_Scroll; If this value is zero, the SLsmg will
+ attempt to scroll the physical display to optimize the update. If it
+ is non-zero, the screen management routines will not perform this
+ optimization. For some applications, this variable should be set to
+ zero. The default value is set by the SLtt_get_terminfo function.
+
+
+
+ 5.6. Hints for using SLsmg
+
+
+ This section discusses some general design issues that one must face
+ when writing an application that requires some sort of screen
+ management.
+
+
+
+ 6. Signal Functions
+
+
+
+ Almost all non-trivial programs must worry about signals. This is
+ especially true for programs that use the S-Lang terminal input/output
+ and screen management routines. Unfortunately, there is no fixed way
+ to handle signals; otherwise, the Unix kernel would take care of all
+ issues regarding signals and the application programmer would never
+ have to worry about them. For this reason, none of the routines in
+ the S-Lang library catch signals; however, some of the routines block
+ the delivery of signals during crucial moments. It is up to the
+ application programmer to install handlers for the various signals of
+ interest.
+
+ For the interpreter, the most important signal to worry about is
+ SIGINT. This signal is usually generated when the user presses Ctrl-C
+ at the keyboard. The interpreter checks the value of the SLang_Error
+ variable to determine whether or not it should abort the interpreting
+ process and return control back to the application. This means that
+ if SIGINT is to be used to abort the interpreter, a signal handler for
+ SIGINT should be installed. The handler should set the value of
+ SLang_Error to SL_USER_BREAK.
+
+ Applications that use the tty getkey routines or the screen management
+ routines must worry about signals such as:
+
+
+ SIGINT interrupt
+ SIGTSTP stop
+ SIGQUIT quit
+ SIGTTOU background write
+ SIGTTIN background read
+ SIGWINCH window resize
+
+
+
+ It is important that handlers be established for these signals while
+ the either the SLsmg routines or the getkey routines are initialized.
+ The SLang_init_tty, SLang_reset_tty, SLsmg_init_smg, and
+ SLsmg_reset_smg functions block these signals from occuring while they
+ are being called.
+
+ Since a signal can be delivered at any time, it is important for the
+ signal handler to call only functions that can be called from a signal
+ handler. This usually means that such function must be re-entrant. In
+ particular, the SLsmg routines are not re-entrant; hence, they should
+ not be called when a signal is being processed unless the application
+ can ensure that the signal was not delivered while an SLsmg function
+ was called. This statement applies to many other functions such as
+ malloc, or, more generally, any function that calls malloc. The
+ upshot is that the signal handler should not attempt to do too much
+ except set a global variable for the application to look at while not
+ in a signal handler.
+
+ The S-Lang library provides two functions for blocking and unblocking
+ the above signals:
+
+
+ int SLsig_block_signals (void);
+ int SLsig_unblock_signals (void);
+
+
+
+ It should be noted that for every call to SLsig_block_signals, a cor-
+ responding call should be made to SLsig_unblock_signals, e.g.,
+
+
+ void update_screen ()
+ {
+ SLsig_block_signals ();
+
+ /* Call SLsmg functions */
+ .
+ .
+ SLsig_unblock_signals ();
+ }
+
+
+
+ See demo/pager.c for examples.
+
+
+
+ 7. Searching Functions
+
+
+
+ The S-Lang library incorporates two types of searches: Regular
+ expression pattern matching and ordinary searching.
+
+
+ 7.1. Regular Expressions
+
+
+
+ !!! No documentation available yet !!!
+
+
+
+ 7.2. Simple Searches
+
+
+ The routines for ordinary searching are defined in the slsearch.c
+ file. To use these routines, simply include "slang.h" in your program
+ and simply call the appropriate routines.
+
+ The searches can go in either a forward or backward direction and can
+ either be case or case insensitive. The region that is searched may
+ contain null characters (ASCII 0) however, the search string cannot in
+ the current implementation. In addition the length of the string to
+ be found is currently limited to 256 characters.
+
+ Before searching, the function SLsearch_init must first be called to
+ `preprocess' the search string.
+
+
+
+ 7.3. Initialization
+
+
+ The function SLsearch_init must be called before a search can take
+ place. Its prototype is:
+
+
+ int SLsearch_init (char *key, int dir, int case_sens, SLsearch_Type *st);
+
+
+
+ Here key is the string to be searched for. dir specifies the direc-
+ tion of the search: a value greater than zero is used for searching
+ forward and a value less than zero is used for searching backward.
+ The parameter case_sens specifies whether the search is case sensitive
+ or not. A non-zero value indicates that case is important. st is a
+ pointer to a structure of type SLsearch_Type defined in "slang.h".
+ This structure is initialized by this routine and must be passed to
+ SLsearch when the search is actually performed.
+
+ This routine returns the length of the string to be searched for.
+
+
+
+ 7.4. SLsearch
+
+
+
+ Prototype: unsigned char *SLsearch (unsigned char *pmin,
+ unsigned char *pmax,
+ SLsearch_Type *st);
+
+
+
+ This function performs the search defined by a previous call to
+ SLsearch_init over a region specified by the pointers pmin and pmax.
+
+ It returns a pointer to the start of the match if successful or it
+ will return NULL if a match was not found.
+
+
+
+ A. Copyright
+
+ The S-Lang library is distributed under two copyrights: the GNU Genral
+ Public License, and the Artistic License. Any program that uses the
+ interpreter must adhere to rules of one of these licenses.
+
+
+ A.1. The GNU Public License
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License
+ is intended to guarantee your freedom to share and change free soft-
+ ware--to make sure the software is free for all its users. This Gen-
+ eral Public License applies to most of the Free Software Foundation's
+ software and to any other program whose authors commit to using it.
+ (Some other Free Software Foundation software is covered by the GNU
+ Library General Public License instead.) You can apply it to your
+ programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if
+ you distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on,
+ we want its recipients to know that what they have is not the
+ original, so that any problems introduced by others will not reflect
+ on the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at
+ all.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term "modification".) Each licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether
+ that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a
+ fee.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above,
+ provided that you also meet all of these conditions:
+
+
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+
+ These requirements apply to the modified work as a whole. If identi-
+ fiable sections of that work are not derived from the Program, and can
+ be reasonably considered independent and separate works in themselves,
+ then this License, and its terms, do not apply to those sections when
+ you distribute them as separate works. But when you distribute the
+ same sections as part of a whole which is a work based on the Program,
+ the distribution of the whole must be on the terms of this License,
+ whose permissions for other licensees extend to the entire whole, and
+ thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to con-
+ trol compilation and installation of the executable. However, as a
+ special exception, the source code distributed need not include any-
+ thing that is normally distributed (in either source or binary form)
+ with the major components (compiler, kernel, and so on) of the operat-
+ ing system on which the executable runs, unless that component itself
+ accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded. In such case, this License incorporates
+ the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and
+ "any later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a
+ version number of this License, you may choose any version ever
+ published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by
+ the Free Software Foundation, write to the Free Software Foundation;
+ we sometimes make exceptions for this. Our decision will be guided by
+ the two goals of preserving the free status of all derivatives of our
+ free software and of promoting the sharing and reuse of software
+ generally.
+
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+
+
+ The hypothetical commands `show w' and `show c' should show the appro-
+ priate parts of the General Public License. Of course, the commands
+ you use may be called something other than `show w' and `show c'; they
+ could even be mouse-clicks or menu items--whatever suits your program.
+
+ You should also get your employer (if you work as a programmer) or
+ your school, if any, to sign a "copyright disclaimer" for the program,
+ if necessary. Here is a sample; alter the names:
+
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+
+
+ This General Public License does not permit incorporating your program
+ into proprietary programs. If your program is a subroutine library,
+ you may consider it more useful to permit linking proprietary applica-
+ tions with the library. If this is what you want to do, use the GNU
+ Library General Public License instead of this License.
+
+
+ A.2. The Artistic License
+
+
+
+ The "Artistic License"
+
+ Preamble
+
+
+
+ The intent of this document is to state the conditions under which a
+ Package may be copied, such that the Copyright Holder maintains some
+ semblance of artistic control over the development of the package,
+ while giving the users of the package the right to use and distribute
+ the Package in a more-or-less customary fashion, plus the right to
+ make reasonable modifications.
+
+ Definitions:
+
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+
+
+ 1. You may make and give away verbatim copies of the source form of
+ the Standard Version of this Package without restriction, provided
+ that you duplicate all of the original copyright notices and associ-
+ ated disclaimers.
+
+ 2. You may apply bug fixes, portability fixes and other modifications
+ derived from the Public Domain or from the Copyright Holder. A
+ Package modified in such a way shall still be considered the Standard
+ Version.
+
+ 3. You may otherwise modify your copy of this Package in any way,
+ provided that you insert a prominent notice in each changed file
+ stating how and when you changed that file, and provided that you do
+ at least ONE of the following:
+
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+ 4. You may distribute the programs of this Package in object code or
+ executable form, provided that you do at least ONE of the following:
+
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+ 5. You may charge a reasonable copying fee for any distribution of
+ this Package. You may charge any fee you choose for support of this
+ Package. You may not charge a fee for this Package itself. However,
+ you may distribute this Package in aggregate with other (possibly com-
+ mercial) programs as part of a larger (possibly commercial) software
+ distribution provided that you do not advertise this Package as a
+ product of your own. You may embed this Package's interpreter within
+ an executable of yours (by linking); this shall be construed as a mere
+ form of aggregation, provided that the complete Standard Version of
+ the interpreter is so embedded.
+
+ 6. The scripts and library files supplied as input to or produced as
+ output from the programs of this Package do not automatically fall
+ under the copyright of this Package, but belong to whomever generated
+ them, and may be sold commercially, and may be aggregated with this
+ Package. If such scripts or library files are aggregated with this
+ Package via the so-called "undump" or "unexec" methods of producing a
+ binary executable image, then distribution of such an image shall
+ neither be construed as a distribution of this Package nor shall it
+ fall under the restrictions of Paragraphs 3 and 4, provided that you
+ do not represent such an executable image as a Standard Version of
+ this Package.
+ 7. C subroutines (or comparably compiled subroutines in other
+ languages) supplied by you and linked into this Package in order to
+ emulate subroutines and variables of the language defined by this
+ Package shall not be considered part of this Package, but are the
+ equivalent of input as in Paragraph 6, provided these subroutines do
+ not change the language in any way that would cause it to fail the
+ regression tests for the language.
+
+ 8. Aggregation of this Package with a commercial distribution is
+ always permitted provided that the use of this Package is embedded;
+ that is, when no overt attempt is made to make this Package's
+ interfaces visible to the end user of the commercial distribution.
+ Such use shall not be construed as a distribution of this Package.
+
+ 9. The name of the Copyright Holder may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+ Table of Contents
+
+
+ 1. Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 1.1. A Brief History of S-Lang . . . . . . . . . . . . . . . . . . 2
+ 1.2. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 2
+ 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 3. Interpreter Interface . . . . . . . . . . . . . . . . . . . . . 5
+ 3.1. Embedding the Interpreter . . . . . . . . . . . . . . . . . . 5
+ 3.2. Calling the Interpreter . . . . . . . . . . . . . . . . . . . 6
+ 3.2.1. Loading Files . . . . . . . . . . . . . . . . . . . . . . . 6
+ 3.2.2. Loading Strings . . . . . . . . . . . . . . . . . . . . . . 7
+ 3.3. Intrinsic Functions . . . . . . . . . . . . . . . . . . . . . 7
+ 3.3.1. Restrictions on Intrinsic Functions . . . . . . . . . . . . 8
+ 3.3.2. Adding a New Intrinsic . . . . . . . . . . . . . . . . . . 9
+ 3.3.3. More Complicated Intrinsics . . . . . . . . . . . . . . . . 11
+ 3.4. Intrinsic Variables . . . . . . . . . . . . . . . . . . . . . 13
+ 3.5. Aggregate Data Objects . . . . . . . . . . . . . . . . . . . 15
+ 3.5.1. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 16
+ 3.5.2. Structures . . . . . . . . . . . . . . . . . . . . . . . . 18
+ 3.5.2.1. Interpreter Structures . . . . . . . . . . . . . . . . . 18
+ 3.5.2.2. Intrinsic Structures . . . . . . . . . . . . . . . . . . 22
+ 4. Keyboard Interface . . . . . . . . . . . . . . . . . . . . . . 24
+ 4.1. Initializing the Keyboard Interface . . . . . . . . . . . . . 24
+ 4.2. Resetting the Keyboard Interface . . . . . . . . . . . . . . 25
+ 4.3. Initializing the SLkp Routines . . . . . . . . . . . . . . . 25
+ 4.4. Setting the Interrupt Handler . . . . . . . . . . . . . . . . 26
+ 4.5. Reading Keyboard Input with SLang_getkey . . . . . . . . . . 27
+ 4.6. Reading Keyboard Input with SLkp_getkey . . . . . . . . . . . 28
+ 4.7. Buffering Input . . . . . . . . . . . . . . . . . . . . . . . 29
+ 4.8. Global Variables . . . . . . . . . . . . . . . . . . . . . . 30
+ 5. Screen Management . . . . . . . . . . . . . . . . . . . . . . . 31
+ 5.1. Initialization . . . . . . . . . . . . . . . . . . . . . . . 31
+ 5.2. Resetting SLsmg . . . . . . . . . . . . . . . . . . . . . . . 31
+ 5.3. Handling Screen Resize Events . . . . . . . . . . . . . . . . 32
+ 5.4. SLsmg Functions . . . . . . . . . . . . . . . . . . . . . . . 33
+ 5.4.1. Positioning the cursor . . . . . . . . . . . . . . . . . . 33
+ 5.4.2. Writing to the Display . . . . . . . . . . . . . . . . . . 34
+ 5.4.3. Erasing the Display . . . . . . . . . . . . . . . . . . . . 35
+ 5.4.4. Setting Character Attributes . . . . . . . . . . . . . . . 35
+ 5.4.5. Lines and Alternate Character Sets . . . . . . . . . . . . 37
+ 5.4.6. Miscellaneous Functions . . . . . . . . . . . . . . . . . . 37
+ 5.5. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 38
+ 5.6. Hints for using SLsmg . . . . . . . . . . . . . . . . . . . . 38
+ 6. Signal Functions . . . . . . . . . . . . . . . . . . . . . . . 39
+ 7. Searching Functions . . . . . . . . . . . . . . . . . . . . . . 41
+ 7.1. Regular Expressions . . . . . . . . . . . . . . . . . . . . . 41
+ 7.2. Simple Searches . . . . . . . . . . . . . . . . . . . . . . . 41
+ 7.3. Initialization . . . . . . . . . . . . . . . . . . . . . . . 41
+ 7.4. SLsearch . . . . . . . . . . . . . . . . . . . . . . . . . . 41
+ A. Copyright . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
+ A.1. The GNU Public License . . . . . . . . . . . . . . . . . . . 43
+ A.2. The Artistic License . . . . . . . . . . . . . . . . . . . . 49
+
+
+
diff --git a/libslang/doc/text/slang.txt b/libslang/doc/text/slang.txt
new file mode 100644
index 0000000..6867293
--- /dev/null
+++ b/libslang/doc/text/slang.txt
@@ -0,0 +1,5642 @@
+ A Guide to the S-Lang Language
+ John E. Davis, davis@space.mit.edu
+ Mar 23, 2003
+ ____________________________________________________________
+
+ Table of Contents
+
+
+
+ Preface
+
+ 1. A Brief History of S-Lang
+ 2. Acknowledgements
+ 2. Introduction
+ 3. Language Features
+ 4. Data Types and Operators
+ 5. Statements and Functions
+ 6. Error Handling
+ 7. Run-Time Library
+ 8. Input/Output
+ 9. Obtaining S-Lang
+ 9. Overview of the Language
+ 10. Variables and Functions
+ 11. Strings
+ 12. Referencing and Dereferencing
+ 13. Arrays
+ 14. Structures and User-Defined Types
+ 15. Namespaces
+ 15. Data Types and Literal Constants
+ 16. Predefined Data Types
+ 16.1 Integers
+ 16.2 Floating Point Numbers
+ 16.3 Complex Numbers
+ 16.4 Strings
+ 16.5 Null_Type
+ 16.6 Ref_Type
+ 16.7 Array_Type and Struct_Type
+ 16.8 DataType_Type Type
+
+ 17. Typecasting: Converting from one Type to Another
+
+ 17. Identifiers
+
+ 17. Variables
+
+ 17. Operators
+ 18. Unary Operators
+ 19. Binary Operators
+ 19.1 Arithmetic Operators
+ 19.2 Relational Operators
+ 19.3 Boolean Operators
+ 19.4 Bitwise Operators
+ 19.5 Namespace operator
+ 19.6 Operator Precedence
+ 19.7 Binary Operators and Functions Returning Multiple Values
+
+ 20. Mixing Integer and Floating Point Arithmetic
+ 21. Short Circuit Boolean Evaluation
+ 21. Statements
+ 22. Variable Declaration Statements
+ 23. Assignment Statements
+ 24. Conditional and Looping Statements
+ 24.1 Conditional Forms
+ 24.1.1 if
+ 24.1.2 if-else
+ 24.1.3 !if
+ 24.1.4 orelse, andelse
+ 24.1.5 switch
+ 24.2 Looping Forms
+ 24.2.1 while
+ 24.2.2 do...while
+ 24.2.3 for
+ 24.2.4 loop
+ 24.2.5 for
+ 24.2.6 forever
+ 24.2.7 foreach
+
+ 25. break, return, continue
+
+ 25. Functions
+ 26. Declaring Functions
+ 27. Parameter Passing Mechanism
+ 28. Referencing Variables
+ 29. Functions with a Variable Number of Arguments
+ 30. Returning Values
+ 31. Multiple Assignment Statement
+ 32. Exit-Blocks
+ 32. Name Spaces
+ 32. Arrays
+ 33. Creating Arrays
+ 33.1 Range Arrays
+ 33.2 Creating arrays via the dereference operator
+
+ 34. Reshaping Arrays
+ 35. Indexing Arrays
+ 36. Arrays and Variables
+ 37. Using Arrays in Computations
+ 37. Associative Arrays
+ 37. Structures and User-Defined Types
+ 38. Defining a Structure
+ 39. Accessing the Fields of a Structure
+ 40. Linked Lists
+ 41. Defining New Types
+ 41. Error Handling
+ 42. Error-Blocks
+ 43. Clearing Errors
+ 43. Loading Files: evalfile and autoload
+ 43. File Input/Output
+ 44. Input/Output via stdio
+ 44.1 Stdio Overview
+ 44.2 Stdio Examples
+
+ 45. POSIX I/O
+ 46. Advanced I/O techniques
+ 46.1 Example: Reading /var/log/wtmp
+ 46.1 Debugging
+ 46.1 Regular Expressions
+
+ 47. S-Lang RE Syntax
+ 48. Differences between S-Lang and egrep REs
+ 48. Future Directions
+ 48. Copyright
+ A. The GNU Public License
+ B. The Artistic License
+
+
+ ______________________________________________________________________
+
+
+
+ 1. Preface
+
+
+
+ S-Lang is an interpreted language that was designed from the start to
+ be easily embedded into a program to provide it with a powerful
+ extension language. Examples of programs that use S-Lang as an
+ extension language include the jed text editor, the slrn newsreader,
+ and sldxe (unreleased), a numerical computation program. For this
+ reason, S-Lang does not exist as a separate application and many of
+ the examples in this document are presented in the context of one of
+ the above applications.
+
+ S-Lang is also a programmer's library that permits a programmer to
+ develop sophisticated platform-independent software. In addition to
+ providing the S-Lang extension language, the library provides
+ facilities for screen management, keymaps, low-level terminal I/O,
+ etc. However, this document is concerned only with the extension
+ language and does not address these other features of the S-Lang
+ library. For information about the other components of the library,
+ the reader is referred to the The S-Lang Library Reference.
+
+
+ 1.1. A Brief History of S-Lang
+
+
+
+ I first began working on S-Lang sometime during the fall of 1992. At
+ that time I was writing a text editor (jed), which I wanted to endow
+ with a macro language. It occured to me that an application-
+ independent language that could be embedded into the editor would
+ prove more useful because I could envision embedding it into other
+ programs. As a result, S-Lang was born.
+
+ S-Lang was originally a stack language that supported a postscript-
+ like syntax. For that reason, I named it S-Lang, where the S was
+ supposed to emphasize its stack-based nature. About a year later, I
+ began to work on a preparser that would allow one to write using a
+ more traditional infix syntax making it easier to use for those
+ unfamiliar with stack based languages. Currently, the syntax of the
+ language resembles C, nevertheless some postscript-like features still
+ remain, e.g., the `%' character is still used as a comment delimiter.
+
+
+
+ 1.2. Acknowledgements
+
+
+
+ Since I first released S-Lang, I have received a lot feedback about
+ the library and the language from many people. This has given me the
+ opportunity and pleasure to interact with several people to make the
+ library portable and easy to use. In particular, I would like to
+ thank the following individuals:
+
+ Luchesar Ionkov <lionkov@sf.cit.bg> for his comments and criticisms of
+ the syntax of the language. He was the person who made me realize
+ that the low-level byte-code engine should be totally type-
+ independent. He also improved the tokenizer and preparser and
+ impressed upon me that the language needed a grammar.
+
+ Mark Olesen <olesen@weber.me.queensu.ca> for his many patches to
+ various aspects of the library and his support on AIX. He also
+ contributed a lot to the pre-processing (SLprep) routines.
+
+ John Burnell <j.burnell@irl.cri.nz> for the OS/2 port of the video and
+ keyboard routines. He also made value suggestions regarding the
+ interpreter interface.
+
+ Darrel Hankerson <hankedr@mail.auburn.edu> for cleaning up and
+ unifying some of the code and the makefiles.
+
+ Dominik Wujastyk <ucgadkw@ucl.ac.uk> who was always willing to test
+ new releases of the library.
+
+ Michael Elkins <me@muddcs.cs.hmc.edu> for his work on the curses
+ emulation.
+
+ Ulli Horlacher <framstag@belwue.de> and Oezguer Kesim <kesim@math.fu-
+ berlin.de> for the S-Lang newsgroup and mailing list.
+
+ Hunter Goatley, Andy Harper <Andy.Harper@kcl.ac.uk>, and Martin P.J.
+ Zinser <zinser@decus.decus.de> for their VMS support.
+
+ Dave Sims <sims@usa.acsys.com> and Chin Huang <cthuang@vex.net> for
+ Windows 95 and Windows NT support.
+
+ Lloyd Zusman <ljz@asfast.com> and Rich Roth <rich@on-the-net.com> for
+ creating and maintaining www.s-lang.org.
+
+ I am also grateful to many other people who send in bug-reports and
+ bug-fixes, for without such community involvement, S-Lang would not be
+ as well-tested and stable as it is. Finally, I would like to thank my
+ wife for her support and understanding while I spent long weekend
+ hours developing the library.
+
+
+
+ 2. Introduction
+
+
+
+ S-Lang is a powerful interpreted language that may be embedded into an
+ application to make the application extensible. This enables the
+ application to be used in ways not envisioned by the programmer, thus
+ providing the application with much more flexibility and power.
+ Examples of applications that take advantage of the interpreter in
+ this way include the jed editor and the slrn newsreader.
+
+
+ 2.1. Language Features
+
+
+ The language features both global and local variables, branching and
+ looping constructs, user-defined functions, structures, datatypes, and
+ arrays. In addition, there is limited support for pointer types. The
+ concise array syntax rivals that of commercial array-based numerical
+ computing environments.
+
+
+ 2.2. Data Types and Operators
+
+
+
+ The language provides built-in support for string, integer (signed and
+ unsigned long and short), double precision floating point, and double
+ precision complex numbers. In addition, it supports user defined
+ structure types, multi-dimensional array types, and associative
+ arrays. To facilitate the construction of sophisticated data
+ structures such as linked lists and trees, a `reference' type was
+ added to the language. The reference type provides much of the same
+ flexibility as pointers in other languages. Finally, applications
+ embedding the interpreter may also provide special application
+ specific types, such as the Mark_Type that the jed editor provides.
+
+ The language provides standard arithmetic operations such as addition,
+ subtraction, multiplication, and division. It also provides support
+ for modulo arithmetic as well as operations at the bit level, e.g.,
+ exclusive-or. Any binary or unary operator may be extended to work
+ with any data type. For example, the addition operator (+) has been
+ extended to work between string types to permit string concatenation.
+
+ The binary and unary operators work transparently with array types.
+ For example, if a and b are arrays, then a + b produces an array whose
+ elements are the result of element by element addition of a and b.
+ This permits one to do vector operations without explicitly looping
+ over the array indices.
+
+
+
+ 2.3. Statements and Functions
+
+
+
+ The S-Lang language supports several types of looping constructs and
+ conditional statements. The looping constructs include while,
+ do...while, for, forever, loop, foreach, and _for. The conditional
+ statements include if, if-then-else, and !if.
+
+ User defined functions may be defined to return zero, one, or more
+ values. Functions that return zero values are similar to `procedures'
+ in languages such as PASCAL. The local variables of a function are
+ always created on a stack allowing one to create recursive functions.
+ Parameters to a function are always passed by value and never by
+ reference. However, the language supports a reference data type that
+ allows one to simulate pass by reference.
+
+ Unlike many interpreted languages, S-Lang allows functions to be
+ dynamically loaded (function autoloading). It also provides
+ constructs specifically designed for error handling and recovery as
+ well as debugging aids (e.g., function tracebacks).
+
+ Functions and variables may be declared as private belonging to a
+ namespace associated with the compilation unit that defines the
+ function or variable. The ideas behind the namespace implementation
+ stems from the C language and should be quite familiar to any one
+ familiar with C.
+
+
+
+ 2.4. Error Handling
+
+
+
+ The S-Lang language defines a construct called an error-block that may
+ be used for error handling and recovery. When a non-fatal run-time
+ error is encountered, any error blocks that have been defined are
+ executed as the run-time stack unwinds. An error block can optionally
+ clear the error and the program will continue running after the
+ statement that triggered the error. This mechanism is somewhat
+ similar to try-catch in C++.
+
+
+
+ 2.5. Run-Time Library
+
+
+
+ Functions that compose the S-Lang run-time library are called
+ intrinsics. Examples of S-Lang intrinsic functions available to every
+ S-Lang application include string manipulation functions such as
+ strcat, strchop, and strcmp. The S-Lang library also provides
+ mathematical functions such as sin, cos, and tan; however, not all
+ applications enable the use of these intrinsics. For example, to
+ conserve memory, the 16 bit version of the jed editor does not provide
+ support for any mathematics other than simple integer arithmetic,
+ whereas other versions of the editor do support these functions.
+
+ Most applications embedding the languages will also provide a set of
+ application specific intrinsic functions. For example, the jed editor
+ adds over 100 application specific intrinsic functions to the
+ language. Consult your application specific documentation to see what
+ additional intrinsics are supported.
+
+
+
+ 2.6. Input/Output
+
+
+ The language supports C-like stdio input/output functions such as
+ fopen, fgets, fputs, and fclose. In addition it provides two
+ functions, message and error, for writing to the standard output
+ device and standard error. Specific applications may provide other
+ I/O mechanisms, e.g., the jed editor supports I/O to files via the
+ editor's buffers.
+
+ 2.7. Obtaining S-Lang
+
+
+
+ Comprehensive information about the library may be obtained via the
+ World Wide Web from http://www.s-lang.org.
+
+ S-Lang as well as some programs that embed it are freely available via
+ anonymous ftp in the United States from
+
+ o ftp://space.mit.edu/pub/davis.
+
+ It is also available outside the United States from the following
+ mirror sites:
+
+ o ftp://ftp.uni-stuttgart.de/pub/unix/misc/slang/
+
+ o ftp://ftp.fu-berlin.de/pub/unix/news/slrn/
+
+ o ftp://ftp.ntua.gr/pub/lang/slang/
+
+ The Usenet newsgroup alt.lang.s-lang was created for S-Lang
+ programmers to exchange information and share macros for the various
+ programs the embed the language. The newsgroup comp.editors can be a
+ useful resource for S-Lang macros for the jed editor. Similarly, slrn
+ users will find news.software.readers to be a valuable source of
+ information.
+
+ Finally, two mailing lists dealing with the S-Lang library have been
+ created:
+
+ o slang-announce@babayaga.math.fu-berlin.de
+
+ o slang-workers@babayaga.math.fu-berlin.de
+
+ The first list is for announcements of new releases of the library,
+ while the second list is intended for those who use the library for
+ their own code development. To subscribe to the announcement list,
+ send an email to slang-announce-subscribe@babayaga.math.fu-
+ berlin.de and include the word subscribe in the body of the
+ message. To subscribe to the developers list, use the address
+ slang-workers-subscribe@babayaga.math.fu-berlin.de.
+
+
+
+ 3. Overview of the Language
+
+
+
+ This purpose of this section is to give the reader a feel for the S-
+ Lang language, its syntax, and its capabilities. The information and
+ examples presented in this section should be sufficient to provide the
+ reader with the necessary background to understand the rest of the
+ document.
+
+
+ 3.1. Variables and Functions
+
+
+
+ S-Lang is different from many other interpreted languages in the sense
+ that all variables and functions must be declared before they can be
+ used.
+
+ Variables are declared using the variable keyword, e.g.,
+
+
+ variable x, y, z;
+
+
+
+ declares three variables, x, y, and z. Note the semicolon at the end
+ of the statement. All S-Lang statements must end in a semi-colon.
+
+ Unlike compiled languages such as C, it is not necessary to specify
+ the data type of a S-Lang variable. The data type of a S-Lang
+ variable is determined upon assignment. For example, after execution
+ of the statements
+
+
+ x = 3;
+ y = sin (5.6);
+ z = "I think, therefore I am.";
+
+
+
+ x will be an integer, y will be a double, and z will be a string. In
+ fact, it is even possible to re-assign x to a string:
+
+
+ x = "x was an integer, but now is a string";
+
+
+
+ Finally, one can combine variable declarations and assignments in the
+ same statement:
+
+
+ variable x = 3, y = sin(5.6), z = "I think, therefore I am.";
+
+
+
+ Most functions are declared using the define keyword. A simple
+ example is
+
+
+
+ define compute_average (x, y)
+ {
+ variable s = x + y;
+ return s / 2.0;
+ }
+
+
+
+ which defines a function that simply computes the average of two num-
+ bers and returns the result. This example shows that a function con-
+ sists of three parts: the function name, a parameter list, and the
+ function body.
+
+ The parameter list consists of a comma separated list of variable
+ names. It is not necessary to declare variables within a parameter
+ list; they are implicitly declared. However, all other local
+ variables used in the function must be declared. If the function
+ takes no parameters, then the parameter list must still be present,
+ but empty:
+
+
+ define go_left_5 ()
+ {
+ go_left (5);
+ }
+
+
+
+ The last example is a function that takes no arguments and returns no
+ value. Some languages such as PASCAL distinguish such objects from
+ functions that return values by calling these objects procedures.
+ However, S-Lang, like C, does not make such a distinction.
+
+ The language permits recursive functions, i.e., functions that call
+ themselves. The way to do this in S-Lang is to first declare the
+ function using the form:
+
+ define function-name ();
+
+
+ It is not necessary to declare a parameter list when declaring a func-
+ tion in this way.
+
+ The most famous example of a recursive function is the factorial
+ function. Here is how to implement it using S-Lang:
+
+
+ define factorial (); % declare it for recursion
+
+ define factorial (n)
+ {
+ if (n < 2) return 1;
+ return n * factorial (n - 1);
+ }
+
+
+
+ This example also shows how to mix comments with code. S-Lang uses
+ the `%' character to start a comment and all characters from the com-
+ ment character to the end of the line are ignored.
+
+
+
+ 3.2. Strings
+
+
+
+ Perhaps the most appealing feature of any interpreted language is that
+ it frees the user from the responsibility of memory management. This
+ is particularly evident when contrasting how S-Lang handles string
+ variables with a lower level language such as C. Consider a function
+ that concatenates three strings. An example in S-Lang is:
+
+
+ define concat_3_strings (a, b, c)
+ {
+ return strcat (a, strcat (b, c));
+ }
+
+
+
+ This function uses the built-in strcat function for concatenating two
+ strings. In C, the simplest such function would look like:
+
+
+ char *concat_3_strings (char *a, char *b, char *c)
+ {
+ unsigned int len;
+ char *result;
+ len = strlen (a) + strlen (b) + strlen (c);
+ if (NULL == (result = (char *) malloc (len + 1)))
+ exit (1);
+ strcpy (result, a);
+ strcat (result, b);
+ strcat (result, c);
+ return result;
+ }
+
+
+
+ Even this C example is misleading since none of the issues of memory
+ management of the strings has been dealt with. The S-Lang language
+ hides all these issues from the user.
+
+ Binary operators have been defined to work with the string data type.
+ In particular the + operator may be used to perform string
+ concatenation. That is, one can use the + operator as an alternative
+ to strcat:
+
+
+ define concat_3_strings (a, b, c)
+ {
+ return a + b + c;
+ }
+
+
+
+ See section ??? for more information about string variables.
+
+
+
+ 3.3. Referencing and Dereferencing
+
+
+ The unary prefix operator, &, may be used to create a reference to an
+ object, which is similar to a pointer in other languages. References
+ are commonly used as a mechanism to pass a function as an argument to
+ another function as the following example illustrates:
+
+
+ define compute_functional_sum (funct)
+ {
+ variable i, s;
+
+ s = 0;
+ for (i = 0; i < 10; i++)
+ {
+ s += (@funct)(i);
+ }
+ return s;
+ }
+
+ variable sin_sum = compute_functional_sum (&sin);
+ variable cos_sum = compute_functional_sum (&cos);
+
+
+
+ Here, the function compute_functional_sum applies the function speci-
+ fied by the parameter funct to the first 10 integers and returns the
+ sum. The two statements following the function definition show how
+ the sin and cos functions may be used.
+
+ Note the @ operator in the definition of compute_functional_sum. It
+ is known as the dereference operator and is the inverse of the
+ reference operator.
+
+ Another use of the reference operator is in the context of the fgets
+ function. For example,
+
+
+ define read_nth_line (file, n)
+ {
+ variable fp, line;
+ fp = fopen (file, "r");
+
+ while (n > 0)
+ {
+ if (-1 == fgets (&line, fp))
+ return NULL;
+ n--;
+ }
+ return line;
+ }
+
+
+
+ uses the fgets function to read the nth line of a file. In particu-
+ lar, a reference to the local variable line is passed to fgets, and
+ upon return line will be set to the character string read by fgets.
+
+ Finally, references may be used as an alternative to multiple return
+ values by passing information back via the parameter list. The
+ example involving fgets presented above provided an illustration of
+ this. Another example is
+
+
+
+ define set_xyz (x, y, z)
+ {
+ @x = 1;
+ @y = 2;
+ @z = 3;
+ }
+ variable X, Y, Z;
+ set_xyz (&X, &Y, &Z);
+
+
+
+ which, after execution, results in X set to 1, Y set to 2, and Z set
+ to 3. A C programmer will note the similarity of set_xyz to the fol-
+ lowing C implementation:
+
+
+ void set_xyz (int *x, int *y, int *z)
+ {
+ *x = 1;
+ *y = 2;
+ *z = 3;
+ }
+
+
+
+ 3.4. Arrays
+
+
+ The S-Lang language supports multi-dimensional arrays of all
+ datatypes. For example, one can define arrays of references to
+ functions as well as arrays of arrays. Here are a few examples of
+ creating arrays:
+
+
+ variable A = Integer_Type [10];
+ variable B = Integer_Type [10, 3];
+ variable C = [1, 3, 5, 7, 9];
+
+
+
+ The first example creates an array of 10 integers and assigns it to
+ the variable A. The second example creates a 2-d array of 30 integers
+ arranged in 10 rows and 3 columns and assigns the result to B. In the
+ last example, an array of 5 integers is assigned to the variable C.
+ However, in this case the elements of the array are initialized to the
+ values specified. This is known as an inline-array.
+
+ S-Lang also supports something called an range-array. An example of
+ such an array is
+
+
+ variable C = [1:9:2];
+
+
+
+ This will produce an array of 5 integers running from 1 through 9 in
+ increments of 2.
+
+ Arrays are passed by reference to functions and never by value. This
+ permits one to write functions which can initialize arrays. For
+ example,
+
+
+ define init_array (a)
+ {
+ variable i, imax;
+
+ imax = length (a);
+ for (i = 0; i < imax; i++)
+ {
+ a[i] = 7;
+ }
+ }
+
+ variable A = Integer_Type [10];
+ init_array (A);
+
+
+
+ creates an array of 10 integers and initializes all its elements to 7.
+
+ There are more concise ways of accomplishing the result of the
+ previous example. These include:
+
+
+ variable A = [7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
+ variable A = Integer_Type [10]; A[[0:9]] = 7;
+ variable A = Integer_Type [10]; A[*] = 7;
+
+
+
+ The second and third methods use an array of indices to index the
+ array A. In the second, the range of indices has been explicitly
+ specified, whereas the third example uses a wildcard form. See sec-
+ tion ??? for more information about array indexing.
+
+ Although the examples have pertained to integer arrays, the fact is
+ that S-Lang arrays can be of any type, e.g.,
+
+
+ variable A = Double_Type [10];
+ variable B = Complex_Type [10];
+ variable C = String_Type [10];
+ variable D = Ref_Type [10];
+
+
+
+ create 10 element arrays of double, complex, string, and reference
+ types, respectively. The last example may be used to create an array
+ of functions, e.g.,
+
+
+ D[0] = &sin;
+ D[1] = &cos;
+
+
+
+ The language also defines unary, binary, and mathematical operations
+ on arrays. For example, if A and B are integer arrays, then A + B is
+ an array whose elements are the sum of the elements of A and B. A
+ trivial example that illustrates the power of this capability is
+
+ variable X, Y;
+ X = [0:2*PI:0.01];
+ Y = 20 * sin (X);
+
+
+
+ which is equivalent to the highly simplified C code:
+
+
+ double *X, *Y;
+ unsigned int i, n;
+
+ n = (2 * PI) / 0.01 + 1;
+ X = (double *) malloc (n * sizeof (double));
+ Y = (double *) malloc (n * sizeof (double));
+ for (i = 0; i < n; i++)
+ {
+ X[i] = i * 0.01;
+ Y[i] = 20 * sin (X[i]);
+ }
+
+
+
+ 3.5. Structures and User-Defined Types
+
+
+
+ A structure is similar to an array in the sense that it is a container
+ object. However, the elements of an array must all be of the same
+ type (or of Any_Type), whereas a structure is heterogeneous. As an
+ example, consider
+
+
+ variable person = struct
+ {
+ first_name, last_name, age
+ };
+ variable bill = @person;
+ bill.first_name = "Bill";
+ bill.last_name = "Clinton";
+ bill.age = 51;
+
+
+
+ In this example a structure consisting of the three fields has been
+ created and assigned to the variable person. Then an instance of this
+ structure has been created using the dereference operator and assigned
+ to bill. Finally, the individual fields of bill were initialized.
+ This is an example of an anonymous structure.
+
+ A named structure is really a new data type and may be created using
+ the typedef keyword:
+
+
+
+ typedef struct
+ {
+ first_name, last_name, age
+ }
+ Person_Type;
+
+ variable bill = @Person_Type;
+ bill.first_name = "Bill";
+ bill.last_name = "Clinton";
+ bill.age = 51;
+
+
+
+ The big advantage of creating a new type is that one can go on to cre-
+ ate arrays of the data type
+
+
+ variable People = Person_Type [100];
+ People[0].first_name = "Bill";
+ People[1].first_name = "Hillary";
+
+
+
+ The creation and initialization of a structure may be facilitated by a
+ function such as
+
+
+ define create_person (first, last, age)
+ {
+ variable person = @Person_Type;
+ person.first_name = first;
+ person.last_name = last;
+ person.age = age;
+ return person;
+ }
+ variable Bill = create_person ("Bill", "Clinton", 51);
+
+
+
+ Other common uses of structures is the creation of linked lists,
+ binary trees, etc. For more information about these and other
+ features of structures, see section ???.
+
+
+
+ 3.6. Namespaces
+
+
+ In addition to the global namespace, each compilation unit (e.g., a
+ file) is given a private namespace. A variable or function name that
+ is declared using the static keyword will be placed in the private
+ namespace associated with compilation unit. For example,
+
+
+ variable i;
+ static variable i;
+
+
+
+ defines two variables called i. The first declaration defines i in
+ the global namespace, but the second declaration defines i in the pri-
+ vate namespace.
+
+ The -> operator may be used in conjunction with the name of the
+ namespace to access objects in the name space. In the above example,
+ to access the variable i in the global namespace, one would use
+ Global->i. Unless otherwise specified, a private namespace has no
+ name and its objects may not be accessed from outside the compilation
+ unit. However, the implements function may be used give the private
+ namespace a name, allowing access to its objects. For example, if the
+ file t.sl contains
+
+
+ implements ("A");
+ static variable i;
+
+
+
+ then another file may access the variable i via A->i.
+
+
+
+ 4. Data Types and Literal Constants
+
+
+
+ The current implementation of the S-Lang language permits up to 256
+ distinct data types, including predefined data types such as integer
+ and floating point, as well as specialized applications specific data
+ types. It is also possible to create new data types in the language
+ using the typedef mechanism.
+
+ Literal constants are objects such as the integer 3 or the string
+ "hello". The actual data type given to a literal constant depends
+ upon the syntax of the constant. The following sections describe the
+ syntax of literals of specific data types.
+
+
+ 4.1. Predefined Data Types
+
+
+
+ The current version of S-Lang defines integer, floating point,
+ complex, and string types. It also defines special purpose data types
+ such as Null_Type, DataType_Type, and Ref_Type. These types are
+ discussed below.
+
+
+ 4.1.1. Integers
+
+
+
+ The S-Lang language supports both signed and unsigned characters,
+ short integer, long integer, and plain integer types. On most 32 bit
+ systems, there is no difference between an integer and a long integer;
+ however, they may differ on 16 and 64 bit systems. Generally
+ speaking, on a 16 bit system, plain integers are 16 bit quantities
+ with a range of -32767 to 32767. On a 32 bit system, plain integers
+ range from -2147483648 to 2147483647.
+
+ An plain integer literal can be specified in one of several ways:
+
+ o As a decimal (base 10) integer consisting of the characters 0
+ through 9, e.g., 127. An integer specified this way cannot begin
+ with a leading 0. That is, 0127 is not the same as 127.
+
+ o Using hexadecimal (base 16) notation consisting of the characters 0
+ to 9 and A through F. The hexadecimal number must be preceded by
+ the characters 0x. For example, 0x7F specifies an integer using
+ hexadecimal notation and has the same value as decimal 127.
+
+ o In Octal notation using characters 0 through 7. The Octal number
+ must begin with a leading 0. For example, 0177 and 127 represent
+ the same integer.
+
+ Short, long, and unsigned types may be specified by using the
+ proper suffixes: L indicates that the integer is a long integer, h
+ indicates that the integer is a short integer, and U indicates that
+ it is unsigned. For example, 1UL specifies an unsigned long
+ integer.
+
+ Finally, a character literal may be specified using a notation
+ containing a character enclosed in single quotes as 'a'. The value
+ of the character specified this way will lie in the range 0 to 256
+ and will be determined by the ASCII value of the character in
+ quotes. For example,
+
+
+ i = '0';
+
+
+
+ assigns to i the character 48 since the '0' character has an ASCII
+ value of 48.
+
+ Any integer may be preceded by a minus sign to indicate that it is a
+ negative integer.
+
+
+
+ 4.1.2. Floating Point Numbers
+
+
+
+ Single and double precision floating point literals must contain
+ either a decimal point or an exponent (or both). Here are examples of
+ specifying the same double precision point number:
+
+
+ 12. 12.0 12e0 1.2e1 120e-1 .12e2 0.12e2
+
+
+
+ Note that 12 is not a floating point number since it contains neither
+ a decimal point nor an exponent. In fact, 12 is an integer.
+
+ One may append the f character to the end of the number to indicate
+ that the number is a single precision literal.
+
+
+
+ 4.1.3. Complex Numbers
+
+
+
+ The language implements complex numbers as a pair of double precision
+ floating point numbers. The first number in the pair forms the real
+ part, while the second number forms the imaginary part. That is, a
+ complex number may be regarded as the sum of a real number and an
+ imaginary number.
+
+ Strictly speaking, the current implementation of the S-Lang does not
+ support generic complex literals. However, it does support imaginary
+ literals and a more generic complex number with a non-zero real part
+ may be constructed from the imaginary literal via addition of a real
+ number.
+
+ An imaginary literal is specified in the same way as a floating point
+ literal except that i or j is appended. For example,
+
+
+ 12i 12.0i 12e0j
+
+
+
+ all represent the same imaginary number. Actually, 12i is really an
+ imaginary integer except that S-Lang automatically promotes it to a
+ double precision imaginary number.
+
+ A more generic complex number may be constructed from an imaginary
+ literal via addition, e.g.,
+
+
+ 3.0 + 4.0i
+
+
+
+ produces a complex number whose real part is 3.0 and whose imaginary
+ part is 4.0.
+
+ The intrinsic functions Real and Imag may be used to retrieve the real
+ and imaginary parts of a complex number, respectively.
+
+
+
+ 4.1.4. Strings
+
+
+
+ A string literal must be enclosed in double quotes as in:
+
+
+ "This is a string".
+
+
+
+ Although there is no imposed limit on the length of a string, string
+ literals must be less than 256 characters in length. It is possible
+ to go beyond this limit by string concatenation, e.g.,
+
+
+ "This is the first part of a long string"
+ + "and this is the second half"
+
+
+
+ Any character except a newline (ASCII 10) or the null character (ASCII
+ 0) may appear explicitly in a string literal. However, these charac-
+ ters may be used implicitly using the mechanism described below.
+
+ The backslash character is a special character and is used to include
+ other special characters (such as a newline character) in the string.
+ The special characters recognized are:
+
+
+ \" -- double quote
+ \' -- single quote
+ \\ -- backslash
+ \a -- bell character (ASCII 7)
+ \t -- tab character (ASCII 9)
+ \n -- newline character (ASCII 10)
+ \e -- escape character (ASCII 27)
+ \xhhh -- character expressed in HEXADECIMAL notation
+ \ooo -- character expressed in OCTAL notation
+ \dnnn -- character expressed in DECIMAL
+
+
+
+ For example, to include the double quote character as part of the
+ string, it must be preceded by a backslash character, e.g.,
+ "This is a \"quote\""
+
+
+
+ Similarly, the next illustrates how a newline character may be
+ included:
+
+
+ "This is the first line\nand this is the second"
+
+
+
+ 4.1.5. Null_Type
+
+
+ Objects of type Null_Type can have only one value: NULL. About the
+ only thing that you can do with this data type is to assign it to
+ variables and test for equality with other objects. Nevertheless,
+ Null_Type is an important and extremely useful data type. Its main
+ use stems from the fact that since it can be compared for equality
+ with any other data type, it is ideal to represent the value of an
+ object which does not yet have a value, or has an illegal value.
+
+ As a trivial example of its use, consider
+
+
+ define add_numbers (a, b)
+ {
+ if (a == NULL) a = 0;
+ if (b == NULL) b = 0;
+ return a + b;
+ }
+ variable c = add_numbers (1, 2);
+ variable d = add_numbers (1, NULL);
+ variable e = add_numbers (1,);
+ variable f = add_numbers (,);
+
+
+
+ It should be clear that after these statements have been executed, c
+ will have a value of 3. It should also be clear that d will have a
+ value of 1 because NULL has been passed as the second parameter. One
+ feature of the language is that if a parameter has been omitted from a
+ function call, the variable associated with that parameter will be set
+ to NULL. Hence, e and f will be set to 1 and 0, respectively.
+
+ The Null_Type data type also plays an important role in the context of
+ structures.
+
+
+ 4.1.6. Ref_Type
+
+ Objects of Ref_Type are created using the unary reference operator &.
+ Such objects may be dereferenced using the dereference operator @.
+ For example,
+
+
+ variable sin_ref = &sin;
+ variable y = (@sin_ref) (1.0);
+
+ creates a reference to the sin function and assigns it to sin_ref.
+ The second statement uses the dereference operator to call the func-
+ tion that sin_ref references.
+
+ The Ref_Type is useful for passing functions as arguments to other
+ functions, or for returning information from a function via its
+ parameter list. The dereference operator is also used to create an
+ instance of a structure. For these reasons, further discussion of
+ this important type can be found in section ??? and section ???.
+
+
+ 4.1.7. Array_Type and Struct_Type
+
+
+ Variables of type Array_Type and Struct_Type are known as container
+ objects. They are much more complicated than the simple data types
+ discussed so far and each obeys a special syntax. For these reasons
+ they are discussed in a separate chapters. See ???.
+
+
+ 4.1.8. DataType_Type Type
+
+
+
+ S-Lang defines a type called DataType_Type. Objects of this type have
+ values that are type names. For example, an integer is an object of
+ type Integer_Type. The literals of DataType_Type include:
+
+
+ Char_Type (signed character)
+ UChar_Type (unsigned character)
+ Short_Type (short integer)
+ UShort_Type (unsigned short integer)
+ Integer_Type (plain integer)
+ UInteger_Type (plain unsigned integer)
+ Long_Type (long integer)
+ ULong_Type (unsigned long integer)
+ Float_Type (single precision real)
+ Double_Type (double precision real)
+ Complex_Type (complex numbers)
+ String_Type (strings, C strings)
+ BString_Type (binary strings)
+ Struct_Type (structures)
+ Ref_Type (references)
+ Null_Type (NULL)
+ Array_Type (arrays)
+ DataType_Type (data types)
+
+
+
+ as well as the names of any other types that an application defines.
+
+ The built-in function typeof returns the data type of its argument,
+ i.e., a DataType_Type. For instance typeof(7) returns Integer_Type
+ and typeof(Integer_Type) returns DataType_Type. One can use this
+ function as in the following example:
+
+
+ if (Integer_Type == typeof (x)) message ("x is an integer");
+
+
+
+ The literals of DataType_Type have other uses as well. One of the
+ most common uses of these literals is to create arrays, e.g.,
+ x = Complex_Type [100];
+
+
+
+ creates an array of 100 complex numbers and assigns it to x.
+
+
+
+ 4.2. Typecasting: Converting from one Type to Another
+
+
+ Occasionally, it is necessary to convert from one data type to
+ another. For example, if you need to print an object as a string, it
+ may be necessary to convert it to a String_Type. The typecast
+ function may be used to perform such conversions. For example,
+ consider
+
+
+ variable x = 10, y;
+ y = typecast (x, Double_Type);
+
+
+
+ After execution of these statements, x will have the integer value 10
+ and y will have the double precision floating point value 10.0. If
+ the object to be converted is an array, the typecast function will act
+ upon all elements of the array. For example,
+
+
+ variable x = [1:10]; % Array of integers
+ variable y = typecast (x, Double_Type);
+
+
+
+ will create an array of 10 double precision values and assign it to y.
+ One should also realize that it is not always possible to perform a
+ typecast. For example, any attempt to convert an Integer_Type to a
+ Null_Type will result in a run-time error.
+
+ Often the interpreter will perform implicit type conversions as
+ necessary to complete calculations. For example, when multiplying an
+ Integer_Type with a Double_Type, it will convert the Integer_Type to a
+ Double_Type for the purpose of the calculation. Thus, the example
+ involving the conversion of an array of integers to an array of
+ doubles could have been performed by multiplication by 1.0, i.e.,
+
+
+ variable x = [1:10]; % Array of integers
+ variable y = 1.0 * x;
+
+
+
+ The string intrinsic function is similar to the typecast function
+ except that it converts an object to a string representation. It is
+ important to understand that a typecast from some type to String_Type
+ is not the same as converting an object to its string operation.
+ That is, typecast(x,String_Type) is not equivalent to string(x). The
+ reason for this is that when given an array, the typecast function
+ acts on each element of the array to produce another array, whereas
+ the string function produces a a string.
+ The string function is useful for printing the value of an object.
+ This use is illustrated in the following simple example:
+
+
+ define print_object (x)
+ {
+ message (string (x));
+ }
+
+
+
+ Here, the message function has been used because it writes a string to
+ the display. If the string function was not used and the message
+ function was passed an integer, a type-mismatch error would have
+ resulted.
+
+
+
+ 5. Identifiers
+
+
+
+ The names given to variables, functions, and data types are called
+ identifiers. There are some restrictions upon the actual characters
+ that make up an identifier. An identifier name must start with a
+ letter ([A-Za-z]), an underscore character, or a dollar sign. The
+ rest of the characters in the name can be any combination of letters,
+ digits, dollar signs, or underscore characters. However, all
+ identifiers whose name begins with two underscore characters are
+ reserved for internal use by the interpreter and declarations of
+ objects with such names should be avoided.
+
+ Examples of valid identifiers include:
+
+
+ mary _3 _this_is_ok
+ a7e1 $44 _44$_Three
+
+
+
+ However, the following are not legal:
+
+
+ 7abc 2e0 #xx
+
+
+
+ In fact, 2e0 actually specifies the real number 2.0.
+
+ Although the maximum length of identifiers is unspecified by the
+ language, the length should be kept below 64 characters.
+
+ The following identifiers are reserved by the language for use as
+ keywords:
+
+
+ !if _for do mod sign xor
+ ERROR_BLOCK abs do_while mul2 sqr public
+ EXIT_BLOCK and else not static private
+ USER_BLOCK0 andelse exch or struct
+ USER_BLOCK1 break for orelse switch
+ USER_BLOCK2 case foreach pop typedef
+ USER_BLOCK3 chs forever return using
+ USER_BLOCK4 continue if shl variable
+ __tmp define loop shr while
+
+
+
+ In addition, the next major S-Lang release (v2.0) will reserve try and
+ catch, so it is probably a good idea to avoid those words until then.
+
+
+
+ 6. Variables
+
+
+
+ A variable must be declared before it can be used, otherwise an
+ undefined name error will be generated. A variable is declared using
+ the variable keyword, e.g,
+
+
+ variable x, y, z;
+
+
+
+ declares three variables, x, y, and z. This is an example of a vari-
+ able declaration statement, and like all statements, it must end in a
+ semi-colon.
+
+ Variables declared this way are untyped and inherit a type upon
+ assignment. The actual type checking is performed at run-time. For
+ example,
+
+
+ x = "This is a string";
+ x = 1.2;
+ x = 3;
+ x = 2i;
+
+
+
+ results in x being set successively to a string, a float, an integer,
+ and to a complex number (0+2i). Any attempt to use a variable before
+ it has acquired a type will result in an uninitialized variable error.
+
+ It is legal to put executable code in a variable declaration list.
+ That is,
+
+
+ variable x = 1, y = sin (x);
+
+
+
+ are legal variable declarations. This also provides a convenient way
+ of initializing a variable.
+
+ Variables are classified as either global or local. A variable
+ declared inside a function is said to be local and has no meaning
+ outside the function. A variable is said to be global if it was
+ declared outside a function. Global variables are further classified
+ as being public, static, or private, according to the name space where
+ they were defined. See chapter ??? for more information about name
+ spaces.
+
+ The following global variables are predefined by the language and are
+ mainly used as convenience variables:
+
+
+ $0 $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+
+
+ An intrinsic variable is another type of global variable. Such
+ variables have a definite type which cannot be altered. Variables of
+ this type may also be defined to be read-only, or constant variables.
+ An example of an intrinsic variable is PI which is a read-only double
+ precision variable with a value of approximately
+ 3.14159265358979323846.
+
+
+
+ 7. Operators
+
+
+
+ S-Lang supports a variety of operators that are grouped into three
+ classes: assignment operators, binary operators, and unary operators.
+
+ An assignment operator is used to assign a value to a variable. They
+ will be discussed more fully in the context of the assignment
+ statement in section ???.
+
+ An unary operator acts only upon a single quantity while a binary
+ operation is an operation between two quantities. The boolean
+ operator not is an example of an unary operator. Examples of binary
+ operators include the usual arithmetic operators +, -, *, and /. The
+ operator given by - can be either an unary operator (negation) or a
+ binary operator (subtraction); the actual operation is determined from
+ the context in which it is used.
+
+ Binary operators are used in algebraic forms, e.g., a + b. Unary
+ operators fall in one of two classes: postfix-unary or prefix-unary.
+ For example, in the expression -x, the minus sign is a prefix-unary
+ operator.
+
+ Not all data types have binary or unary operations defined. For
+ example, while String_Type objects support the + operator, they do not
+ admit the * operator.
+
+
+ 7.1. Unary Operators
+
+
+ The unary operators operate only upon a single operand. They include:
+ not, ~, -, @, &, as well as the increment and decrement operators ++
+ and --, respectively.
+
+ The boolean operator not acts only upon integers and produces 0 if its
+ operand is non-zero, otherwise it produces 1.
+
+ The bit-level not operator ~ performs a similar function, except that
+ it operates on the individual bits of its integer operand.
+
+ The arithmetic negation operator - is the most well-known unary
+ operator. It simply reverses the sign of its operand.
+
+ The reference (&) and dereference (@) operators will be discussed in
+ greater detail in section ???. Similarly, the increment (++) and
+ decrement (--) operators will be discussed in the context of the
+ assignment operator.
+
+
+ 7.2. Binary Operators
+
+
+
+ The binary operators may be grouped according to several classes:
+ arithmetic operators, relational operators, boolean operators, and
+ bitwise operators.
+
+ All binary and unary operators may be overloaded. For example, the
+ arithmetic plus operator has been overloaded by the String_Type data
+ type to permit concatenation between strings.
+
+
+
+ 7.2.1. Arithmetic Operators
+
+
+
+ The arithmetic operators include +, -, *, /, which perform addition,
+ subtraction, multiplication, and division, respectively. In addition
+ to these, S-Lang supports the mod operator as well as the power
+ operator ^.
+
+ The data type of the result produced by the use of one of these
+ operators depends upon the data types of the binary participants. If
+ they are both integers, the result will be an integer. However, if
+ the operands are not of the same type, they will be converted to a
+ common type before the operation is performed. For example, if one is
+ a floating point value and the other is an integer, the integer will
+ be converted to a float. In general, the promotion from one type to
+ another is such that no information is lost, if possible. As an
+ example, consider the expression 8/5 which indicates division of the
+ integer 8 by the integer 5. The result will be the integer 1 and not
+ the floating point value 1.6. However, 8/5.0 will produce 1.6 because
+ 5.0 is a floating point number.
+
+
+
+ 7.2.2. Relational Operators
+
+
+
+ The relational operators are >, >=, <, <=, ==, and !=. These perform
+ the comparisons greater than, greater than or equal, less than, less
+ than or equal, equal, and not equal, respectively. The result of one
+ of these comparisons is the integer 1 if the comparison is true, or 0
+ if the comparison is false. For example, 6 >= 5 returns 1, but 6 == 5
+ produces 0.
+
+
+
+ 7.2.3. Boolean Operators
+
+
+ There are only two boolean binary operators: or and and. These
+ operators are defined only for integers and produce an integer result.
+ The or operator returns 1 if either of its operands are non-zero,
+ otherwise it produces 0. The and operator produces 1 if and only if
+ both its operands are non-zero, otherwise it produces 0.
+
+ Neither of these operators perform the so-called boolean short-circuit
+ evaluation. For example, consider the expression:
+
+
+ (x != 0) and (1/x > 10)
+
+
+
+ Here, if x were to have a value of zero, a division by zero error
+ would occur because even though x!=0 evaluates to zero, the and opera-
+ tor is not short-circuited and the 1/x expression would still be eval-
+ uated. Although these operators are not short-circuited, S-Lang does
+ have another mechanism of performing short-circuit boolean evaluation
+ via the orelse and andelse expressions. See below for information
+ about these constructs.
+
+
+ 7.2.4. Bitwise Operators
+
+
+
+ The bitwise binary operators are defined only with integer operands
+ and are used for bit-level operations. Operators that fall in this
+ class include &, |, shl, shr, and xor. The & operator performs a
+ boolean AND operation between the corresponding bits of the operands.
+ Similarly, the | operator performs the boolean OR operation on the
+ bits. The bit-shifting operators shl and shr shift the bits of the
+ first operand by the number given by the second operand to the left or
+ right, respectively. Finally, the xor performs an EXCLUSIVE-OR
+ operation.
+
+ These operators are commonly used to manipulate variables whose
+ individual bits have distinct meanings. In particular, & is usually
+ used to test bits, | can be used to set bits, and xor may be used to
+ flip a bit.
+
+ As an example of using & to perform tests on bits, consider the
+ following: The jed text editor stores some of the information about a
+ buffer in a bitmapped integer variable. The value of this variable
+ may be retrieved using the jed intrinsic function getbuf_info, which
+ actually returns four quantities: the buffer flags, the name of the
+ buffer, directory name, and file name. For the purposes of this
+ section, only the buffer flags are of interest and can be retrieved
+ via a function such as
+
+
+ define get_buffer_flags ()
+ {
+ variable flags;
+ (,,,flags) = getbuf_info ();
+ return flags;
+ }
+
+
+
+ The buffer flags is a bitmapped quantity where the 0th bit indicates
+ whether or not the buffer has been modified, the first bit indicates
+ whether or not autosave has been enabled for the buffer, and so on.
+ Consider for the moment the task of determining if the buffer has been
+ modified. This can be determined by looking at the zeroth bit, if it
+ is 0 the buffer has not been modified, otherwise it has. Thus we can
+ create the function,
+
+
+ define is_buffer_modified ()
+ {
+ variable flags = get_buffer_flags ();
+ return (flags & 1);
+ }
+
+
+
+ where the integer 1 has been used since it has all of its bits set to
+ 0, except for the zeroth one, which is set to 1. (At this point, it
+ should also be apparent that bits are numbered from zero, thus an 8
+ bit integer consists of bits 0 to 7, where 0 is the least significant
+ bit and 7 is the most significant one.) Similarly, we can create
+ another function
+
+
+
+ define is_autosave_on ()
+ {
+ variable flags = get_buffer_flags ();
+ return (flags & 2);
+ }
+
+
+
+ to determine whether or not autosave has been turned on for the
+ buffer.
+
+ The shl operator may be used to form the integer with only the nth bit
+ set. For example, 1 shl 6 produces an integer with all bits set to
+ zero except the sixth bit, which is set to one. The following example
+ exploits this fact:
+
+
+ define test_nth_bit (flags, nth)
+ {
+ return flags & (1 shl nth);
+ }
+
+
+
+ 7.2.5. Namespace operator
+
+ The operator -> is used to in conjunction with the name of a namespace
+ to access an object within the namespace. For example, if A is the
+ name of a namespace containing the variable v, then A->v refers to
+ that variable.
+
+
+ 7.2.6. Operator Precedence
+
+
+
+ 7.2.7. Binary Operators and Functions Returning Multiple Values
+
+
+ Care must be exercised when using binary operators with an operand the
+ returns multiple values. In fact, the current implementation of the
+ S-Lang language will produce incorrect results if both operands of a
+ binary expression return multiple values. At most, only one of
+ operands of a binary expression can return multiple values, and that
+ operand must be the first one, not the second. For example,
+
+
+ define read_line (fp)
+ {
+ variable line, status;
+
+ status = fgets (&line, fp);
+ if (status == -1)
+ return -1;
+ return (line, status);
+ }
+
+
+
+ defines a function, read_line that takes a single argument, a handle
+ to an open file, and returns one or two values, depending upon the
+ return value of fgets. Now consider
+
+
+ while (read_line (fp) > 0)
+ {
+ text = ();
+ % Do something with text
+ .
+ .
+ }
+
+
+
+ Here the relational binary operator > forms a comparison between one
+ of the return values (the one at the top of the stack) and 0. In
+ accordance with the above rule, since read_line returns multiple val-
+ ues, it occurs as the left binary operand. Putting it on the right as
+ in
+
+
+ while (0 < read_line (fp)) % Incorrect
+ {
+ text = ();
+ % Do something with text
+ .
+ .
+ }
+
+
+
+ violates the rule and will result in the wrong answer.
+
+
+
+ 7.3. Mixing Integer and Floating Point Arithmetic
+
+
+ If a binary operation (+, -, * , /) is performed on two integers, the
+ result is an integer. If at least one of the operands is a float, the
+ other is converted to float and the result is float. For example:
+
+
+ 11 / 2 --> 5 (integer)
+ 11 / 2.0 --> 5.5 (float)
+ 11.0 / 2 --> 5.5 (float)
+ 11.0 / 2.0 --> 5.5 (float)
+
+
+
+ Finally note that only integers may be used as array indices, loop
+ control variables, and bit operations. The conversion functions, int
+ and float, may be used convert between floats and ints where appropri-
+ ate, e.g.,
+
+
+ int (1.5) --> 1 (integer)
+ float(1.5) --> 1.5 (float)
+ float (1) --> 1.0 (float)
+
+ 7.4. Short Circuit Boolean Evaluation
+
+
+ The boolean operators or and and are not short circuited as they are
+ in some languages. S-Lang uses orelse and andelse expressions for
+ short circuit boolean evaluation. However, these are not binary
+ operators. Expressions of the form:
+
+ expr-1 and expr-2 and ... expr-n
+
+
+ can be replaced by the short circuited version using andelse:
+
+ andelse {expr-1} {expr-2} ... {expr-n}
+
+
+ A similar syntax holds for the orelse operator. For example, consider
+ the statement:
+
+
+ if ((x != 0) and (1/x > 10)) do_something ();
+
+
+
+ Here, if x were to have a value of zero, a division by zero error
+ would occur because even though x!=0 evaluates to zero, the and opera-
+ tor is not short circuited and the 1/x expression would be evaluated
+ causing division by zero. For this case, the andelse expression could
+ be used to avoid the problem:
+
+
+ if (andelse
+ {x != 0}
+ {1 / x > 10}) do_something ();
+
+
+
+ 8. Statements
+
+
+
+ Loosely speaking, a statement is composed of expressions that are
+ grouped according to the syntax or grammar of the language to express
+ a complete computation. Statements are analogous to sentences in a
+ human language and expressions are like phrases. All statements in
+ the S-Lang language must end in a semi-colon.
+
+ A statement that occurs within a function is executed only during
+ execution of the function. However, statements that occur outside the
+ context of a function are evaluated immediately.
+
+ The language supports several different types of statements such as
+ assignment statements, conditional statements, and so forth. These
+ are described in detail in the following sections.
+
+
+ 8.1. Variable Declaration Statements
+
+ Variable declarations were already discussed in chapter ???. For the
+ sake of completeness, a variable declaration is a statement of the
+ form
+
+ variable variable-declaration-list ;
+
+
+ where the variable-declaration-list is a comma separated list of one
+ or more variable names with optional initializations, e.g.,
+
+
+ variable x, y = 2, z;
+
+
+
+ 8.2. Assignment Statements
+
+
+
+ Perhaps the most well known form of statement is the assignment
+ statement. Statements of this type consist of a left-hand side, an
+ assignment operator, and a right-hand side. The left-hand side must
+ be something to which an assignment can be performed. Such an object
+ is called an lvalue.
+
+ The most common assignment operator is the simple assignment operator
+ =. Simple of its use include
+
+
+ x = 3;
+ x = some_function (10);
+ x = 34 + 27/y + some_function (z);
+ x = x + 3;
+
+
+
+ In addition to the simple assignment operator, S-Lang also supports
+ the assignment operators += and -=. Internally, S-Lang transforms
+
+
+ a += b;
+
+
+ to
+
+
+ a = a + b;
+
+
+
+ Similarly, a -= b is transformed to a = a - b. It is extremely impor-
+ tant to realize that, in general, a+b is not equal to b+a. This means
+ that a+=b is not the same as a=b+a. As an example consider
+
+
+ a = "hello"; a += "world";
+
+
+
+ After execution of these two statements, a will have the value "hel-
+ loworld" and not "worldhello".
+
+ Since adding or subtracting 1 from a variable is quite common, S-Lang
+ also supports the unary increment and decrement operators ++, and --,
+ respectively. That is, for numeric data types,
+
+
+ x = x + 1;
+ x += 1;
+ x++;
+
+
+
+ are all equivalent. Similarly,
+
+
+ x = x - 1;
+ x -= 1;
+ x--;
+
+
+
+ are also equivalent.
+
+ Strictly speaking, ++ and -- are unary operators. When used as x++,
+ the ++ operator is said to be a postfix-unary operator. However, when
+ used as ++x it is said to be a prefix-unary operator. The current
+ implementation does not distinguish between the two forms, thus x++
+ and ++x are equivalent. The reason for this equivalence is that
+ assignment expressions do not return a value in the S-Lang language as
+ they do in C. Thus one should exercise care and not try to write C-
+ like code such as
+
+
+ x = 10;
+ while (--x) do_something (x); % Ok in C, but not in S-Lang
+
+
+
+ The closest valid S-Lang form involves a comma-expression:
+
+
+
+ x = 10;
+ while (x--, x) do_something (x); % Ok in S-Lang and in C
+
+
+
+ S-Lang also supports a multiple-assignment statement. It is discussed
+ in detail in section ???.
+
+
+
+ 8.3. Conditional and Looping Statements
+
+
+
+ S-Lang supports a wide variety of conditional and looping statements.
+ These constructs operate on statements grouped together in blocks. A
+ block is a sequence of S-Lang statements enclosed in braces and may
+ contain other blocks. However, a block cannot include function
+ declarations. In the following, statement-or-block refers to either a
+ single S-Lang statement or to a block of statements, and integer-
+ expression is an integer-valued expression. next-statement represents
+ the statement following the form under discussion.
+
+
+ 8.3.1. Conditional Forms
+
+
+
+ 8.3.1.1. if
+
+ The simplest condition statement is the if statement. It follows the
+ syntax
+
+ if (integer-expression) statement-or-block next-statement
+
+
+ If integer-expression evaluates to a non-zero result, then the state-
+ ment or group of statements implied statement-or-block will get exe-
+ cuted. Otherwise, control will proceed to next-statement.
+
+ An example of the use of this type of conditional statement is
+
+
+ if (x != 0)
+ {
+ y = 1.0 / x;
+ if (x > 0) z = log (x);
+ }
+
+
+
+ This example illustrates two if statements where the second if state-
+ ment is part of the block of statements that belong to the first.
+
+
+ 8.3.1.2. if-else
+
+ Another form of if statement is the if-else statement. It follows the
+ syntax:
+
+ if (integer-expression) statement-or-block-1 else statement-or-block-2
+ next-statement
+
+ Here, if expression returns non-zero, statement-or-block-1 will get
+ executed and control will pass on to next-statement. However, if
+ expression returns zero, statement-or-block-2 will get executed before
+ continuing with next-statement. A simple example of this form is
+
+
+ if (x > 0) z = log (x); else error ("x must be positive");
+
+
+
+ Consider the more complex example:
+
+
+ if (city == "Boston")
+ if (street == "Beacon") found = 1;
+ else if (city == "Madrid")
+ if (street == "Calle Mayor") found = 1;
+ else found = 0;
+
+
+
+ This example illustrates a problem that beginners have with if-else
+ statements. The grammar presented above shows that the this example
+ is equivalent to
+
+
+ if (city == "Boston")
+ {
+ if (street == "Beacon") found = 1;
+ else if (city == "Madrid")
+ {
+ if (street == "Calle Mayor") found = 1;
+ else found = 0;
+ }
+ }
+
+
+
+ It is important to understand the grammar and not be seduced by the
+ indentation!
+
+
+ 8.3.1.3. !if
+
+
+ One often encounters if statements similar to
+
+ if (integer-expression == 0) statement-or-block
+
+
+ or equivalently,
+
+ if (not(integer-expression)) statement-or-block
+
+
+ The !if statement was added to the language to simplify the handling
+ of such statements. It obeys the syntax
+
+ !if (integer-expression) statement-or-block
+
+
+ and is functionally equivalent to
+
+ if (not (expression)) statement-or-block
+
+
+
+ 8.3.1.4. orelse, andelse
+
+
+ These constructs were discussed earlier. The syntax for the orelse
+ statement is:
+
+ orelse {integer-expression-1} ... {integer-expression-n}
+
+
+ This causes each of the blocks to be executed in turn until one of
+ them returns a non-zero integer value. The result of this statement
+ is the integer value returned by the last block executed. For exam-
+ ple,
+
+
+ orelse { 0 } { 6 } { 2 } { 3 }
+
+
+
+ returns 6 since the second block is the first to return a non-zero
+ result. The last two block will not get executed.
+
+ The syntax for the andelse statement is:
+
+ andelse {integer-expression-1} ... {integer-expression-n}
+
+
+ Each of the blocks will be executed in turn until one of them returns
+ a zero value. The result of this statement is the integer value
+ returned by the last block executed. For example,
+
+
+ andelse { 6 } { 2 } { 0 } { 4 }
+
+
+
+ returns 0 since the third block will be the last to execute.
+
+
+ 8.3.1.5. switch
+
+ The switch statement deviates the most from its C counterpart. The
+ syntax is:
+
+
+ switch (x)
+ { ... : ...}
+ .
+ .
+ { ... : ...}
+
+
+
+ The `:' operator is a special symbol which means to test the top item
+ on the stack, and if it is non-zero, the rest of the block will get
+ executed and control will pass out of the switch statement. Other-
+ wise, the execution of the block will be terminated and the process
+ will be repeated for the next block. If a block contains no : opera-
+ tor, the entire block is executed and control will pass onto the next
+ statement following the switch statement. Such a block is known as
+ the default case.
+
+ As a simple example, consider the following:
+
+
+ switch (x)
+ { x == 1 : message("Number is one.");}
+ { x == 2 : message("Number is two.");}
+ { x == 3 : message("Number is three.");}
+ { x == 4 : message("Number is four.");}
+ { x == 5 : message("Number is five.");}
+ { message ("Number is greater than five.");}
+
+
+
+ Suppose x has an integer value of 3. The first two blocks will termi-
+ nate at the `:' character because each of the comparisons with x will
+ produce zero. However, the third block will execute to completion.
+ Similarly, if x is 7, only the last block will execute in full.
+
+ A more familiar way to write the previous example used the case
+ keyword:
+
+
+ switch (x)
+ { case 1 : print("Number is one.");}
+ { case 2 : print("Number is two.");}
+ { case 3 : print("Number is three.");}
+ { case 4 : print("Number is four.");}
+ { case 5 : print("Number is five.");}
+ { print ("Number is greater than five.");}
+
+
+
+ The case keyword is a more useful comparison operator because it can
+ perform a comparison between different data types while using == may
+ result in a type-mismatch error. For example,
+
+
+ switch (x)
+ { (x == 1) or (x == "one") : print("Number is one.");}
+ { (x == 2) or (x == "two") : print("Number is two.");}
+ { (x == 3) or (x == "three") : print("Number is three.");}
+ { (x == 4) or (x == "four") : print("Number is four.");}
+ { (x == 5) or (x == "five") : print("Number is five.");}
+ { print ("Number is greater than five.");}
+
+
+
+ will fail because the == operation is not defined between strings and
+ integers. The correct way to write this to use the case keyword:
+
+
+ switch (x)
+ { case 1 or case "one" : print("Number is one.");}
+ { case 2 or case "two" : print("Number is two.");}
+ { case 3 or case "three" : print("Number is three.");}
+ { case 4 or case "four" : print("Number is four.");}
+ { case 5 or case "five" : print("Number is five.");}
+ { print ("Number is greater than five.");}
+
+
+ 8.3.2. Looping Forms
+
+
+
+ 8.3.2.1. while
+
+ The while statement follows the syntax
+
+ while (integer-expression) statement-or-block next-statement
+
+
+ It simply causes statement-or-block to get executed as long as inte-
+ ger-expression evaluates to a non-zero result. For example,
+
+
+ i = 10;
+ while (i)
+ {
+ i--;
+ newline ();
+ }
+
+
+
+ will cause the newline function to get called 10 times. However,
+
+
+ i = -10;
+ while (i)
+ {
+ i--;
+ newline ();
+ }
+
+
+
+ would loop forever (or until i wraps from the most negative integer
+ value to the most positive and then decrements to zero).
+
+
+ If you are a C programmer, do not let the syntax of the language
+ seduce you into writing this example as you would in C:
+
+
+ i = 10;
+ while (i--) newline ();
+
+
+
+ The fact is that expressions such as i-- do not return a value in S-
+ Lang as they do in C. If you must write this way, use the comma oper-
+ ator as in
+
+
+ i = 10;
+ while (i, i--) newline ();
+
+
+
+ 8.3.2.2. do...while
+
+ The do...while statement follows the syntax
+
+ do statement-or-block while (integer-expression);
+
+
+ The main difference between this statement and the while statement is
+ that the do...while form performs the test involving integer-expres-
+ sion after each execution of statement-or-block rather than before.
+ This guarantees that statement-or-block will get executed at least
+ once.
+
+ A simple example from the jed editor follows:
+
+
+ bob (); % Move to beginning of buffer
+ do
+ {
+ indent_line ();
+ }
+ while (down (1));
+
+
+
+ This will cause all lines in the buffer to get indented via the jed
+ intrinsic function indent_line.
+
+
+ 8.3.2.3. for
+
+ Perhaps the most complex looping statement is the for statement;
+ nevertheless, it is a favorite of many programmers. This statement
+ obeys the syntax
+
+ for (init-expression; integer-expression; end-expression) statement-
+ or-block next-statement
+
+
+ In addition to statement-or-block, its specification requires three
+ other expressions. When executed, the for statement evaluates init-
+ expression, then it tests integer-expression. If integer-expression
+ returns zero, control passes to next-statement. Otherwise, it exe-
+ cutes statement-or-block as long as integer-expression evaluates to a
+ non-zero result. After every execution of statement-or-block, end-
+ expression will get evaluated.
+
+ This statement is almost equivalent to
+
+ init-expression; while (integer-expression) { statement-or-block end-
+ expression; }
+
+
+ The reason that they are not fully equivalent involves what happens
+ when statement-or-block contains a continue statement.
+
+ Despite the apparent complexity of the for statement, it is very easy
+ to use. As an example, consider
+
+
+ s = 0;
+ for (i = 1; i <= 10; i++) s += i;
+
+
+
+ which computes the sum of the first 10 integers.
+
+
+ 8.3.2.4. loop
+
+ The loop statement simply executes a block of code a fixed number of
+ times. It follows the syntax
+
+ loop (integer-expression) statement-or-block next-statement
+
+
+ If the integer-expression evaluates to a positive integer, statement-
+ or-block will get executed that many times. Otherwise, control will
+ pass to next-statement.
+
+ For example,
+
+
+ loop (10) newline ();
+
+
+
+ will cause the function newline to get called 10 times.
+
+
+ 8.3.2.5. _.ds h for loop
+
+ Like loop, the _for statement simply executes a block of code a fixed
+ number times. Unlike the loop statement, the _for loop is useful in
+ situations where the loop index is needed. It obeys the syntax
+
+ _for (first-value, last-value, increment) block next-statement
+
+
+ Each time through the loop, the current value of the loop index is
+ pushed onto the stack. The first time through, the loop index will
+ have the value of first-value. The second time its value will be
+ first-value + increment, and so on. The loop will terminate when the
+ value of the loop index exceeds last-value. The current implementa-
+ tion requires the control parameters first-value, last-value, and
+ increment to be integered valued expressions.
+
+ For example, it may be used to compute the sum of the first ten
+ integers:
+
+
+ s = 0;
+ _for (1, 10, 1)
+ {
+ i = ();
+ s += i;
+ }
+
+
+
+ The execution speed of the _for loop is more than twice as fast as the
+ more powerful for loop making it a better choice for many situations.
+
+
+ 8.3.2.6. forever
+
+ The forever statement is similar to the loop statement except that it
+ loops forever, or until a break or a return statement is executed. It
+ obeys the syntax
+ forever statement-or-block
+
+
+ A trivial example of this statement is
+
+
+ n = 10;
+ forever
+ {
+ if (n == 0) break;
+ newline ();
+ n--;
+ }
+
+
+
+ 8.3.2.7. foreach
+
+ The foreach statement is used to loop over one or more statements for
+ every element in a container object. A container object is a data
+ type that consists of other types. Examples include both ordinary and
+ associative arrays, structures, and strings. Every time through the
+ loop the current member of the object is pushed onto the stack.
+
+ The simple type of foreach statement obeys the syntax
+
+ foreach (container-object) statement-or-block
+
+
+ Here container-object can be an expression that returns a container
+ object. A simple example is
+
+
+ foreach (["apple", "peach", "pear"])
+ {
+ fruit = ();
+ process_fruit (fruit);
+ }
+
+
+
+ This example shows that if the container object is an array, then suc-
+ cessive elements of the array are pushed onto the stack prior to each
+ execution cycle. If the container object is a string, then successive
+ characters of the string are pushed onto the stack.
+
+ What actually gets pushed onto the stack may be controlled via the
+ using form of the foreach statement. This more complex type of
+ foreach statement follows the syntax
+
+ foreach ( container-object ) using ( control-list ) statement-or-block
+
+
+ The allowed values of control-list will depend upon the type of con-
+ tainer object. For associative arrays (Assoc_Type), control-list
+ specified whether keys, values, or both are pushed onto the stack.
+ For example,
+
+
+
+ foreach (a) using ("keys")
+ {
+ k = ();
+ .
+ .
+ }
+
+
+
+ results in the keys of the associative array a being pushed on the
+ list. However,
+
+
+ foreach (a) using ("values")
+ {
+ v = ();
+ .
+ .
+ }
+
+
+
+ will cause the values to be used, and
+
+
+ foreach (a) using ("keys", "values")
+ {
+ (k,v) = ();
+ .
+ .
+ }
+
+
+
+ will use both the keys and values of the array.
+
+ Similarly, for linked-lists of structures, one may walk the list via
+ code like
+
+
+ foreach (linked_list) using ("next")
+ {
+ s = ();
+ .
+ .
+ }
+
+
+
+ This foreach statement is equivalent
+
+
+ s = linked_list;
+ while (s != NULL)
+ {
+ .
+ .
+ s = s.next;
+ }
+
+
+
+ Consult the type-specific documentation for a discussion of the using
+ control words, if any, appropriate for a given type.
+
+
+ 8.4. break, return, continue
+
+
+ S-Lang also includes the non-local transfer functions return, break,
+ and continue. The return statement causes control to return to the
+ calling function while the break and continue statements are used in
+ the context of loop structures. Consider:
+
+
+ define fun ()
+ {
+ forever
+ {
+ s1;
+ s2;
+ ..
+ if (condition_1) break;
+ if (condition_2) return;
+ if (condition_3) continue;
+ ..
+ s3;
+ }
+ s4;
+ ..
+ }
+
+
+
+ Here, a function fun has been defined that contains a forever loop
+ consisting of statements s1, s2,...,s3, and three if statements. As
+ long as the expressions condition_1, condition_2, and condition_3
+ evaluate to zero, the statements s1, s2,...,s3 will be repeatedly exe-
+ cuted. However, if condition_1 returns a non-zero value, the break
+ statement will get executed, and control will pass out of the forever
+ loop to the statement immediately following the loop which in this
+ case is s4. Similarly, if condition_2 returns a non-zero number, the
+ return statement will cause control to pass back to the caller of fun.
+ Finally, the continue statement will cause control to pass back to the
+ start of the loop, skipping the statement s3 altogether.
+
+
+
+ 9. Functions
+
+
+
+ A function may be thought of as a group of statements that work
+ together to perform a computation. While there are no imposed limits
+ upon the number statements that may occur within a function, it is
+ considered poor programming practice if a function contains many
+ statements. This notion stems from the belief that a function should
+ have a simple, well defined purpose.
+
+
+ 9.1. Declaring Functions
+
+
+
+ Like variables, functions must be declared before they can be used.
+ The define keyword is used for this purpose. For example,
+
+
+ define factorial ();
+
+
+
+ is sufficient to declare a function named factorial. Unlike the vari-
+ able keyword used for declaring variables, the define keyword does not
+ accept a list of names.
+
+ Usually, the above form is used only for recursive functions. In most
+ cases, the function name is almost always followed by a parameter list
+ and the body of the function:
+
+ define function-name (parameter-list) { statement-list }
+
+
+ The function-name is an identifier and must conform to the naming
+ scheme for identifiers discussed in chapter ???. The parameter-list
+ is a comma-separated list of variable names that represent parameters
+ passed to the function, and may be empty if no parameters are to be
+ passed. The body of the function is enclosed in braces and consists
+ of zero or more statements (statement-list).
+
+ The variables in the parameter-list are implicitly declared, thus,
+ there is no need to declare them via a variable declaration statement.
+ In fact any attempt to do so will result in a syntax error.
+
+
+
+ 9.2. Parameter Passing Mechanism
+
+
+
+ Parameters to a function are always passed by value and never by
+ reference. To see what this means, consider
+
+
+ define add_10 (a)
+ {
+ a = a + 10;
+ }
+ variable b = 0;
+ add_10 (b);
+
+
+ Here a function add_10 has been defined, which when executed, adds 10
+ to its parameter. A variable b has also been declared and initialized
+ to zero before it is passed to add_10. What will be the value of b
+ after the call to add_10? If S-Lang were a language that passed
+ parameters by reference, the value of b would be changed to 10. How-
+ ever, S-Lang always passes by value, which means that b would retain
+ its value of zero after the function call.
+
+ S-Lang does provide a mechanism for simulating pass by reference via
+ the reference operator. See the next section for more details.
+
+ If a function is called with a parameter in the parameter list
+ omitted, the corresponding variable in the function will be set to
+ NULL. To make this clear, consider the function
+
+
+ define add_two_numbers (a, b)
+ {
+ if (a == NULL) a = 0;
+ if (b == NULL) b = 0;
+ return a + b;
+ }
+
+
+
+ This function must be called with two parameters. However, we can
+ omit one or both of the parameters by calling it in one of the follow-
+ ing ways:
+
+
+ variable s = add_two_numbers (2,3);
+ variable s = add_two_numbers (2,);
+ variable s = add_two_numbers (,3);
+ variable s = add_two_numbers (,);
+
+
+
+ The first example calls the function using both parameters; however,
+ at least one of the parameters was omitted in the other examples. The
+ interpreter will implicitly convert the last three examples to
+
+
+ variable s = add_two_numbers (2, NULL);
+ variable s = add_two_numbers (NULL, 3);
+ variable s = add_two_numbers (NULL, NULL);
+
+
+
+ It is important to note that this mechanism is available only for
+ function calls that specify more than one parameter. That is,
+
+
+ variable s = add_10 ();
+
+
+
+ is not equivalent to add_10(NULL). The reason for this is simple: the
+ parser can only tell whether or not NULL should be substituted by
+ looking at the position of the comma character in the parameter list,
+ and only function calls that indicate more than one parameter will use
+ a comma. A mechanism for handling single parameter function calls is
+ described in the next section.
+ 9.3. Referencing Variables
+
+
+
+ One can achieve the effect of passing by reference by using the
+ reference (&) and dereference (@) operators. Consider again the add_10
+ function presented in the previous section. This time we write it as
+
+
+ define add_10 (a)
+ {
+ @a = @a + 10;
+ }
+ variable b = 0;
+ add_10 (&b);
+
+
+
+ The expression &b creates a reference to the variable b and it is the
+ reference that gets passed to add_10. When the function add_10 is
+ called, the value of a will be a reference to b. It is only by deref-
+ erencing this value that b can be accessed and changed. So, the
+ statement @a=@a+10; should be read `add 10' to the value of the object
+ that a references and assign the result to the object that a refer-
+ ences.
+
+ The reader familiar with C will note the similarity between references
+ in S-Lang and pointers in C.
+
+ One of the main purposes for references is that this mechanism allows
+ reference to functions to be passed to other functions. As a simple
+ example from elementary calculus, consider the following function
+ which returns an approximation to the derivative of another function
+ at a specified point:
+
+
+ define derivative (f, x)
+ {
+ variable h = 1e-6;
+ return ((@f)(x+h) - (@f)(x)) / h;
+ }
+
+
+
+ It can be used to differentiate the function
+
+
+ define x_squared (x)
+ {
+ return x^2;
+ }
+
+
+
+ at the point x = 3 via the expression derivative(&x_squared,3).
+
+
+
+ 9.4. Functions with a Variable Number of Arguments
+
+
+
+ S-Lang functions may be defined to take a variable number of
+ arguments. The reason for this is that the calling routine pushes the
+ arguments onto the stack before making a function call, and it is up
+ to the called function to pop the values off the stack and make
+ assignments to the variables in the parameter list. These details
+ are, for the most part, hidden from the programmer. However, they are
+ important when a variable number of arguments are passed.
+
+ Consider the add_10 example presented earlier. This time it is
+ written
+
+
+ define add_10 ()
+ {
+ variable x;
+ x = ();
+ return x + 10;
+ }
+ variable s = add_10 (12); % ==> s = 22;
+
+
+
+ For the uninitiated, this example looks as if it is destined for dis-
+ aster. The add_10 function looks like it accepts zero arguments, yet
+ it was called with a single argument. On top of that, the assignment
+ to x looks strange. The truth is, the code presented in this example
+ makes perfect sense, once you realize what is happening.
+
+ First, consider what happened when add_10 is called with the the
+ parameter 12. Internally, 12 is pushed onto the stack and then the
+ function called. Now, consider the function itself. x is a variable
+ local to the function. The strange looking assignment `x=()' simply
+ takes whatever is on the stack and assigns it to x. In other words,
+ after this statement, the value of x will be 12, since 12 will be at
+ the top of the stack.
+
+ A generic function of the form
+
+
+ define function_name (x, y, ..., z)
+ {
+ .
+ .
+ }
+
+
+
+ is internally transformed by the interpreter to
+
+
+
+ define function_name ()
+ {
+ variable x, y, ..., z;
+ z = ();
+ .
+ .
+ y = ();
+ x = ();
+ .
+ .
+ }
+
+
+
+ before further parsing. (The add_10 function, as defined above, is
+ already in this form.) With this knowledge in hand, one can write a
+ function that accepts a variable number of arguments. Consider the
+ function:
+
+
+ define average_n (n)
+ {
+ variable x, y;
+ variable s;
+
+ if (n == 1)
+ {
+ x = ();
+ s = x;
+ }
+ else if (n == 2)
+ {
+ y = ();
+ x = ();
+ s = x + y;
+ }
+ else error ("average_n: only one or two values supported");
+
+ return s / n;
+ }
+ variable ave1 = average_n (3.0, 1); % ==> 3.0
+ variable ave2 = average_n (3.0, 5.0, 2); % ==> 4.0
+
+
+
+ Here, the last argument passed to average_n is an integer reflecting
+ the number of quantities to be averaged. Although this example works
+ fine, its principal limitation is obvious: it only supports one or two
+ values. Extending it to three or more values by adding more else if
+ constructs is rather straightforward but hardly worth the effort.
+ There must be a better way, and there is:
+
+
+
+ define average_n (n)
+ {
+ variable s, x;
+ s = 0;
+ loop (n)
+ {
+ x = (); % get next value from stack
+ s += x;
+ }
+ return s / n;
+ }
+
+
+
+ The principal limitation of this approach is that one must still pass
+ an integer that specifies how many values are to be averaged.
+
+ Fortunately, a special variable exists that is local to every function
+ and contains the number of values that were passed to the function.
+ That variable has the name _NARGS and may be used as follows:
+
+
+ define average_n ()
+ {
+ variable x, s = 0;
+
+ if (_NARGS == 0) error ("Usage: ave = average_n (x, ...);");
+
+ loop (_NARGS)
+ {
+ x = ();
+ s += x;
+ }
+ return s / _NARGS;
+ }
+
+
+
+ Here, if no arguments are passed to the function, a simple message
+ that indicates how it is to be used is printed out.
+
+
+
+ 9.5. Returning Values
+
+
+ As stated earlier, the usual way to return values from a function is
+ via the return statement. This statement has the simple syntax
+
+ return expression-list ;
+
+
+ where expression-list is a comma separated list of expressions. If
+ the function does not return any values, the expression list will be
+ empty. As an example of a function that can return multiple values,
+ consider
+
+
+
+ define sum_and_diff (x, y)
+ {
+ variable sum, diff;
+
+ sum = x + y; diff = x - y;
+ return sum, diff;
+ }
+
+
+
+ which is a function returning two values.
+
+ It is extremely important to note that the calling routine must
+ explicitly handle all values returned by a function. Although some
+ languages such as C do not have this restriction, S-Lang does and it
+ is a direct result of a S-Lang function's ability to return many
+ values and accept a variable number of parameters. Examples of
+ properly handling the above function include
+
+
+ variable s, d;
+ (s, d) = sum_and_diff (5, 4); % ignore neither
+ (s,) = sum_and_diff (5, 4); % ignore diff
+ (,) = sum_and_diff (5, 4); % ignore both sum and diff
+
+
+
+ See the section below on assignment statements for more information
+ about this important point.
+
+
+ 9.6. Multiple Assignment Statement
+
+
+
+ S-Lang functions can return more than one value, e.g.,
+
+
+ define sum_and_diff (x, y)
+ {
+ return x + y, x - y;
+ }
+
+
+
+ returns two values. It accomplishes this by placing both values on
+ the stack before returning. If you understand how S-Lang functions
+ handle a variable number of parameters (section ???), then it should
+ be rather obvious that one assigns such values to variables. One way
+ is to use, e.g.,
+
+
+ sum_and_diff (9, 4);
+ d = ();
+ s = ();
+
+
+
+ However, the most convenient way to accomplish this is to use a
+ multiple assignment statement such as
+
+
+ (s, d) = sum_and_diff (9, 4);
+
+
+
+ The most general form of the multiple assignment statement is
+
+
+ ( var_1, var_2, ..., var_n ) = expression;
+
+
+
+ In fact, internally the interpreter transforms this statement into the
+ form
+
+
+ expression; var_n = (); ... var_2 = (); var_1 = ();
+
+
+
+ for further processing.
+
+ If you do not care about one of return values, simply omit the
+ variable name from the list. For example,
+
+
+ (s, ) = sum_and_diff (9, 4);
+
+
+
+ assigns the sum of 9 and 4 to s and the difference (9-4) will be
+ removed from the stack.
+
+ As another example, the jed editor provides a function called down
+ that takes an integer argument and returns an integer. It is used to
+ move the current editing position down the number of lines specified
+ by the argument passed to it. It returns the number of lines it
+ successfully moved the editing position. Often one does not care
+ about the return value from this function. Although it is always
+ possible to handle the return value via
+
+
+ variable dummy = down (10);
+
+
+
+ it is more convenient to use a multiple assignment expression and omit
+ the variable name, e.g.,
+
+
+ () = down (10);
+
+
+
+ Some functions return a variable number of values instead of a fixed
+ number. Usually, the value at the top of the stack will indicate the
+ actual number of return values. For such functions, the multiple
+ assignment statement cannot directly be used. To see how such
+ functions can be dealt with, consider the following function:
+
+
+ define read_line (fp)
+ {
+ variable line;
+ if (-1 == fgets (&line, fp))
+ return -1;
+ return (line, 0);
+ }
+
+
+
+ This function returns either one or two values, depending upon the
+ return value of fgets. Such a function may be handled as in the fol-
+ lowing example:
+
+
+ status = read_line (fp);
+ if (status != -1)
+ {
+ s = ();
+ .
+ .
+ }
+
+
+
+ In this example, the last value returned by read_line is assigned to
+ status and then tested. If it is non-zero, the second return value is
+ assigned to s. In particular note the empty set of parenthesis in the
+ assignment to s. This simply indicates that whatever is on the top of
+ the stack when the statement is executed will be assigned to s.
+
+ Before leaving this section it is important to reiterate the fact that
+ if a function returns a value, the caller must deal with that return
+ value. Otherwise, the value will continue to live onto the stack and
+ may eventually lead to a stack overflow error. Failing to handle the
+ return value of a function is the most common mistake that
+ inexperienced S-Lang programmers make. For example, the fflush
+ function returns a value that many C programmer's never check.
+ Instead of writing
+
+
+ fflush (fp);
+
+
+
+ as one could in C, a S-Lang programmer should write
+
+
+ () = fflush (fp);
+
+
+
+ in S-Lang. (Many good C programmer's write (void)fflush(fp) to indi-
+ cate that the return value is being ignored).
+
+
+
+ 9.7. Exit-Blocks
+
+
+
+ An exit-block is a set of statements that get executed when a
+ functions returns. They are very useful for cleaning up when a
+ function returns via an explicit call to return from deep within a
+ function.
+
+ An exit-block is created by using the EXIT_BLOCK keyword according to
+ the syntax
+
+ EXIT_BLOCK { statement-list }
+
+
+ where statement-list represents the list of statements that comprise
+ the exit-block. The following example illustrates the use of an exit-
+ block:
+
+
+ define simple_demo ()
+ {
+ variable n = 0;
+
+ EXIT_BLOCK { message ("Exit block called."); }
+
+ forever
+ {
+ if (n == 10) return;
+ n++;
+ }
+ }
+
+
+
+ Here, the function contains an exit-block and a forever loop. The
+ loop will terminate via the return statement when n is 10. Before it
+ returns, the exit-block will get executed.
+
+ A function can contain multiple exit-blocks, but only the last one
+ encountered during execution will actually get executed. For example,
+
+
+ define simple_demo (n)
+ {
+ EXIT_BLOCK { return 1; }
+
+ if (n != 1)
+ {
+ EXIT_BLOCK { return 2; }
+ }
+ return;
+ }
+
+
+
+ If 1 is passed to this function, the first exit-block will get exe-
+ cuted because the second one would not have been encountered during
+ the execution. However, if some other value is passed, the second
+ exit-block would get executed. This example also illustrates that it
+ is possible to explicitly return from an exit-block, although nested
+ exit-blocks are illegal.
+
+
+
+ 10. Name Spaces
+
+
+
+ By default, all global variables and functions are defined in the
+ global namespace. In addition to the global namespace, every
+ compilation unit (e.g., a file containing S-Lang code) has an
+ anonymous namespace. Objects may be defined in the anonymous
+ namespace via the static declaration keyword. For example,
+
+
+ static variable x;
+ static define hello () { message ("hello"); }
+
+
+
+ defines a variable x and a function hello in the anonymous namespace.
+ This is useful when one wants to define functions and variables that
+ are only to be used within the file, or more precisely the compilation
+ unit, that defines them.
+
+ The implements function may be used to give the anonymous namespace a
+ name to allow access to its objects from outside the compilation unit
+ that defines them. For example,
+
+
+ implements ("foo");
+ static variable x;
+
+
+
+ allows the variable x to be accessed via foo->x, e.g.,
+
+
+ if (foo->x == 1) foo->x = 2;
+
+
+
+ The implements function does more than simply giving the anonymous
+ namespace a name. It also changes the default variable and function
+ declaration mode from public to static. That is,
+
+
+ implements ("foo");
+ variable x;
+
+
+
+ and
+
+
+ implements ("foo");
+ static variable x;
+
+
+
+ are equivalent. Then to create a public object within the namespace,
+ one must explicitly use the public keyword.
+
+ Finally, the private keyword may be used to create an object that is
+ truly private within the compilation unit. For example,
+ implements ("foo");
+ variable x;
+ private variable y;
+
+
+
+ allows x to be accessed from outside the namespace via foo->x, however
+ y cannot be accessed.
+
+
+
+ 11. Arrays
+
+
+
+ An array is a container object that can contain many values of one
+ data type. Arrays are very useful objects and are indispensable for
+ certain types of programming. The purpose of this chapter is to
+ describe how arrays are defined and used in the S-Lang language.
+
+
+ 11.1. Creating Arrays
+
+
+
+ The S-Lang language supports multi-dimensional arrays of all data
+ types. Since the Array_Type is a data type, one can even have arrays
+ of arrays. To create a multi-dimensional array of SomeType use the
+ syntax
+
+
+ SomeType [dim0, dim1, ..., dimN]
+
+
+
+ Here dim0, dim1, ... dimN specify the size of the individual dimen-
+ sions of the array. The current implementation permits arrays consist
+ of up to 7 dimensions. When a numeric array is created, all its ele-
+ ments are initialized to zero. The initialization of other array
+ types depend upon the data type, e.g., String_Type and Struct_Type
+ arrays are initialized to NULL.
+
+ As a concrete example, consider
+
+
+ a = Integer_Type [10];
+
+
+
+ which creates a one-dimensional array of 10 integers and assigns it to
+ a. Similarly,
+
+
+ b = Double_Type [10, 3];
+
+
+
+ creates a 30 element array of double precision numbers arranged in 10
+ rows and 3 columns, and assigns it to b.
+
+
+ 11.1.1. Range Arrays
+
+
+ There is a more convenient syntax for creating and initializing a 1-d
+ arrays. For example, to create an array of ten integers whose
+ elements run from 1 through 10, one may simply use:
+
+
+ a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+
+
+ Similarly,
+
+
+ b = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
+
+
+
+ specifies an array of ten doubles.
+
+ An even more compact way of specifying a numeric array is to use a
+ range-array. For example,
+
+
+ a = [0:9];
+
+
+
+ specifies an array of 10 integers whose elements range from 0 through
+ 9. The most general form of a range array is
+
+
+ [first-value : last-value : increment]
+
+
+
+ where the increment is optional and defaults to 1. This creates an
+ array whose first element is first-value and whose successive values
+ differ by increment. last-value sets an upper limit upon the last
+ value of the array as described below.
+
+ If the range array [a:b:c] is integer valued, then the interval
+ specified by a and b is closed. That is, the kth element of the array
+ x_k is given by x_k=a+ck and must satisfy a<=x_k<=b. Hence, the
+ number of elements in an integer range array is given by the
+ expression 1 + (b-a)/c.
+
+ The situation is somewhat more complicated for floating point range
+ arrays. The interval specified by a floating point range array
+ [a:b:c] is semi-open such that b is not contained in the interval. In
+ particular, the kth element of [a:b:c] is given by x_k=a+kc such that
+ a<=x_k<b when c>=0, and b<x_k<=a otherwise. The number of elements in
+ the array is one greater than the largest k that satisfies the open
+ interval constraint.
+
+ Here are a few examples that illustrate the above comments:
+
+
+ [1:5:1] ==> [1,2,3,4,5]
+ [1.0:5.0:1.0] ==> [1.0, 2.0, 3.0, 4.0]
+ [5:1:-1] ==> [5,4,3,2,1]
+ [5.0:1.0:-1.0] ==> [5.0, 4.0, 3.0, 2.0];
+ [1:1] ==> [1]
+ [1.0:1.0] ==> []
+ [1:-3] ==> []
+
+
+
+ 11.1.2. Creating arrays via the dereference operator
+
+
+
+ Another way to create an array is apply the dereference operator @ to
+ the DataType_Type literal Array_Type. The actual syntax for this
+ operation resembles a function call
+
+ variable a = @Array_Type (data-type, integer-array);
+
+
+ where data-type is of type DataType_Type and integer-array is a 1-d
+ array of integers that specify the size of each dimension. For exam-
+ ple,
+
+
+ variable a = @Array_Type (Double_Type, [10, 20]);
+
+
+
+ will create a 10 by 20 array of doubles and assign it to a. This
+ method of creating arrays derives its power from the fact that it is
+ more flexible than the methods discussed in this section. We shall
+ encounter it again in section ??? in the context of the array_info
+ function.
+
+
+
+ 11.2. Reshaping Arrays
+
+
+ It is sometimes possible to change the `shape' of an array using the
+ reshape function. For example, a 1-d 10 element array may be reshaped
+ into a 2-d array consisting of 5 rows and 2 columns. The only
+ restriction on the operation is that the arrays must be commensurate.
+ The reshape function follows the syntax
+
+ reshape (array-name, integer-array);
+
+
+ where array-name specifies the array to be reshaped to have the dimen-
+ sions given by integer-array, a 1-dimensional array of integers. It
+ is important to note that this does not create a new array, it simply
+ reshapes the existing array. Thus,
+
+
+ variable a = Double_Type [100];
+ reshape (a, [10, 10]);
+
+
+
+ turns a into a 10 by 10 array.
+
+
+
+ 11.3. Indexing Arrays
+
+
+ An individual element of an array may be referred to by its index.
+ For example, a[0] specifies the zeroth element of the one dimensional
+ array a, and b[3,2] specifies the element in the third row and second
+ column of the two dimensional array b. As in C array indices are
+ numbered from 0. Thus if a is a one-dimensional array of ten
+ integers, the last element of the array is given by a[9]. Using a[10]
+ would result in a range error.
+
+ A negative index may be used to index from the end of the array, with
+ a[-1] referring to the last element of a, a[-2] referring to the next
+ to the last element, and so on.
+
+ One may use the indexed value like any other variable. For example,
+ to set the third element of an integer array to 6, use
+
+
+ a[2] = 6;
+
+
+
+ Similarly, that element may be used in an expression, such as
+
+
+ y = a[2] + 7;
+
+
+
+ Unlike other S-Lang variables which inherit a type upon assignment,
+ array elements already have a type. For example, an attempt to assign
+ a string value to an element of an integer array will result in a
+ type-mismatch error.
+
+ One may use any integer expression to index an array. A simple
+ example that computes the sum of the elements of 10 element 1-d array
+ is
+
+
+ variable i, s;
+ s = 0;
+ for (i = 0; i < 10; i++) s += a[i];
+
+
+
+ However, if the built-in sum function is available (not all programs
+ using S-Lang support this), then it should be used to compute the sum
+ of an array, e.g.,
+
+
+ s = sum(a);
+
+
+
+ Unlike many other languages, S-Lang permits arrays to be indexed by
+ other integer arrays. Suppose that a is a 1-d array of 10 doubles.
+ Now consider:
+
+
+ i = [6:8];
+ b = a[i];
+
+
+
+ Here, i is a 1-dimensional range array of three integers with i[0]
+ equal to 6, i[1] equal to 7, and i[2] equal to 8. The statement b =
+ a[i]; will create a 1-d array of three doubles and assign it to b.
+ The zeroth element of b, b[0] will be set to the sixth element of a,
+ or a[6], and so on. In fact, these two simple statements are equiva-
+ lent to
+
+ b = Double_Type [3];
+ b[0] = a[6];
+ b[1] = a[7];
+ b[2] = a[8];
+
+
+
+ except that using an array of indices is not only much more conve-
+ nient, but executes much faster.
+
+ More generally, one may use an index array to specify which elements
+ are to participate in a calculation. For example, consider
+
+
+ a = Double_Type [1000];
+ i = [0:499];
+ j = [500:999];
+ a[i] = -1.0;
+ a[j] = 1.0;
+
+
+
+ This creates an array of 1000 doubles and sets the first 500 elements
+ to -1.0 and the last 500 to 1.0. Actually, one may do away with the i
+ and j variables altogether and use
+
+
+ a = Double_Type [1000];
+ a [[0:499]] = -1.0;
+ a [[500:999]] = 1.0;
+
+
+
+ It is important to understand the syntax used and, in particular, to
+ note that a[[0:499]] is not the same as a[0:499]. In fact, the latter
+ will generate a syntax error.
+
+ Often, it is convenient to use a rubber range to specify indices. For
+ example, a[[500:]] specifies all elements of a whose index is greater
+ than or equal to 500. Similarly, a[[:499]] specifies the first 500
+ elements of a. Finally, a[[:]] specifies all the elements of a;
+ however, using a[*] is more convenient.
+
+ One should be careful when using index arrays with negative elements.
+ As pointed out above, a negative index is used to index from the end
+ of the array. That is, a[-1] refers to the last element of a. How
+ should a[[[0:-1]] be interpreted? By itself, [0:-1] is an empty
+ array; hence, one might expect a[[0:-1]] to refer to no elements.
+ However, when used in an array indexing context, [0:-1] is interpreted
+ as an array indexing the first through the last elements of the array.
+ While this is a very convenient mechanism to specifiy the last 3
+ elements of an array using a[[-3:-1]], it is very easy to forget these
+ semantics.
+
+ Now consider a multi-dimensional array. For simplicity, suppose that
+ a is a 100 by 100 array of doubles. Then the expression a[0, *]
+ specifies all elements in the zeroth row. Similarly, a[*, 7]
+ specifies all elements in the seventh column. Finally, a[[3:5][6:12]]
+ specifies the 3 by 7 region consisting of rows 3, 4, and 5, and
+ columns 6 through 12 of a.
+
+ We conclude this section with a few examples.
+
+ Here is a function that computes the trace (sum of the diagonal
+ elements) of a square 2 dimensional n by n array:
+
+
+ define array_trace (a, n)
+ {
+ variable s = 0, i;
+ for (i = 0; i < n; i++) s += a[i, i];
+ return s;
+ }
+
+
+
+ This fragment creates a 10 by 10 integer array, sets its diagonal ele-
+ ments to 5, and then computes the trace of the array:
+
+
+ a = Integer_Type [10, 10];
+ for (j = 0; j < 10; j++) a[j, j] = 5;
+ the_trace = array_trace(a, 10);
+
+
+
+ We can get rid of the for loop as follows:
+
+
+ j = Integer_Type [10, 2];
+ j[*,0] = [0:9];
+ j[*,1] = [0:9];
+ a[j] = 5;
+
+
+
+ Here, the goal was to construct a 2-d array of indices that correspond
+ to the diagonal elements of a, and then use that array to index a. To
+ understand how this works, consider the middle statements. They are
+ equivalent to the following for loops:
+
+
+ variable i;
+ for (i = 0; i < 10; i++) j[i, 0] = i;
+ for (i = 0; i < 10; i++) j[i, 1] = i;
+
+
+
+ Thus, row n of j will have the value (n,n), which is precisely what
+ was sought.
+
+ Another example of this technique is the function:
+
+
+ define unit_matrix (n)
+ {
+ variable a = Integer_Type [n, n];
+ variable j = Integer_Type [n, 2];
+ j[*,0] = [0:n - 1];
+ j[*,1] = [0:n - 1];
+
+ a[j] = 1;
+ return a;
+ }
+
+ This function creates an n by n unit matrix, that is a 2-d n by n
+ array whose elements are all zero except on the diagonal where they
+ have a value of 1.
+
+
+
+ 11.4. Arrays and Variables
+
+
+ When an array is created and assigned to a variable, the interpreter
+ allocates the proper amount of space for the array, initializes it,
+ and then assigns to the variable a reference to the array. So, a
+ variable that represents an array has a value that is really a
+ reference to the array. This has several consequences, some good and
+ some bad. It is believed that the advantages of this representation
+ outweigh the disadvantages. First, we shall look at the positive
+ aspects.
+
+ When a variable is passed to a function, it is always the value of the
+ variable that gets passed. Since the value of a variable representing
+ an array is a reference, a reference to the array gets passed. One
+ major advantage of this is rather obvious: it is a fast and efficient
+ way to pass the array. This also has another consequence that is
+ illustrated by the function
+
+
+ define init_array (a, n)
+ {
+ variable i;
+
+ for (i = 0; i < n; i++) a[i] = some_function (i);
+ }
+
+
+
+ where some_function is a function that generates a scalar value to
+ initialize the ith element. This function can be used in the follow-
+ ing way:
+
+
+ variable X = Double_Type [100000];
+ init_array (X, 100000);
+
+
+
+ Since the array is passed to the function by reference, there is no
+ need to make a separate copy of the 100000 element array. As pointed
+ out above, this saves both execution time and memory. The other
+ salient feature to note is that any changes made to the elements of
+ the array within the function will be manifested in the array outside
+ the function. Of course, in this case, this is a desirable side-
+ effect.
+
+ To see the downside of this representation, consider:
+
+
+ variable a, b;
+ a = Double_Type [10];
+ b = a;
+ a[0] = 7;
+
+
+ What will be the value of b[0]? Since the value of a is really a ref-
+ erence to the array of ten doubles, and that reference was assigned to
+ b, b also refers to the same array. Thus any changes made to the ele-
+ ments of a, will also be made implicitly to b.
+
+ This begs the question: If the assignment of one variable which
+ represents an array, to another variable results in the assignment of
+ a reference to the array, then how does one make separate copies of
+ the array? There are several answers including using an index array,
+ e.g., b = a[*]; however, the most natural method is to use the
+ dereference operator:
+
+
+ variable a, b;
+ a = Double_Type [10];
+ b = @a;
+ a[0] = 7;
+
+
+
+ In this example, a separate copy of a will be created and assigned to
+ b. It is very important to note that S-Lang never implicitly derefer-
+ ences an object. So, one must explicitly use the dereference opera-
+ tor. This means that the elements of a dereferenced array are not
+ themselves dereferenced. For example, consider dereferencing an array
+ of arrays, e.g.,
+
+
+ variable a, b;
+ a = Array_Type [2];
+ a[0] = Double_Type [10];
+ a[1] = Double_Type [10];
+ b = @a;
+
+
+
+ In this example, b[0] will be a reference to the array that a[0] ref-
+ erences because a[0] was not explicitly dereferenced.
+
+
+ 11.5. Using Arrays in Computations
+
+
+
+ Many functions and operations work transparently with arrays. For
+ example, if a and b are arrays, then the sum a + b is an array whose
+ elements are formed from the sum of the corresponding elements of a
+ and b. A similar statement holds for all other binary and unary
+ operations.
+
+ Let's consider a simple example. Suppose, that we wish to solve a set
+ of n quadratic equations whose coefficients are given by the 1-d
+ arrays a, b, and c. In general, the solution of a quadratic equation
+ will be two complex numbers. For simplicity, suppose that all we
+ really want is to know what subset of the coefficients, a, b, c,
+ correspond to real-valued solutions. In terms of for loops, we can
+ write:
+
+
+
+ variable i, d, index_array;
+ index_array = Integer_Type [n];
+ for (i = 0; i < n; i++)
+ {
+ d = b[i]^2 - 4 * a[i] * c[i];
+ index_array [i] = (d >= 0.0);
+ }
+
+
+
+ In this example, the array index_array will contain a non-zero value
+ if the corresponding set of coefficients has a real-valued solution.
+ This code may be written much more compactly and with more clarity as
+ follows:
+
+
+ variable index_array = ((b^2 - 4 * a * c) >= 0.0);
+
+
+
+ S-Lang has a powerful built-in function called where. This function
+ takes an array of integers and returns a 2-d array of indices that
+ correspond to where the elements of the input array are non-zero.
+ This simple operation is extremely useful. For example, suppose a is a
+ 1-d array of n doubles, and it is desired to set to zero all elements
+ of the array whose value is less than zero. One way is to use a for
+ loop:
+
+
+ for (i = 0; i < n; i++)
+ if (a[i] < 0.0) a[i] = 0.0;
+
+
+
+ If n is a large number, this statement can take some time to execute.
+ The optimal way to achieve the same result is to use the where func-
+ tion:
+
+
+ a[where (a < 0.0)] = 0;
+
+
+
+ Here, the expression (a < 0.0) returns an array whose dimensions are
+ the same size as a but whose elements are either 1 or 0, according to
+ whether or not the corresponding element of a is less than zero. This
+ array of zeros and ones is then passed to where which returns a 2-d
+ integer array of indices that indicate where the elements of a are
+ less than zero. Finally, those elements of a are set to zero.
+
+ As a final example, consider once more the example involving the set
+ of n quadratic equations presented above. Suppose that we wish to get
+ rid of the coefficients of the previous example that generated non-
+ real solutions. Using an explicit for loop requires code such as:
+
+
+
+ variable i, j, nn, tmp_a, tmp_b, tmp_c;
+
+ nn = 0;
+ for (i = 0; i < n; i++)
+ if (index_array [i]) nn++;
+
+ tmp_a = Double_Type [nn];
+ tmp_b = Double_Type [nn];
+ tmp_c = Double_Type [nn];
+
+ j = 0;
+ for (i = 0; i < n; i++)
+ {
+ if (index_array [i])
+ {
+ tmp_a [j] = a[i];
+ tmp_b [j] = b[i];
+ tmp_c [j] = c[i];
+ j++;
+ }
+ }
+ a = tmp_a;
+ b = tmp_b;
+ c = tmp_c;
+
+
+
+ Not only is this a lot of code, it is also clumsy and error-prone.
+ Using the where function, this task is trivial:
+
+
+ variable i;
+ i = where (index_array != 0);
+ a = a[i];
+ b = b[i];
+ c = c[i];
+
+
+
+ All the examples up to now assumed that the dimensions of the array
+ were known. Although the intrinsic function length may be used to get
+ the total number of elements of an array, it cannot be used to get the
+ individual dimensions of a multi-dimensional array. However, the
+ function array_info may be used to get information about an array,
+ such as its data type and size. The function returns three values:
+ the data type, the number of dimensions, and an integer array
+ containing the size of each dimension. It may be used to determine
+ the number of rows of an array as follows:
+
+
+ define num_rows (a)
+ {
+ variable dims, type, num_dims;
+
+ (dims, num_dims, type) = array_info (a);
+ return dims[0];
+ }
+
+
+
+ The number of columns may be obtained in a similar manner:
+
+
+ define num_cols (a)
+ {
+ variable dims, type, num_dims;
+
+ (dims, num_dims, type) = array_info (a);
+ if (num_dims > 1) return dims[1];
+ return 1;
+ }
+
+
+
+ Another use of array_info is to create an array that has the same
+ number of dimensions as another array:
+
+
+ define make_int_array (a)
+ {
+ variable dims, num_dims, type;
+
+ (dims, num_dims, type) = array_info (a);
+ return @Array_Type (Integer_Type, dims);
+ }
+
+
+
+ 12. Associative Arrays
+
+
+
+ An associative array differs from an ordinary array in the sense that
+ its size is not fixed and that is indexed by a string, called the key.
+ For example, consider:
+
+
+ variable A = Assoc_Type [Integer_Type];
+ A["alpha"] = 1;
+ A["beta"] = 2;
+ A["gamma"] = 3;
+
+
+
+ Here, A represents an associative array of integers (Integer_Type) and
+ three keys have been added to the array.
+
+ As the example suggests, an associative array may be created using one
+ of the following forms:
+
+ Assoc_Type [type] Assoc_Type [type, default-value] Assoc_Type []
+
+
+ The last form returns an associative array of Any_Type objects allow-
+ ing any type of object to may be stored in the array.
+
+ The form involving a default-value is useful for associating a default
+ value for non-existent array members. This feature is explained in
+ more detail below.
+
+ There are several functions that are specially designed to work with
+ associative arrays. These include:
+
+ o assoc_get_keys, which returns an ordinary array of strings
+ containing the keys in the array.
+
+
+ o assoc_get_values, which returns an ordinary array of the values of
+ the associative array.
+
+
+ o assoc_key_exists, which can be used to determine whether or not a
+ key exists in the array.
+
+ o assoc_delete_key, which may be used to remove a key (and its value)
+ from the array.
+
+ To illustrate the use of an associative array, consider the problem of
+ counting the number of repeated occurrences of words in a list. Let
+ the word list be represented as an array of strings given by
+ word_list. The number of occurrences of each word may be stored in an
+ associative array as follows:
+
+
+
+ variable a, word;
+ a = Assoc_Type [Integer_Type];
+ foreach (word_list)
+ {
+ word = ();
+ if (0 == assoc_key_exists (a, word))
+ a[word] = 0;
+ a[word]++; % same as a[word] = a[word] + 1;
+ }
+
+
+
+ Note that assoc_key_exists was necessary to determine whether or not a
+ word was already added to the array in order to properly initialize
+ it. However, by creating the associative array with a default value
+ of 0, the above code may be simplified to
+
+
+ variable a, word;
+ a = Assoc_Type [Integer_Type, 0];
+ foreach (word_list)
+ {
+ word = ();
+ a[word]++;
+ }
+
+
+
+ 13. Structures and User-Defined Types
+
+
+
+ A structure is a heterogeneous container object, i.e., it is an object
+ with elements whose values do not have to be of the same data type.
+ The elements or fields of a structure are named, and one accesses a
+ particular field of the structure via the field name. This should be
+ contrasted with an array whose values are of the same type, and whose
+ elements are accessed via array indices.
+
+ A user-defined data type is a structure with a fixed set of fields
+ defined by the user.
+
+
+ 13.1. Defining a Structure
+
+
+ The struct keyword is used to define a structure. The syntax for this
+ operation is:
+
+ struct {field-name-1, field-name-2, ... field-name-N};
+
+
+ This creates and returns a structure with N fields whose names are
+ specified by field-name-1, field-name-2, ..., field-name-N. When a
+ structure is created, all its fields are initialized to NULL.
+
+ For example,
+
+
+ variable t = struct { city_name, population, next };
+
+
+
+ creates a structure with three fields and assigns it to the variable
+ t.
+
+ Alternatively, a structure may be created by dereferencing
+ Struct_Type. For example, the above structure may also be created
+ using one of the two forms:
+
+
+ t = @Struct_Type ("city_name", "population", "next");
+ t = @Struct_Type (["city_name", "population", "next"]);
+
+
+
+ These are useful when creating structures dynamically where one does
+ not know the name of the fields until run-time.
+
+ Like arrays, structures are passed around via a references. Thus, in
+ the above example, the value of t is a reference to the structure.
+ This means that after execution of
+
+
+ variable u = t;
+
+
+
+ both t and u refer to the same structure, since only the reference was
+ used in the assignment. To actually create a new copy of the struc-
+ ture, use the dereference operator, e.g.,
+ variable u = @t;
+
+
+
+ 13.2. Accessing the Fields of a Structure
+
+
+ The dot (.) operator is used to specify the particular field of
+ structure. If s is a structure and field_name is a field of the
+ structure, then s.field_name specifies that field of s. This
+ specification can be used in expressions just like ordinary variables.
+ Again, consider
+
+
+ variable t = struct { city_name, population, next };
+
+
+
+ described in the last section. Then,
+
+
+ t.city_name = "New York";
+ t.population = 13000000;
+ if (t.population > 200) t = t.next;
+
+
+
+ are all valid statements involving the fields of t.
+
+
+ 13.3. Linked Lists
+
+
+ One of the most important uses of structures is to create a dynamic
+ data structure such as a linked-list. A linked-list is simply a chain
+ of structures that are linked together such that one structure in the
+ chain is the value of a field of the previous structure in the chain.
+ To be concrete, consider the structure discussed earlier:
+
+
+ variable t = struct { city_name, population, next };
+
+
+
+ and suppose that we desire to create a list of such structures. The
+ purpose of the next field is to provide the link to the next structure
+ in the chain. Suppose that there exists a function, read_next_city,
+ that reads city names and populations from a file. Then we can create
+ the list via:
+
+
+
+ define create_population_list ()
+ {
+ variable city_name, population, list_root, list_tail;
+ variable next;
+
+ list_root = NULL;
+ while (read_next_city (&city_name, &population))
+ {
+ next = struct {city_name, population, next };
+
+ next.city_name = city_name;
+ next.population = population;
+ next.next = NULL;
+
+ if (list_root == NULL)
+ list_root = next;
+ else
+ list_tail.next = next;
+
+ list_tail = next;
+ }
+ return list_root;
+ }
+
+
+
+ In this function, the variables list_root and list_tail represent the
+ beginning and end of the list, respectively. As long as read_next_city
+ returns a non-zero value, a new structure is created, initialized, and
+ then appended to the list via the next field of the list_tail struc-
+ ture. On the first time through the loop, the list is created via the
+ assignment to the list_root variable.
+
+ This function may be used as follows:
+
+
+ variable Population_List = create_population_list ();
+ if (Population_List == NULL) error ("List is empty");
+
+
+
+ We can create other functions that manipulate the list. An example is
+ a function that finds the city with the largest population:
+
+
+ define get_largest_city (list)
+ {
+ variable largest;
+
+ largest = list;
+ while (list != NULL)
+ {
+ if (list.population > largest.population)
+ largest = list;
+ list = list.next;
+ }
+ return largest.city_name;
+ }
+
+ vmessage ("%s is the largest city in the list",
+ get_largest_city (Population_List)));
+
+
+
+ The get_largest_city is a typical example of how one traverses a lin-
+ ear linked-list by starting at the head of the list and successively
+ moves to the next element of the list via the next field.
+
+ In the previous example, a while loop was used to traverse the linked
+ list. It is faster to use a foreach loop for this:
+
+
+ define get_largest_city (list)
+ {
+ variable largest, elem;
+
+ largest = list;
+ foreach (list)
+ {
+ elem = ();
+ if (item.population > largest.population)
+ largest = item;
+ }
+ return largest.city_name;
+ }
+
+
+
+ Here a foreach loop has been used to walk the list via its next field.
+ If the field name was not next, then it would have been necessary to
+ use the using form of the foreach statement. For example, if the
+ field name implementing the linked list was next_item, then
+
+
+ foreach (list) using ("next_item")
+ {
+ elem = ();
+ .
+ .
+ }
+
+
+
+ would have been used. In other words, unless otherwise indicated via
+ the using clause, foreach walks the list using a field named next.
+
+ Now consider a function that sorts the list according to population.
+ To illustrate the technique, a bubble-sort will be used, not because
+ it is efficient, it is not, but because it is simple and intuitive.
+
+
+
+ define sort_population_list (list)
+ {
+ variable changed;
+ variable node, next_node, last_node;
+ do
+ {
+ changed = 0;
+ node = list;
+ next_node = node.next;
+ last_node = NULL;
+ while (next_node != NULL)
+ {
+ if (node.population < next_node.population)
+ {
+ % swap node and next_node
+ node.next = next_node.next;
+ next_node.next = node;
+ if (last_node != NULL)
+ last_node.next = next_node;
+
+ if (list == node) list = next_node;
+ node = next_node;
+ next_node = node.next;
+ changed++;
+ }
+ last_node = node;
+ node = next_node;
+ next_node = next_node.next;
+ }
+ }
+ while (changed);
+
+ return list;
+ }
+
+
+
+ Note the test for equality between list and node, i.e.,
+
+
+ if (list == node) list = next_node;
+
+
+
+ It is important to appreciate the fact that the values of these vari-
+ ables are references to structures, and that the comparison only com-
+ pares the references and not the actual structures they reference. If
+ it were not for this, the algorithm would fail.
+
+
+ 13.4. Defining New Types
+
+
+ A user-defined data type may be defined using the typedef keyword. In
+ the current implementation, a user-defined data type is essentially a
+ structure with a user-defined set of fields. For example, in the
+ previous section a structure was used to represent a city/population
+ pair. We can define a data type called Population_Type to represent
+ the same information:
+
+
+
+ typedef struct
+ {
+ city_name,
+ population
+ } Population_Type;
+
+
+
+ This data type can be used like all other data types. For example, an
+ array of Population_Type types can be created,
+
+
+ variable a = Population_Type[10];
+
+
+
+ and `populated' via expressions such as
+
+
+ a[0].city_name = "Boston";
+ a[0].population = 2500000;
+
+
+
+ The new type Population_Type may also be used with the typeof func-
+ tion:
+
+
+ if (Population_Type = typeof (a)) city = a.city_name;
+
+
+
+ The dereference @ may be used to create an instance of the new type:
+
+
+ a = @Population_Type;
+ a.city_name = "Calcutta";
+ a.population = 13000000;
+
+
+
+ 14. Error Handling
+
+
+
+ Many intrinsic functions signal errors in the event of failure. User
+ defined functions may also generate an error condition via the error
+ function. Depending upon the severity of the error, it can be caught
+ and cleared using a construct called an error-block.
+
+
+ 14.1. Error-Blocks
+
+
+ When the interpreter encounters a recoverable run-time error, it will
+ return to top-level by unwinding its function call stack. Any error-
+ blocks that it encounters as part of this unwinding process will get
+ executed. Errors such as syntax errors and memory allocation errors
+ are not recoverable, and error-blocks will not get executed when such
+ errors are encountered.
+
+ An error-block is defined using the syntax
+
+
+ ERROR_BLOCK { statement-list }
+
+
+
+ where statement-list represents a list of statements that comprise the
+ error-block. A simple example of an error-block is
+
+
+ define simple (a)
+ {
+ ERROR_BLOCK { message ("error-block executed"); }
+ if (a) error ("Triggering Error");
+ message ("hello");
+ }
+
+
+
+ Executing this function via simple(0) will result in the message
+ "hello". However, calling it using simple(1) will generate an error
+ that will be caught, but not cleared, by the error-block and the
+ "error-block executed" message will result.
+
+ Error-blocks are never executed unless triggered by an error. The
+ only exception to this is when the user explicitly indicates that the
+ error-block in scope should execute. This is indicated by the special
+ keyword EXECUTE_ERROR_BLOCK. For example, simple could be recoded as
+
+
+ define simple (a)
+ {
+ variable err_string = "error-block executed";
+ ERROR_BLOCK { message (err_string); }
+ if (a) error ("Triggering Error");
+ err_string = "hello";
+ EXECUTE_ERROR_BLOCK;
+ }
+
+
+
+ Please note that EXECUTE_ERROR_BLOCK does not initiate an error
+ condition; it simply causes the error-block to be executed and control
+ will pass onto the next statement following the EXECUTE_ERROR_BLOCK
+ statement.
+
+
+ 14.2. Clearing Errors
+
+
+ Once an error has been caught by an error-block, the error can be
+ cleared by the _clear_error function. After the error has been
+ cleared, execution will resume at the next statement at the level of
+ the error block following the statement that generated the error. For
+ example, consider:
+
+
+ define make_error ()
+ {
+ error ("Error condition created.");
+ message ("This statement is not executed.");
+ }
+
+ define test ()
+ {
+ ERROR_BLOCK
+ {
+ _clear_error ();
+ }
+ make_error ();
+ message ("error cleared.");
+ }
+
+
+
+ Calling test will trigger an error in the make_error function, but
+ will get cleared in the test function. The call-stack will unwind
+ from make_error back into test where the error-block will get exe-
+ cuted. As a result, execution resumes after the statement that makes
+ the call to make_error since this statement is at the same level as
+ the error-block that cleared the error.
+
+ Here is another example that illustrates how multiple error-blocks
+ work:
+
+
+
+ define example ()
+ {
+ variable n = 0, s = "";
+ variable str;
+
+ ERROR_BLOCK {
+ str = sprintf ("s=%s,n=%d", s, n);
+ _clear_error ();
+ }
+
+ forever
+ {
+ ERROR_BLOCK {
+ s += "0";
+ _clear_error ();
+ }
+
+ if (n == 0) error ("");
+
+ ERROR_BLOCK {
+ s += "1";
+ }
+
+ if (n == 1) error ("");
+ n++;
+ }
+ return str;
+ }
+
+
+
+ Here, three error-blocks have been declared. One has been declared
+ outside the forever loop and the other two have been declared inside
+ the forever loop. Each time through the loop, the variable n is
+ incremented and a different error-block is triggered. The error-block
+ that gets triggered is the last one encountered, since that will be
+ the one in scope. On the first time through the loop, n will be zero
+ and the first error-block in the loop will get executed. This error
+ block clears the error and execution resumes following the if state-
+ ment that triggered the error. The variable n will get incremented to
+ 1 and, on the second cycle through the loop the second if statement
+ will trigger an error causing the second error-block to execute. This
+ time, the error is not cleared and the call-stack unwinds out of the
+ forever loop, at which point the error-block outside the loop is in
+ scope, causing it to execute. This error-block prints out the values
+ of the variables s and n. It will clear the error and execution
+ resumes on the statement following the forever loop. The result of
+ this complicated series of events is that the function will return the
+ string "s=01,n=1".
+
+
+
+ 15. Loading Files: evalfile and autoload
+
+
+
+ 16. File Input/Output
+
+
+
+ S-Lang provides built-in supports for two different I/O facilities.
+ The simplest interface is modeled upon the C language stdio streams
+ interface and consists of functions such as fopen, fgets, etc. The
+ other interface is modeled on a lower level POSIX interface consisting
+ of functions such as open, read, etc. In addition to permitting more
+ control, the lower level interface permits one to access network
+ objects as well as disk files.
+
+
+ 16.1. Input/Output via stdio
+
+
+ 16.1.1. Stdio Overview
+
+ The stdio interface consists of the following functions:
+
+ o fopen, which opens a file for read or writing.
+
+ o fclose, which closes a file opened by fopen.
+
+ o fgets, used to read a line from the file.
+
+ o fputs, which writes text to the file.
+
+ o fprintf, used to write formatted text to the file.
+
+ o fwrite, which may be used to write objects to the file.
+
+ o fread, which reads a specified number of objects from the file.
+
+ o feof, which is used to test whether the file pointer is at the end
+ of the file.
+
+ o ferror, which is used to see whether or not the stream associated
+ with the file has an error.
+
+
+ o clearerr, which clears the end-of-file and error indicators for the
+ stream.
+
+ o fflush, used to force all buffered data associated with the stream
+ to be written out.
+
+ o ftell, which is used to query the file position indicator of the
+ stream.
+
+
+ o fseek, which is used to set the position of the file position
+ indicator of the stream.
+
+ o fgetslines, which reads all the lines in a text file and returns
+ them as an array of strings.
+
+ In addition, the interface supports the popen and pclose functions on
+ systems where the corresponding C functions are available.
+
+ Before reading or writing to a file, it must first be opened using the
+ fopen function. The only exceptions to this rule involves use of the
+ pre-opened streams: stdin, stdout, and stderr. fopen accepts two
+ arguments: a file name and a string argument that indicates how the
+ file is to be opened, e.g., for reading, writing, update, etc. It
+ returns a File_Type stream object that is used as an argument to all
+ other functions of the stdio interface. Upon failure, it returns
+ NULL. See the reference manual for more information about fopen.
+
+
+ 16.1.2. Stdio Examples
+
+
+ In this section, some simple examples of the use of the stdio
+ interface is presented. It is important to realize that all the
+ functions of the interface return something, and that return value
+ must be dealt with.
+
+ The first example involves writing a function to count the number of
+ lines in a text file. To do this, we shall read in the lines, one by
+ one, and count them:
+
+
+ define count_lines_in_file (file)
+ {
+ variable fp, line, count;
+
+ fp = fopen (file, "r"); % Open the file for reading
+ if (fp == NULL)
+ verror ("%s failed to open", file);
+
+ count = 0;
+ while (-1 != fgets (&line, fp))
+ count++;
+
+ () = fclose (fp);
+ return count;
+ }
+
+
+
+ Note that &line was passed to the fgets function. When fgets returns,
+ line will contain the line of text read in from the file. Also note
+ how the return value from fclose was handled.
+
+ Although the preceding example closed the file via fclose, there is no
+ need to explicitly close a file because S-Lang will automatically
+ close the file when it is no longer referenced. Since the only
+ variable to reference the file is fp, it would have automatically been
+ closed when the function returned.
+
+ Suppose that it is desired to count the number of characters in the
+ file instead of the number of lines. To do this, the while loop could
+ be modified to count the characters as follows:
+
+
+ while (-1 != fgets (&line, fp))
+ count += strlen (line);
+
+
+
+ The main difficulty with this approach is that it will not work for
+ binary files, i.e., files that contain null characters. For such
+ files, the file should be opened in binary mode via
+
+
+ fp = fopen (file, "rb");
+
+
+
+ and then the data read in using the fread function:
+
+
+ while (-1 != fread (&line, Char_Type, 1024, fp))
+ count += bstrlen (line);
+
+
+
+ The fread function requires two additional arguments: the type of
+ object to read (Char_Type in the case), and the number of such objects
+ to read. The function returns the number of objects actually read, or
+ -1 upon failure. The bstrlen function was used to compute the length
+ of line because for Char_Type or UChar_Type objects, the fread func-
+ tion assigns a binary string (BString_Type) to line.
+
+ The foreach construct also works with File_Type objects. For example,
+ the number of characters in a file may be counted via
+
+
+ foreach (fp) using ("char")
+ {
+ ch = ();
+ count++;
+ }
+
+
+
+ To count the number of lines, one can use:
+
+
+ foreach (fp) using ("line")
+ {
+ line = ();
+ num_lines++;
+ count += strlen (line);
+ }
+
+
+
+ Often one is not interested in trailing whitespace in the lines of a
+ file. To have trailing whitespace automatically stripped from the
+ lines as they are read in, use the "wsline" form, e.g.,
+
+
+ foreach (fp) using ("wsline")
+ {
+ line = ();
+ .
+ .
+ }
+
+
+
+ Finally, it should be mentioned that none of these examples should be
+ used to count the number of bytes in a file when that information is
+ more readily accessible by another means. For example, it is
+ preferable to get this information via the stat_file function:
+
+
+
+ define count_chars_in_file (file)
+ {
+ variable st;
+
+ st = stat_file (file);
+ if (st == NULL)
+ error ("stat_file failed.");
+ return st.st_size;
+ }
+
+
+
+ 16.2. POSIX I/O
+
+
+
+ 16.3. Advanced I/O techniques
+
+
+ The previous examples illustrate how to read and write objects of a
+ single data-type from a file, e.g.,
+
+
+ num = fread (&a, Double_Type, 20, fp);
+
+
+
+ would result in a Double_Type[num] array being assigned to a if suc-
+ cessful. However, suppose that the binary data file consists of num-
+ bers in a specified byte-order. How can one read such objects with
+ the proper byte swapping? The answer is to use the fread function to
+ read the objects as Char_Type and then unpack the resulting string
+ into the specified data type, or types. This process is facilitated
+ using the pack and unpack functions.
+
+ The pack function follows the syntax
+
+ BString_Type pack (format-string, item-list);
+
+
+ and combines the objects in the item-list according to format-string
+ into a binary string and returns the result. Likewise, the unpack
+ function may be used to convert a binary string into separate data
+ objects:
+
+ (variable-list) = unpack (format-string, binary-string);
+
+
+ The format string consists of one or more data-type specification
+ characters, and each may be followed by an optional decimal length
+ specifier. Specifically, the data-types are specified according to the
+ following table:
+
+
+
+ c char
+ C unsigned char
+ h short
+ H unsigned short
+ i int
+ I unsigned int
+ l long
+ L unsigned long
+ j 16 bit int
+ J 16 unsigned int
+ k 32 bit int
+ K 32 bit unsigned int
+ f float
+ d double
+ F 32 bit float
+ D 64 bit float
+ s character string, null padded
+ S character string, space padded
+ x a null pad character
+
+
+
+ A decimal length specifier may follow the data-type specifier. With
+ the exception of the s and S specifiers, the length specifier indi-
+ cates how many objects of that data type are to be packed or unpacked
+ from the string. When used with the s or S specifiers, it indicates
+ the field width to be used. If the length specifier is not present,
+ the length defaults to one.
+
+ With the exception of c, C, s, S, and x, each of these may be prefixed
+ by a character that indicates the byte-order of the object:
+
+
+ > big-endian order (network order)
+ < little-endian order
+ = native byte-order
+
+
+
+ The default is native byte order.
+
+ Here are a few examples that should make this more clear:
+
+
+ a = pack ("cc", 'A', 'B'); % ==> a = "AB";
+ a = pack ("c2", 'A', 'B'); % ==> a = "AB";
+ a = pack ("xxcxxc", 'A', 'B'); % ==> a = "\0\0A\0\0B";
+ a = pack ("h2", 'A', 'B'); % ==> a = "\0A\0B" or "\0B\0A"
+ a = pack (">h2", 'A', 'B'); % ==> a = "\0\xA\0\xB"
+ a = pack ("<h2", 'A', 'B'); % ==> a = "\0B\0A"
+ a = pack ("s4", "AB", "CD"); % ==> a = "AB\0\0"
+ a = pack ("s4s2", "AB", "CD"); % ==> a = "AB\0\0CD"
+ a = pack ("S4", "AB", "CD"); % ==> a = "AB "
+ a = pack ("S4S2", "AB", "CD"); % ==> a = "AB CD"
+
+
+
+ When unpacking, if the length specifier is greater than one, then an
+ array of that length will be returned. In addition, trailing
+ whitespace and null character are stripped when unpacking an object
+ given by the S specifier. Here are a few examples:
+
+
+ (x,y) = unpack ("cc", "AB"); % ==> x = 'A', y = 'B'
+ x = unpack ("c2", "AB"); % ==> x = ['A', 'B']
+ x = unpack ("x<H", "\0\xAB\xCD"); % ==> x = 0xCDABuh
+ x = unpack ("xxs4", "a b c\0d e f"); % ==> x = "b c\0"
+ x = unpack ("xxS4", "a b c\0d e f"); % ==> x = "b c"
+
+
+
+ 16.3.1. Example: Reading /var/log/wtmp
+
+
+ Consider the task of reading the Unix system file /var/log/utmp, which
+ contains login records about who logged onto the system. This file
+ format is documented in section 5 of the online Unix man pages, and
+ consists of a sequence of entries formatted according to the C
+ structure utmp defined in the utmp.h C header file. The actual
+ details of the structure may vary from one version of Unix to the
+ other. For the purposes of this example, consider its definition
+ under the Linux operating system running on an Intel processor:
+
+
+ struct utmp {
+ short ut_type; /* type of login */
+ pid_t ut_pid; /* pid of process */
+ char ut_line[12]; /* device name of tty - "/dev/" */
+ char ut_id[2]; /* init id or abbrev. ttyname */
+ time_t ut_time; /* login time */
+ char ut_user[8]; /* user name */
+ char ut_host[16]; /* host name for remote login */
+ long ut_addr; /* IP addr of remote host */
+ };
+
+
+
+ On this system, pid_t is defined to be an int and time_t is a long.
+ Hence, a format specifier for the pack and unpack functions is easily
+ constructed to be:
+
+
+ "h i S12 S2 l S8 S16 l"
+
+
+
+ However, this particular definition is naive because it does not allow
+ for structure padding performed by the C compiler in order to align
+ the data types on suitable word boundaries. Fortunately, the intrin-
+ sic function pad_pack_format may be used to modify a format by adding
+ the correct amount of padding in the right places. In fact,
+ pad_pack_format applied to the above format on an Intel-based Linux
+ system produces the result:
+
+
+ "h x2 i S12 S2 x2 l S8 S16 l"
+
+
+
+ Here we see that 4 bytes of padding were added.
+
+ The other missing piece of information is the size of the structure.
+ This is useful because we would like to read in one structure at a
+ time using the fread function. Knowing the size of the various data
+ types makes this easy; however it is even easier to use the
+ sizeof_pack intrinsic function, which returns the size (in bytes) of
+ the structure described by the pack format.
+
+ So, with all the pieces in place, it is rather straightforward to
+ write the code:
+
+
+ variable format, size, fp, buf;
+
+ typedef struct
+ {
+ ut_type, ut_pid, ut_line, ut_id,
+ ut_time, ut_user, ut_host, ut_addr
+ } UTMP_Type;
+
+ format = pad_pack_format ("h i S12 S2 l S8 S16 l");
+ size = sizeof_pack (format);
+
+ define print_utmp (u)
+ {
+
+ () = fprintf (stdout, "%-16s %-12s %-16s %s\n",
+ u.ut_user, u.ut_line, u.ut_host, ctime (u.ut_time));
+ }
+
+
+ fp = fopen ("/var/log/utmp", "rb");
+ if (fp == NULL)
+ error ("Unable to open utmp file");
+
+ () = fprintf (stdout, "%-16s %-12s %-16s %s\n",
+ "USER", "TTY", "FROM", "LOGIN@");
+
+ variable U = @UTMP_Type;
+
+ while (-1 != fread (&buf, Char_Type, size, fp))
+ {
+ set_struct_fields (U, unpack (format, buf));
+ print_utmp (U);
+ }
+
+ () = fclose (fp);
+
+
+
+ A few comments about this example are in order. First of all, note
+ that a new data type called UTMP_Type was created, although this was
+ not really necessary. We also opened the file in binary mode, but
+ this too is optional under a Unix system where there is no distinction
+ between binary and text modes. The print_utmp function does not print
+ all of the structure fields. Finally, last but not least, the return
+ values from fprintf and fclose were dealt with.
+
+
+
+ 17. Debugging
+
+
+
+ The current implementation provides no support for an interactive
+ debugger, although a future version will. Nevertheless, S-Lang has
+ several features that aid the programmer in tracking down problems,
+ including function call tracebacks and the tracing of function calls.
+ However, the biggest debugging aid stems from the fact that the
+ language is interpreted permitting one to easily add debugging
+ statements to the code.
+
+ To enable debugging information, add the lines
+
+
+ _debug_info = 1;
+ _traceback = 1;
+
+
+
+ to the top of the source file of the code containing the bug and the
+ reload the file. Setting the _debug_info variable to 1 causes line
+ number information to be compiled into the functions when the file is
+ loaded. The _traceback variable controls whether or not traceback
+ information should be generated. If it is set to 1, the values of
+ local variables will be dumped when the traceback is generated. Set-
+ ting this variable to -1 will cause only function names to be reported
+ in the traceback.
+
+ Here is an example of a traceback report:
+
+
+ S-Lang Traceback: error
+ S-Lang Traceback: verror
+ S-Lang Traceback: (Error occurred on line 65)
+ S-Lang Traceback: search_generic_search
+ Local Variables:
+ $0: Type: String_Type, Value: "Search forward:"
+ $1: Type: Integer_Type, Value: 1
+ $2: Type: Ref_Type, Value: _function_return_1
+ $3: Type: String_Type, Value: "abcdefg"
+ $4: Type: Integer_Type, Value: 1
+ S-Lang Traceback: (Error occurred on line 72)
+ S-Lang Traceback: search_forward
+
+
+
+ There are several ways to read this report; perhaps the simplest is to
+ read it from the bottom. This report says that on line 72, the
+ search_forward function called the search_generic_search function. On
+ line 65 it called the verror function, which called error. The
+ search_generic_search function contains 5 local variables and are rep-
+ resented symbolically as $0 through $4.
+
+
+
+ 18. Regular Expressions
+
+
+ The S-Lang library includes a regular expression (RE) package that may
+ be used by an application embedding the library. The RE syntax should
+ be familiar to anyone acquainted with regular expressions. In this
+ section the syntax of the S-Lang regular expressions is discussed.
+
+
+ 18.1. S-Lang RE Syntax
+
+
+ A regular expression specifies a pattern to be matched against a
+ string, and has the property that the contcatenation of two REs is
+ also a RE.
+
+ The S-Lang library supports the following standard regular
+ expressions:
+
+
+ . match any character except newline
+ * matches zero or more occurences of previous RE
+ + matches one or more occurences of previous RE
+ ? matches zero or one occurence of previous RE
+ ^ matches beginning of a line
+ $ matches end of line
+ [ ... ] matches any single character between brackets.
+ For example, [-02468] matches `-' or any even digit.
+ and [-0-9a-z] matches `-' and any digit between 0 and 9
+ as well as letters a through z.
+ \< Match the beginning of a word.
+ \> Match the end of a word.
+ \( ... \)
+ \1, \2, ..., \9 Matches the match specified by nth \( ... \)
+ expression.
+
+
+
+ In addition the following extensions are also supported:
+
+
+ \c turn on case-sensitivity (default)
+ \C turn off case-sensitivity
+ \d match any digit
+ \e match ESC char
+
+
+
+ Here are some simple examples:
+
+ "^int " matches the "int " at the beginning of a line.
+
+ "\<money\>" matches "money" but only if it appears as a separate word.
+
+ "^$" matches an empty line.
+
+ A more complex pattern is
+
+
+ "\(\<[a-zA-Z]+\>\)[ ]+\1\>"
+
+
+
+ which matches any word repeated consecutively. Note how the grouping
+ operators \( and \) are used to define the text matched by the
+ enclosed regular expression, and then subsequently referred to \1.
+
+ Finally, remember that when used in string literals either in the S-
+ Lang language or in the C language, care must be taken to "double-up"
+ the '\' character since both languages treat it as an escape
+ character.
+
+
+ 18.2. Differences between S-Lang and egrep REs
+
+
+ There are several differences between S-Lang regular expressions and,
+ e.g., egrep regular expressions.
+
+ The most notable difference is that the S-Lang regular expressions do
+ not support the OR operator | in expressions. This means that "a|b"
+ or "a\|b" do not have the meaning that they have in regular expression
+ packages that support egrep-style expressions.
+
+ The other main difference is that while S-Lang regular expressions
+ support the grouping operators \( and \), they are only used as a
+ means of specifying the text that is matched. That is, the expression
+
+
+ "@\([a-z]*\)@.*@\1@"
+
+
+
+ matches "xxx@abc@silly@abc@yyy", where the pattern \1 matches the text
+ enclosed by the \( and \) expressions. However, in the current imple-
+ mentation, the grouping operators are not used to group regular
+ expressions to form a single regular expression. Thus expression such
+ as "\(hello\)*" is not a pattern to match zero or more occurances of
+ "hello" as it is in e.g., egrep.
+
+ One question that comes up from time to time is why doesn't S-Lang
+ simply employ some posix-compatible regular expression library. The
+ simple answer is that, at the time of this writing, none exists that
+ is available across all the platforms that the S-Lang library supports
+ (Unix, VMS, OS/2, win32, win16, BEOS, MSDOS, and QNX) and can be
+ distributed under both the GNU and Artistic licenses. It is
+ particularly important that the library and the interpreter support a
+ common set of regular expressions in a platform independent manner.
+
+
+
+ 19. Future Directions
+
+
+
+ Several new features or enhancements to the S-Lang language are
+ planned for the next major release. In no particular order, these
+ include:
+
+ o An interactive debugging facility.
+
+ o Function qualifiers. These entities should already be familiar to
+ VMS users or to those who are familiar with the IDL language.
+ Basically, a qualifier is an optional argument that is passed to a
+ function, e.g., plot(X,Y,/logx). Here /logx is a qualifier that
+ specifies that the plot function should use a log scale for x.
+
+ o File local variables and functions. A file local variable or
+ function is an object that is global to the file that defines it.
+
+ o Multi-threading. Currently the language does not support multiple
+ threads.
+
+
+
+ A. Copyright
+
+ The S-Lang library is distributed under two copyrights: the GNU Genral
+ Public License, and the Artistic License. Any program that uses the
+ interpreter must adhere to rules of one of these licenses.
+
+
+ A.1. The GNU Public License
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License
+ is intended to guarantee your freedom to share and change free soft-
+ ware--to make sure the software is free for all its users. This Gen-
+ eral Public License applies to most of the Free Software Foundation's
+ software and to any other program whose authors commit to using it.
+ (Some other Free Software Foundation software is covered by the GNU
+ Library General Public License instead.) You can apply it to your
+ programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if
+ you distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on,
+ we want its recipients to know that what they have is not the
+ original, so that any problems introduced by others will not reflect
+ on the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at
+ all.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term "modification".) Each licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether
+ that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a
+ fee.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above,
+ provided that you also meet all of these conditions:
+
+
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+
+ These requirements apply to the modified work as a whole. If identi-
+ fiable sections of that work are not derived from the Program, and can
+ be reasonably considered independent and separate works in themselves,
+ then this License, and its terms, do not apply to those sections when
+ you distribute them as separate works. But when you distribute the
+ same sections as part of a whole which is a work based on the Program,
+ the distribution of the whole must be on the terms of this License,
+ whose permissions for other licensees extend to the entire whole, and
+ thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to con-
+ trol compilation and installation of the executable. However, as a
+ special exception, the source code distributed need not include any-
+ thing that is normally distributed (in either source or binary form)
+ with the major components (compiler, kernel, and so on) of the operat-
+ ing system on which the executable runs, unless that component itself
+ accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded. In such case, this License incorporates
+ the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and
+ "any later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a
+ version number of this License, you may choose any version ever
+ published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by
+ the Free Software Foundation, write to the Free Software Foundation;
+ we sometimes make exceptions for this. Our decision will be guided by
+ the two goals of preserving the free status of all derivatives of our
+ free software and of promoting the sharing and reuse of software
+ generally.
+
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+
+
+ The hypothetical commands `show w' and `show c' should show the appro-
+ priate parts of the General Public License. Of course, the commands
+ you use may be called something other than `show w' and `show c'; they
+ could even be mouse-clicks or menu items--whatever suits your program.
+
+ You should also get your employer (if you work as a programmer) or
+ your school, if any, to sign a "copyright disclaimer" for the program,
+ if necessary. Here is a sample; alter the names:
+
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+
+
+ This General Public License does not permit incorporating your program
+ into proprietary programs. If your program is a subroutine library,
+ you may consider it more useful to permit linking proprietary applica-
+ tions with the library. If this is what you want to do, use the GNU
+ Library General Public License instead of this License.
+
+
+ A.2. The Artistic License
+
+
+
+ The "Artistic License"
+
+ Preamble
+
+
+
+ The intent of this document is to state the conditions under which a
+ Package may be copied, such that the Copyright Holder maintains some
+ semblance of artistic control over the development of the package,
+ while giving the users of the package the right to use and distribute
+ the Package in a more-or-less customary fashion, plus the right to
+ make reasonable modifications.
+
+ Definitions:
+
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+
+
+ 1. You may make and give away verbatim copies of the source form of
+ the Standard Version of this Package without restriction, provided
+ that you duplicate all of the original copyright notices and associ-
+ ated disclaimers.
+
+ 2. You may apply bug fixes, portability fixes and other modifications
+ derived from the Public Domain or from the Copyright Holder. A
+ Package modified in such a way shall still be considered the Standard
+ Version.
+
+ 3. You may otherwise modify your copy of this Package in any way,
+ provided that you insert a prominent notice in each changed file
+ stating how and when you changed that file, and provided that you do
+ at least ONE of the following:
+
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+ 4. You may distribute the programs of this Package in object code or
+ executable form, provided that you do at least ONE of the following:
+
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+ 5. You may charge a reasonable copying fee for any distribution of
+ this Package. You may charge any fee you choose for support of this
+ Package. You may not charge a fee for this Package itself. However,
+ you may distribute this Package in aggregate with other (possibly com-
+ mercial) programs as part of a larger (possibly commercial) software
+ distribution provided that you do not advertise this Package as a
+ product of your own. You may embed this Package's interpreter within
+ an executable of yours (by linking); this shall be construed as a mere
+ form of aggregation, provided that the complete Standard Version of
+ the interpreter is so embedded.
+
+ 6. The scripts and library files supplied as input to or produced as
+ output from the programs of this Package do not automatically fall
+ under the copyright of this Package, but belong to whomever generated
+ them, and may be sold commercially, and may be aggregated with this
+ Package. If such scripts or library files are aggregated with this
+ Package via the so-called "undump" or "unexec" methods of producing a
+ binary executable image, then distribution of such an image shall
+ neither be construed as a distribution of this Package nor shall it
+ fall under the restrictions of Paragraphs 3 and 4, provided that you
+ do not represent such an executable image as a Standard Version of
+ this Package.
+ 7. C subroutines (or comparably compiled subroutines in other
+ languages) supplied by you and linked into this Package in order to
+ emulate subroutines and variables of the language defined by this
+ Package shall not be considered part of this Package, but are the
+ equivalent of input as in Paragraph 6, provided these subroutines do
+ not change the language in any way that would cause it to fail the
+ regression tests for the language.
+
+ 8. Aggregation of this Package with a commercial distribution is
+ always permitted provided that the use of this Package is embedded;
+ that is, when no overt attempt is made to make this Package's
+ interfaces visible to the end user of the commercial distribution.
+ Such use shall not be construed as a distribution of this Package.
+
+ 9. The name of the Copyright Holder may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+ Table of Contents
+
+
+ 1. Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 1.1. A Brief History of S-Lang . . . . . . . . . . . . . . . . . . 4
+ 1.2. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 4
+ 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 2.1. Language Features . . . . . . . . . . . . . . . . . . . . . . 6
+ 2.2. Data Types and Operators . . . . . . . . . . . . . . . . . . 6
+ 2.3. Statements and Functions . . . . . . . . . . . . . . . . . . 6
+ 2.4. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 7
+ 2.5. Run-Time Library . . . . . . . . . . . . . . . . . . . . . . 7
+ 2.6. Input/Output . . . . . . . . . . . . . . . . . . . . . . . . 7
+ 2.7. Obtaining S-Lang . . . . . . . . . . . . . . . . . . . . . . 8
+ 3. Overview of the Language . . . . . . . . . . . . . . . . . . . 9
+ 3.1. Variables and Functions . . . . . . . . . . . . . . . . . . . 9
+ 3.2. Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
+ 3.3. Referencing and Dereferencing . . . . . . . . . . . . . . . . 11
+ 3.4. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
+ 3.5. Structures and User-Defined Types . . . . . . . . . . . . . . 15
+ 3.6. Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . 16
+ 4. Data Types and Literal Constants . . . . . . . . . . . . . . . 18
+ 4.1. Predefined Data Types . . . . . . . . . . . . . . . . . . . . 18
+ 4.1.1. Integers . . . . . . . . . . . . . . . . . . . . . . . . . 18
+ 4.1.2. Floating Point Numbers . . . . . . . . . . . . . . . . . . 19
+ 4.1.3. Complex Numbers . . . . . . . . . . . . . . . . . . . . . . 19
+ 4.1.4. Strings . . . . . . . . . . . . . . . . . . . . . . . . . . 20
+ 4.1.5. Null_Type . . . . . . . . . . . . . . . . . . . . . . . . . 21
+ 4.1.6. Ref_Type . . . . . . . . . . . . . . . . . . . . . . . . . 21
+ 4.1.7. Array_Type and Struct_Type . . . . . . . . . . . . . . . . 22
+ 4.1.8. DataType_Type Type . . . . . . . . . . . . . . . . . . . . 22
+ 4.2. Typecasting: Converting from one Type to Another . . . . . . 23
+ 5. Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . 25
+ 6. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
+ 7. Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
+ 7.1. Unary Operators . . . . . . . . . . . . . . . . . . . . . . . 28
+ 7.2. Binary Operators . . . . . . . . . . . . . . . . . . . . . . 28
+ 7.2.1. Arithmetic Operators . . . . . . . . . . . . . . . . . . . 29
+ 7.2.2. Relational Operators . . . . . . . . . . . . . . . . . . . 29
+ 7.2.3. Boolean Operators . . . . . . . . . . . . . . . . . . . . . 29
+ 7.2.4. Bitwise Operators . . . . . . . . . . . . . . . . . . . . . 30
+ 7.2.5. Namespace operator . . . . . . . . . . . . . . . . . . . . 31
+ 7.2.6. Operator Precedence . . . . . . . . . . . . . . . . . . . . 31
+ 7.2.7. Binary Operators and Functions Returning Multiple Val-
+ ues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
+ 7.3. Mixing Integer and Floating Point Arithmetic . . . . . . . . 32
+ 7.4. Short Circuit Boolean Evaluation . . . . . . . . . . . . . . 33
+ 8. Statements . . . . . . . . . . . . . . . . . . . . . . . . . . 34
+ 8.1. Variable Declaration Statements . . . . . . . . . . . . . . . 34
+ 8.2. Assignment Statements . . . . . . . . . . . . . . . . . . . . 34
+ 8.3. Conditional and Looping Statements . . . . . . . . . . . . . 36
+ 8.3.1. Conditional Forms . . . . . . . . . . . . . . . . . . . . . 36
+ 8.3.1.1. if . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
+ 8.3.1.2. if-else . . . . . . . . . . . . . . . . . . . . . . . . . 36
+ 8.3.1.3. !if . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
+ 8.3.1.4. orelse, andelse . . . . . . . . . . . . . . . . . . . . . 38
+ 8.3.1.5. switch . . . . . . . . . . . . . . . . . . . . . . . . . 38
+ 8.3.2. Looping Forms . . . . . . . . . . . . . . . . . . . . . . . 40
+ 8.3.2.1. while . . . . . . . . . . . . . . . . . . . . . . . . . . 40
+ 8.3.2.2. do...while . . . . . . . . . . . . . . . . . . . . . . . 41
+ 8.3.2.3. for . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
+ 8.3.2.4. loop . . . . . . . . . . . . . . . . . . . . . . . . . . 42
+ 8.3.2.5. loop . . . . . . . . . . . . . . . . . . . . . . . . . . 42
+ 8.3.2.6. forever . . . . . . . . . . . . . . . . . . . . . . . . . 42
+ 8.3.2.7. foreach . . . . . . . . . . . . . . . . . . . . . . . . . 43
+ 8.4. break, return, continue . . . . . . . . . . . . . . . . . . . 45
+ 9. Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
+ 9.1. Declaring Functions . . . . . . . . . . . . . . . . . . . . . 46
+ 9.2. Parameter Passing Mechanism . . . . . . . . . . . . . . . . . 46
+ 9.3. Referencing Variables . . . . . . . . . . . . . . . . . . . . 48
+ 9.4. Functions with a Variable Number of Arguments . . . . . . . . 49
+ 9.5. Returning Values . . . . . . . . . . . . . . . . . . . . . . 51
+ 9.6. Multiple Assignment Statement . . . . . . . . . . . . . . . . 52
+ 9.7. Exit-Blocks . . . . . . . . . . . . . . . . . . . . . . . . . 54
+ 10. Name Spaces . . . . . . . . . . . . . . . . . . . . . . . . . 56
+ 11. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
+ 11.1. Creating Arrays . . . . . . . . . . . . . . . . . . . . . . 58
+ 11.1.1. Range Arrays . . . . . . . . . . . . . . . . . . . . . . . 58
+ 11.1.2. Creating arrays via the dereference operator . . . . . . . 59
+ 11.2. Reshaping Arrays . . . . . . . . . . . . . . . . . . . . . . 60
+ 11.3. Indexing Arrays . . . . . . . . . . . . . . . . . . . . . . 60
+ 11.4. Arrays and Variables . . . . . . . . . . . . . . . . . . . . 64
+ 11.5. Using Arrays in Computations . . . . . . . . . . . . . . . . 65
+ 12. Associative Arrays . . . . . . . . . . . . . . . . . . . . . . 69
+ 13. Structures and User-Defined Types . . . . . . . . . . . . . . 71
+ 13.1. Defining a Structure . . . . . . . . . . . . . . . . . . . . 71
+ 13.2. Accessing the Fields of a Structure . . . . . . . . . . . . 72
+ 13.3. Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . 72
+ 13.4. Defining New Types . . . . . . . . . . . . . . . . . . . . . 75
+ 14. Error Handling . . . . . . . . . . . . . . . . . . . . . . . . 77
+ 14.1. Error-Blocks . . . . . . . . . . . . . . . . . . . . . . . . 77
+ 14.2. Clearing Errors . . . . . . . . . . . . . . . . . . . . . . 78
+ 15. Loading Files: evalfile and autoload . . . . . . . . . . . . . 80
+ 16. File Input/Output . . . . . . . . . . . . . . . . . . . . . . 81
+ 16.1. Input/Output via stdio . . . . . . . . . . . . . . . . . . . 81
+ 16.1.1. Stdio Overview . . . . . . . . . . . . . . . . . . . . . . 81
+ 16.1.2. Stdio Examples . . . . . . . . . . . . . . . . . . . . . . 82
+ 16.2. POSIX I/O . . . . . . . . . . . . . . . . . . . . . . . . . 84
+ 16.3. Advanced I/O techniques . . . . . . . . . . . . . . . . . . 84
+ 16.3.1. Example: Reading /var/log/wtmp . . . . . . . . . . . . . . 86
+ 17. Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . 88
+ 18. Regular Expressions . . . . . . . . . . . . . . . . . . . . . 89
+ 18.1. S-Lang RE Syntax . . . . . . . . . . . . . . . . . . . . . 89
+ 18.2. Differences between S-Lang and egrep REs . . . . . . . . . 90
+ 19. Future Directions . . . . . . . . . . . . . . . . . . . . . . 91
+ A. Copyright . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
+ A.1. The GNU Public License . . . . . . . . . . . . . . . . . . . 92
+ A.2. The Artistic License . . . . . . . . . . . . . . . . . . . . 98
+
+
+
diff --git a/libslang/doc/text/slangfun.txt b/libslang/doc/text/slangfun.txt
new file mode 100644
index 0000000..3f35b89
--- /dev/null
+++ b/libslang/doc/text/slangfun.txt
@@ -0,0 +1,5943 @@
+_isnull
+
+ SYNOPSIS
+ Check array for NULL elements
+
+ USAGE
+ Char_Type[] = _isnull (a[])
+
+ DESCRIPTION
+ This function may be used to test for the presence of NULL elements
+ of an array. Specifically, it returns a `Char_Type' array of
+ with the same number of elements and dimensionality of the input
+ array. If an element of the input array is NULL, then the
+ corresponding element of the output array will be set to 1,
+ otherwise it will be set to 0.
+
+ EXAMPLE
+ Set all NULL elements of a string array `A' to the empty
+ string `""':
+
+ A[where(_isnull(A))] = "";
+
+
+ NOTES
+ It is important to understand the difference between `A==NULL'
+ and `_isnull(A)'. The latter tests all elements of `A'
+ against NULL, whereas the former only tests `A' itself.
+
+ SEE ALSO
+ where, array_map
+--------------------------------------------------------------
+
+_reshape
+
+ SYNOPSIS
+ Copy an array to a new shape
+
+ USAGE
+ Array_Type _reshape (Array_Type A, Array_Type I)
+
+ DESCRIPTION
+ The `_reshape' function creates a copy of an array `A',
+ reshapes it to the form specified by `I' and returns the result.
+ The elements of `I' specify the new dimensions of the copy of
+ `A' and must be consistent with the number of elements `A'.
+
+ EXAMPLE
+ If `A' is a `100' element 1-d array, a new array 2-d array of
+ size `20' by `5' may be created from the elements of `A'
+ by
+
+ A = _reshape (A, [20, 5]);
+
+ In this example, the original array was no longer needed. Hence, it
+ is preferable to make use of the `__tmp' operator to avoid the
+ creation of a new array, i.e.,
+
+ A = _reshape (__tmp(A), [20,5]);
+
+
+ NOTES
+ The `reshape' function performs a similar function to
+ `_reshape'. In fact, the `_reshape' function could have been
+ implemented via:
+
+ define _reshape (a, i)
+ {
+ a = @a; % Make a new copy
+ reshape (a, i);
+ return a;
+ }
+
+
+ SEE ALSO
+ reshape, array_info
+--------------------------------------------------------------
+
+array_info
+
+ SYNOPSIS
+ Returns information about an array
+
+ USAGE
+ (Array_Type, Integer_Type, DataType_Type) array_info (Array_Type a)
+
+ DESCRIPTION
+ The `array_info' function returns information about the array `a'.
+ It returns three values: an 1-d integer array specifying the
+ size of each dimension of `a', the number of dimensions of
+ `a', and the data type of `a'.
+
+ EXAMPLE
+ The `array_info' function may be used to find the number of rows
+ of an array:
+
+ define num_rows (a)
+ {
+ variable dims, num_dims, data_type;
+
+ (dims, num_dims, data_type) = array_info (a);
+ return dims [0];
+ }
+
+ For 1-d arrays, this information is more easily obtained from the
+ `length' function.
+
+ SEE ALSO
+ typeof, reshape, length, _reshape
+--------------------------------------------------------------
+
+array_map
+
+ SYNOPSIS
+ Apply a function to each element of an array
+
+ USAGE
+ Array_Type array_map (type, func, arg0, ...)
+
+ DataType_Type type;
+ Ref_Type func;
+
+
+ DESCRIPTION
+ The `array_map' function may be used to apply a function to each
+ element of an array and returns the result as an array of a
+ specified type. The `type' parameter indicates what kind of
+ array should be returned and generally corresponds to the return
+ type of the function. The `arg0' parameter should be an array
+ and is used to determine the dimensions of the resulting array. If
+ any subsequent arguments correspond to an array of the same size,
+ then those array elements will be passed in parallel with the first
+ arrays arguments.
+
+ EXAMPLE
+ The first example illustrates how to apply the `strlen' function
+ to an array of strings:
+
+ S = ["", "Train", "Subway", "Car"];
+ L = array_map (Integer_Type, &strlen, S);
+
+ This is equivalent to:
+
+ S = ["", "Train", "Subway", "Car"];
+ L = Integer_Type [length (S)];
+ for (i = 0; i < length (S); i++) L[i] = strlen (S[i]);
+
+
+ Now consider an example involving the `strcat' function:
+
+ files = ["slang", "slstring", "slarray"];
+
+ exts = ".c";
+ cfiles = array_map (String_Type, &strcat, files, exts);
+ % ==> cfiles = ["slang.c slstring.c slarray.c"];
+
+ exts = [".a",".b",".c"];
+ xfiles = array_map (String_Type, &strcat, files, exts);
+ % ==> xfiles = ["slang.a", "slstring.b", "slarray.c"];
+
+
+ NOTES
+ Many mathemetical functions already work transparantly on arrays.
+ For example, the following two statements produce identical results:
+
+ B = sin (A);
+ B = array_map (Double_Type, &sin, A);
+
+
+ SEE ALSO
+ array_info, strlen, strcat, sin
+--------------------------------------------------------------
+
+array_sort
+
+ SYNOPSIS
+ Sort an array
+
+ USAGE
+ Array_Type array_sort (Array_Type a [, String_Type or Ref_Type f])
+
+ DESCRIPTION
+ `array_sort' sorts the array `a' into ascending order and
+ returns an integer array that represents the result of the sort. If
+ the optional second parameter `f' is present, the function
+ specified by `f' will be used to compare elements of `a';
+ otherwise, a built-in sorting function will be used.
+
+ If `f' is present, then it must be either a string representing
+ the name of the comparison function, or a reference to the function.
+ The sort function represented by `f' must be a S-Lang
+ user-defined function that takes two arguments. The function must
+ return an integer that is less than zero if the first parameter is
+ considered to be less than the second, zero if they are equal, and a
+ value greater than zero if the first is greater than the second.
+
+ If the comparision function is not specified, then a built-in comparison
+ function appropriate for the data type will be used. For example,
+ if `a' is an array of character strings, then the sort will be
+ preformed using `strcmp'.
+
+ The integer array returned by this function is simply an index that
+ indicates the order of the sorted array. The input array `a' is
+ not changed.
+
+ EXAMPLE
+ An array of strings may be sorted using the `strcmp' function
+ since it fits the specification for the sorting function described
+ above:
+
+ variable A = String_Type [3];
+ A[0] = "gamma"; A[1] = "alpha"; A[2] = "beta";
+
+ variable I = array_sort (A, &strcmp);
+
+ Alternatively, one may use
+
+ variable I = array_sort (A);
+
+ to use the built-in comparison function.
+
+ After the `array_sort' has executed, the variable `I' will
+ have the values `[2, 0, 1]'. This array can be used to
+ re-shuffle the elements of `A' into the sorted order via the
+ array index expression `A = A[I]'.
+
+ SEE ALSO
+ strcmp
+--------------------------------------------------------------
+
+cumsum
+
+ SYNOPSIS
+ Compute the cumulative sum of an array
+
+ USAGE
+ result = cumsum (Array_Type a [, Int_Type dim])
+
+ DESCRIPTION
+ The `cumsum' function performs a cumulative sum over the
+ elements of a numeric array and returns the resulting. If a second
+ argument is given, then it specifies the dimension of the array to
+ be summed over. For example, the cumulative sum of
+ `[1,2,3,4]', is the array `[1,1+2,1+2+3,1+2+3+4]', i.e.,
+ `[1,3,6,10]'.
+
+ SEE ALSO
+ sum
+--------------------------------------------------------------
+
+init_char_array
+
+ SYNOPSIS
+ Initialize an array of characters
+
+ USAGE
+ init_char_array (Array_Type a, String_Type s)
+
+ DESCRIPTION
+ The `init_char_array' function may be used to initialize a
+ character array `a' by setting the elements of the array
+ `a' to the corresponding characters of the string `s'.
+
+ EXAMPLE
+ The statements
+
+ variable a = Char_Type [10];
+ init_char_array (a, "HelloWorld");
+
+ creates an character array and initializes its elements to the
+ characters in the string `"HelloWorld"'.
+
+ NOTES
+ The character array must be large enough to hold all the characters
+ of the initialization string.
+
+ SEE ALSO
+ bstring_to_array, strlen, strcat
+--------------------------------------------------------------
+
+length
+
+ SYNOPSIS
+ Get the length of an object
+
+ USAGE
+ Integer_Type length (obj)
+
+ DESCRIPTION
+ The `length' function may be used to get information about the
+ length of an object. For simple scalar data-types, it returns 1.
+ For arrays, it returns the total number of elements of the array.
+
+ NOTES
+ If `obj' is a string, `length' returns 1 because a
+ `String_Type' object is considered to be a scalar. To get the
+ number of characters in a string, use the `strlen' function.
+
+ SEE ALSO
+ array_info, typeof, strlen
+--------------------------------------------------------------
+
+max
+
+ SYNOPSIS
+ Get the maximum value of an array
+
+ USAGE
+ result = max (Array_Type a [,Int_Type dim])
+
+ DESCRIPTION
+ The `max' function examines the elements of a numeric array and
+ returns the value of the largest element. If a second argument is
+ given, then it specifies the dimension of the array to be searched.
+ In this case, an array of dimension one less than that of the input array
+ will be returned with the corresponding elements in the specified
+ dimension replaced by the minimum value in that dimension.
+
+ EXAMPLE
+ Consider the 2-d array
+
+ 1 2 3 4 5
+ 6 7 8 9 10
+
+ generated by
+
+ a = _reshape ([1:10], [2, 5]);
+
+ Then `max(a)' will return `10', and `max(a,0)' will return
+ a 1-d array with elements
+
+ 6 7 8 9 10
+
+
+ SEE ALSO
+ max, sum, reshape
+--------------------------------------------------------------
+
+min
+
+ SYNOPSIS
+ Get the minimum value of an array
+
+ USAGE
+ result = min (Array_Type a [,Int_Type dim])
+
+ DESCRIPTION
+ The `min' function examines the elements of a numeric array and
+ returns the value of the smallest element. If a second argument is
+ given, then it specifies the dimension of the array to be searched.
+ In this case, an array of dimension one less than that of the input array
+ will be returned with the corresponding elements in the specified
+ dimension replaced by the minimum value in that dimension.
+
+ EXAMPLE
+ Consider the 2-d array
+
+ 1 2 3 4 5
+ 6 7 8 9 10
+
+ generated by
+
+ a = _reshape ([1:10], [2, 5]);
+
+ Then `min(a)' will return `1', and `min(a,0)' will return
+ a 1-d array with elements
+
+ 1 2 3 4 5
+
+
+ SEE ALSO
+ max, sum, reshape
+--------------------------------------------------------------
+
+reshape
+
+ SYNOPSIS
+ Reshape an array
+
+ USAGE
+ reshape (Array_Type A, Array_Type I)
+
+ DESCRIPTION
+ The `reshape' function changes the size of `A' to have the size
+ specified by the 1-d integer array `I'. The elements of `I'
+ specify the new dimensions of `A' and must be consistent with
+ the number of elements `A'.
+
+ EXAMPLE
+ If `A' is a `100' element 1-d array, it can be changed to a
+ 2-d `20' by `5' array via
+
+ reshape (A, [20, 5]);
+
+ However, `reshape(A, [11,5])' will result in an error because
+ the `[11,5]' array specifies `55' elements.
+
+ NOTES
+ Since `reshape' modifies the shape of an array, and arrays are
+ treated as references, then all references to the array will
+ reference the new shape. If this effect is unwanted, then use the
+ `_reshape' function instead.
+
+ SEE ALSO
+ _reshape, array_info
+--------------------------------------------------------------
+
+sum
+
+ SYNOPSIS
+ Sum over the elements of an array
+
+ USAGE
+ result = sum (Array_Type a [, Int_Type dim])
+
+ DESCRIPTION
+ The `sum' function sums over the elements of a numeric array and
+ returns its result. If a second argument is given, then it
+ specifies the dimension of the array to be summed over. In this
+ case, an array of dimension one less than that of the input array
+ will be returned.
+
+ If the input array is an integer type, then the resulting value will
+ be a `Double_Type'. If the input array is a `Float_Type',
+ then the result will be a `Float_Type'.
+
+ EXAMPLE
+ The mean of an array `a' of numbers is
+
+ sum(a)/length(a)
+
+
+ SEE ALSO
+ cumsum, transpose, reshape
+--------------------------------------------------------------
+
+transpose
+
+ SYNOPSIS
+ Transpose an array
+
+ USAGE
+ Array_Type transpose (Array_Type a)
+
+ DESCRIPTION
+ The `transpose' function returns the transpose of a specified
+ array. By definition, the transpose of an array, say one with
+ elements `a[i,j,...k]' is an array whose elements are
+ `a[k,...,j,i]'.
+
+ SEE ALSO
+ _reshape, reshape, sum, array_info
+--------------------------------------------------------------
+
+where
+
+ SYNOPSIS
+ Get indices where an integer array is non-zero
+
+ USAGE
+ Array_Type where (Array_Type a)
+
+ DESCRIPTION
+ The `where' function examines an numeric array `a' and
+ returns an integer array giving the indices of `a'
+ where the corresponding element of `a' is non-zero.
+
+ Although this function may appear to be simple or even trivial, it
+ is arguably one of the most important and powerful functions for
+ manipulating arrays.
+
+ EXAMPLE
+ Consider the following:
+
+ variable X = [0.0:10.0:0.01];
+ variable A = sin (X);
+ variable I = where (A < 0.0);
+ A[I] = cos (X) [I];
+
+ Here the variable `X' has been assigned an array of doubles
+ whose elements range from `0.0' through `10.0' in
+ increments of `0.01'. The second statement assigns `A' to
+ an array whose elements are the `sin' of the elements of `X'.
+ The third statement uses the where function to get the indices of
+ the elements of `A' that are less than `0.0'. Finally, the
+ last statement substitutes into `A' the `cos' of the
+ elements of `X' at the positions of `A' where the
+ corresponding `sin' is less than `0'. The end result is
+ that the elements of `A' are a mixture of sines and cosines.
+
+ SEE ALSO
+ array_info, sin, cos
+--------------------------------------------------------------
+
+assoc_delete_key
+
+ SYNOPSIS
+ Delete a key from an Associative Array
+
+ USAGE
+ assoc_delete_key (Assoc_Type a, String_Type k)
+
+ DESCRIPTION
+ The `assoc_delete_key' function deletes a key given by `k'
+ from the associative array `a'. If the specified key does not
+ exist in `a', then this function has no effect.
+
+ SEE ALSO
+ assoc_key_exists, assoc_get_keys
+--------------------------------------------------------------
+
+assoc_get_keys
+
+ SYNOPSIS
+ Return all the key names of an Associative Array
+
+ USAGE
+ String_Type[] assoc_get_keys (Assoc_Type a)
+
+ DESCRIPTION
+ This function returns all the key names of an associative array
+ `a' as an ordinary one dimensional array of strings. If the
+ associative array contains no keys, an empty array will be returned.
+
+ EXAMPLE
+ The following function computes the number of keys in an associative
+ array:
+
+ define get_num_elements (a)
+ {
+ return length (assoc_get_keys (a));
+ }
+
+
+ SEE ALSO
+ assoc_get_values, assoc_key_exists, assoc_delete_key, length
+--------------------------------------------------------------
+
+assoc_get_values
+
+ SYNOPSIS
+ Return all the values of an Associative Array
+
+ USAGE
+ Array_Type assoc_get_keys (Assoc_Type a)
+
+ DESCRIPTION
+ This function returns all the values in the associative array
+ `a' as an array of proper type. If the associative array
+ contains no keys, an empty array will be returned.
+
+ EXAMPLE
+ Suppose that `a' is an associative array of type
+ `Integer_Type', i.e., it was created via
+
+ variable a = Assoc_Type[Integer_Type];
+
+ The the following may be used to print the values of the array in
+ ascending order:
+
+ static define int_sort_fun (x, y)
+ {
+ return sign (x - y);
+ }
+ define sort_and_print_values (a)
+ {
+ variable i, v;
+
+ v = assoc_get_values (a);
+ i = array_sort (v, &int_sort_fun);
+ v = v[i];
+ foreach (v)
+ {
+ variable vi = ();
+ () = fprintf (stdout, "%d\n", vi);
+ }
+ }
+
+
+ SEE ALSO
+ assoc_get_values, assoc_key_exists, assoc_delete_key, array_sort
+--------------------------------------------------------------
+
+assoc_key_exists
+
+ SYNOPSIS
+ Check to see whether a key exists in an Associative Array
+
+ USAGE
+ Integer_Type assoc_key_exists (Assoc_Type a, String_Type k)
+
+ DESCRIPTION
+ The `assoc_key_exists' function may be used to determine whether
+ or not a specified key `k' exists in an associative array `a'.
+ It returns 1 if the key exists, or 0 if it does not.
+
+ SEE ALSO
+ assoc_get_keys, assoc_get_values, assoc_delete_key
+--------------------------------------------------------------
+
+array_to_bstring
+
+ SYNOPSIS
+ Convert an array to a binary string
+
+ USAGE
+ BString_Type array_to_bstring (Array_Type a)
+
+ DESCRIPTION
+ The `array_to_bstring' function returns the elements of an
+ array `a' as a binary string.
+
+ SEE ALSO
+ bstring_to_array, init_char_array
+--------------------------------------------------------------
+
+bstring_to_array
+
+ SYNOPSIS
+ Convert a binary string to an array of characters
+
+ USAGE
+ UChar_Type[] bstring_to_array (BString_Type b)
+
+ DESCRIPTION
+ The `bstring_to_array' function returns an array of unsigned
+ characters whose elements correspond to the characters in the
+ binary string.
+
+ SEE ALSO
+ array_to_bstring, init_char_array
+--------------------------------------------------------------
+
+bstrlen
+
+ SYNOPSIS
+ Get the length of a binary string
+
+ USAGE
+ UInt_Type bstrlen (BString_Type s)
+
+ DESCRIPTION
+ The `bstrlen' function may be used to obtain the length of a
+ binary string. A binary string differs from an ordinary string (a C
+ string) in that a binary string may include null chracters.
+
+ EXAMPLE
+
+ variable s = "hello\0";
+ len = bstrlen (s); % ==> len = 6
+ len = strlen (s); % ==> len = 5
+
+
+ SEE ALSO
+ strlen, length
+--------------------------------------------------------------
+
+pack
+
+ SYNOPSIS
+ Pack objects into a binary string
+
+ USAGE
+ BString_Type pack (String_Type fmt, ...)
+
+ DESCRIPTION
+ The `pack' function combines zero or more the objects (represented
+ by the ellipses above) into a binary string acording to the format
+ string `fmt'.
+
+ The format string consists of one or more data-type specification
+ characters, and each may be followed by an optional decimal length
+ specifier. Specifically, the data-types are specified according to
+ the following table:
+
+ c char
+ C unsigned char
+ h short
+ H unsigned short
+ i int
+ I unsigned int
+ l long
+ L unsigned long
+ j 16 bit int
+ J 16 unsigned int
+ k 32 bit int
+ K 32 bit unsigned int
+ f float
+ d double
+ F 32 bit float
+ D 64 bit float
+ s character string, null padded
+ S character string, space padded
+ x a null pad character
+
+ A decimal length specifier may follow the data-type specifier. With
+ the exception of the `s' and `S' specifiers, the length
+ specifier indicates how many objects of that data type are to be
+ packed or unpacked from the string. When used with the `s' or
+ `S' specifiers, it indicates the field width to be used. If the
+ length specifier is not present, the length defaults to one.
+
+ With the exception of `c', `C', `s', `S', and
+ `x', each of these may be prefixed by a character that indicates
+ the byte-order of the object:
+
+ > big-endian order (network order)
+ < little-endian order
+ = native byte-order
+
+ The default is to use native byte order.
+
+ When unpacking via the `unpack' function, if the length
+ specifier is greater than one, then an array of that length will be
+ returned. In addition, trailing whitespace and null character are
+ stripped when unpacking an object given by the `S' specifier.
+
+ EXAMPLE
+
+ a = pack ("cc", 'A', 'B'); % ==> a = "AB";
+ a = pack ("c2", 'A', 'B'); % ==> a = "AB";
+ a = pack ("xxcxxc", 'A', 'B'); % ==> a = "\0\0A\0\0B";
+ a = pack ("h2", 'A', 'B'); % ==> a = "\0A\0B" or "\0B\0A"
+ a = pack (">h2", 'A', 'B'); % ==> a = "\0\xA\0\xB"
+ a = pack ("<h2", 'A', 'B'); % ==> a = "\0B\0A"
+ a = pack ("s4", "AB", "CD"); % ==> a = "AB\0\0"
+ a = pack ("s4s2", "AB", "CD"); % ==> a = "AB\0\0CD"
+ a = pack ("S4", "AB", "CD"); % ==> a = "AB "
+ a = pack ("S4S2", "AB", "CD"); % ==> a = "AB CD"
+
+
+ SEE ALSO
+ unpack, sizeof_pack, pad_pack_format, sprintf
+--------------------------------------------------------------
+
+pad_pack_format
+
+ SYNOPSIS
+ Add padding to a pack format
+
+ USAGE
+ BString_Type pad_pack_format (String_Type fmt)
+
+ DESCRIPTION
+ The `pad_pack_format' function may be used to add the
+ appropriate padding to the format `fmt' such that the data types
+ specified by the format will be properly aligned for the system.
+ This is especially important when reading or writing files that
+ assume the native alignment.
+
+ See the S-Lang User's Guide for more information about the use of
+ this function.
+
+ SEE ALSO
+ pack, unpack, sizeof_pack
+--------------------------------------------------------------
+
+sizeof_pack
+
+ SYNOPSIS
+ Compute the size implied by a pack format string
+
+ USAGE
+ UInt_Type sizeof_pack (String_Type fmt)
+
+ DESCRIPTION
+ The `sizeof_pack' function returns the size of the binary string
+ represented by the format string `fmt'. This information may be
+ needed when reading a structure from a file.
+
+ NOTES
+
+ SEE ALSO
+ pack, unpack, pad_pack_format
+--------------------------------------------------------------
+
+unpack
+
+ SYNOPSIS
+ Unpack Objects from a Binary String
+
+ USAGE
+ (...) = unpack (String_Type fmt, BString_Type s)
+
+ DESCRIPTION
+ The `unpack' function unpacks objects from a binary string
+ `s' according to the format `fmt' and returns the objects to
+ the stack in the order in which they were unpacked. See the
+ documentation of the `pack' function for details about the
+ format string.
+
+ EXAMPLE
+
+ (x,y) = unpack ("cc", "AB"); % ==> x = 'A', y = 'B'
+ x = unpack ("c2", "AB"); % ==> x = ['A', 'B']
+ x = unpack ("x<H", "\0\xAB\xCD"); % ==> x = 0xCDABuh
+ x = unpack ("xxs4", "a b c\0d e f"); % ==> x = "b c\0"
+ x = unpack ("xxS4", "a b c\0d e f"); % ==> x = "b c"
+
+
+ SEE ALSO
+ pack, sizeof_pack, pad_pack_format
+--------------------------------------------------------------
+
+_clear_error
+
+ SYNOPSIS
+ Clear an error condition
+
+ USAGE
+ _clear_error ()
+
+ DESCRIPTION
+ This function may be used in error-blocks to clear the error that
+ triggered execution of the error block. Execution resumes following
+ the statement, in the scope of the error-block, that triggered the
+ error.
+
+ EXAMPLE
+ Consider the following wrapper around the `putenv' function:
+
+ define try_putenv (name, value)
+ {
+ variable status;
+ ERROR_BLOCK
+ {
+ _clear_error ();
+ status = -1;
+ }
+ status = 0;
+ putenv (sprintf ("%s=%s", name, value);
+ return status;
+ }
+
+ If `putenv' fails, it generates an error condition, which the
+ `try_putenv' function catches and clears. Thus `try_putenv'
+ is a function that returns `-1' upon failure and `0' upon
+ success.
+
+ SEE ALSO
+ _trace_function, _slangtrace, _traceback
+--------------------------------------------------------------
+
+_debug_info
+
+ SYNOPSIS
+ Configure debugging information
+
+ USAGE
+ Integer_Type _debug_info
+
+ DESCRIPTION
+ The `_debug_info' variable controls whether or not extra code
+ should be generated for additional debugging and traceback
+ information. Currently, if `_debug_info' is zero, no extra code
+ will be generated; otherwise extra code will be inserted into the
+ compiled bytecode for additional debugging data.
+
+ The value of this variable is local to each compilation unit and
+ setting its value in one unit has no effect upon its value in other
+ units.
+
+ EXAMPLE
+
+ _debug_info = 1; % Enable debugging information
+
+
+ NOTES
+ Setting this variable to a non-zero value may slow down the
+ interpreter somewhat.
+
+ SEE ALSO
+ _traceback, _slangtrace
+--------------------------------------------------------------
+
+_slangtrace
+
+ SYNOPSIS
+ Turn function tracing on or off.
+
+ USAGE
+ Integer_Type _slangtrace
+
+ DESCRIPTION
+ The `_slangtrace' variable is a debugging aid that when set to a
+ non-zero value enables tracing when function declared by
+ `_trace_function' is entered. If the value is greater than
+ zero, both intrinsic and user defined functions will get traced.
+ However, if set to a value less than zero, intrinsic functions will
+ not get traced.
+
+ SEE ALSO
+ _trace_function, _traceback, _print_stack
+--------------------------------------------------------------
+
+_trace_function
+
+ SYNOPSIS
+ Set the function to trace
+
+ USAGE
+ _trace_function (String_Type f)
+
+ DESCRIPTION
+ `_trace_function' declares that the S-Lang function with name
+ `f' is to be traced when it is called. Calling
+ `_trace_function' does not in itself turn tracing on. Tracing
+ is turned on only when the variable `_slangtrace' is non-zero.
+
+ SEE ALSO
+ _slangtrace, _traceback
+--------------------------------------------------------------
+
+_traceback
+
+ SYNOPSIS
+ Generate a traceback upon error
+
+ USAGE
+ Integer_Type _traceback
+
+ DESCRIPTION
+ `_traceback' is an intrinsic integer variable whose value
+ controls whether or not a traceback of the call stack is to be
+ generated upon error. If `_traceback' is greater than zero, a
+ full traceback will be generated, which includes the values of local
+ variables. If the value is less than zero, a traceback will be
+ generated without local variable information, and if
+ `_traceback' is zero the traceback will not be generated.
+
+ Local variables are represented in the form `$n' where `n' is an
+ integer numbered from zero. More explicitly, `$0' represents the
+ first local variable, `$1' represents the second, and so on.
+ Please note that function parameters are local variables and that the
+ first parameter corresponds to `$0'.
+
+ SEE ALSO
+ _slangtrace, error
+--------------------------------------------------------------
+
+chdir
+
+ SYNOPSIS
+ Change the current working directory.
+
+ USAGE
+ Integer_Type chdir (String_Type dir)
+
+ DESCRIPTION
+ The `chdir' function may be used to changed the current working
+ directory to the directory specified by `dir'. Upon success it
+ returns zero; however, upon failure it returns `-1' and sets
+ `errno' accordingly.
+
+ SEE ALSO
+ mkdir, stat_file
+--------------------------------------------------------------
+
+chmod
+
+ SYNOPSIS
+ Change the mode of a file
+
+ USAGE
+ Integer_Type chmod (String_Type file, Integer_Type mode)
+
+ DESCRIPTION
+ The `chmod' function changes the permissions of `file' to those
+ specified by `mode'. It returns `0' upon success, or
+ `-1' upon failure setting `errno' accordingly.
+
+ See the system specific documentation for the C library
+ function `chmod' for a discussion of the `mode' parameter.
+
+ SEE ALSO
+ chown, stat_file
+--------------------------------------------------------------
+
+chown
+
+ SYNOPSIS
+ Change the owner of a file
+
+ USAGE
+ Integer_Type chown (String_Type file, Integer_Type uid, Integer_Type gid)
+
+ DESCRIPTION
+ The `chown' function is used to change the user-id and group-id of
+ `file' to `uid' and `gid', respectively. It returns
+ `zero' upon success and `-1' upon failure, with `errno'
+ set accordingly.
+
+ NOTES
+ On most systems, only the super user can change the ownership of a
+ file.
+
+ Some systems do not support this function.
+
+ SEE ALSO
+ chmod, stat_file
+--------------------------------------------------------------
+
+getcwd
+
+ SYNOPSIS
+ Get the current working directory
+
+ USAGE
+ String_Type getcwd ()
+
+ DESCRIPTION
+ The `getcwd' function returns the absolute pathname of the
+ current working directory. If an error occurs or it cannot
+ determine the working directory, it returns `NULL' and sets
+ `errno' accordingly.
+
+ NOTES
+ Under Unix, OS/2, and MSDOS, the pathname returned by this function
+ includes the trailing slash character. Some versions also include
+ the drive specifier.
+
+ SEE ALSO
+ mkdir, chdir, errno
+--------------------------------------------------------------
+
+listdir
+
+ SYNOPSIS
+ Get a list of the files in a directory
+
+ USAGE
+ String_Type[] listdir (String_Type dir)
+
+ DESCRIPTION
+ The `listdir' function returns the directory listing of all the
+ files in the specified directory `dir' as an array of strings.
+ It does not return the special files `".."' and `"."' as
+ part of the list.
+
+ SEE ALSO
+ stat_file, stat_is, length
+--------------------------------------------------------------
+
+lstat_file
+
+ SYNOPSIS
+ Get information about a symbolic link
+
+ USAGE
+ Struct_Type lstat_file (String_Type file)
+
+ DESCRIPTION
+ The `lstat_file' function behaves identically to `stat_file'
+ but if `file' is a symbolic link, `lstat_file' returns
+ information about the link itself, and not the file that it
+ references.
+
+ See the documentation for `stat_file' for more information.
+
+ NOTES
+ On systems that do not support symbolic links, there is no
+ difference between this function and the `stat_file' function.
+
+ SEE ALSO
+ stat_file, readlink
+--------------------------------------------------------------
+
+mkdir
+
+ SYNOPSIS
+ Create a new directory
+
+ USAGE
+ Integer_Type mkdir (String_Type dir, Integer_Type mode)
+
+ DESCRIPTION
+ The `mkdir' function creates a directory whose name is specified
+ by the `dir' parameter with permissions specified by `mode'.
+ Upon success `mkdir' returns zero, or it returns `-1' and
+ sets `errno' accordingly. In particular, if the directory
+ already exists, the function will fail and set errno to
+ `EEXIST'.
+
+ EXAMPLE
+
+ define my_mkdir (dir)
+ {
+ if (0 == mkdir (dir, 0777)) return;
+ if (errno == EEXIST) return;
+ verror ("mkdir %s failed: %s", dir, errno_string (errno));
+ }
+
+
+ NOTES
+ The `mode' parameter may not be meaningful on all systems. On
+ systems where it is meaningful, the actual permissions on the newly
+ created directory are modified by the process's umask.
+
+ SEE ALSO
+ rmdir, getcwd, chdir, fopen, errno
+--------------------------------------------------------------
+
+readlink
+
+ SYNOPSIS
+ String_Type readlink (String_Type path)
+
+ USAGE
+ Get the value of a symbolic link
+
+ DESCRIPTION
+ The `readlink' function returns the value of a symbolic link and
+ returns it as a string. Upon failure, NULL is returned and
+ `errno' set accordingly.
+
+ NOTES
+ Not all systems support this function.
+
+ SEE ALSO
+ lstat_file, stat_file, stat_is
+--------------------------------------------------------------
+
+remove
+
+ SYNOPSIS
+ Delete a file
+
+ USAGE
+ Integer_Type remove (String_Type file)
+
+ DESCRIPTION
+ The `remove' function deletes a file. It returns 0 upon
+ success, or -1 upon error and sets `errno' accordingly.
+
+ SEE ALSO
+ rename, rmdir
+--------------------------------------------------------------
+
+rename
+
+ SYNOPSIS
+ Rename a file
+
+ USAGE
+ Integer_Type rename (String_Type old, String_Type new)
+
+ DESCRIPTION
+ The `rename' function renames a file from `old' to `new'
+ moving it between directories if necessary. This function may fail
+ if the directories do not refer to the same file system. It returns
+ 0 upon success, or -1 upon error and sets `errno' accordingly.
+
+ SEE ALSO
+ remove, errno
+--------------------------------------------------------------
+
+rmdir
+
+ SYNOPSIS
+ Remove a directory
+
+ USAGE
+ Integer_Type rmdir (String_Type dir)
+
+ DESCRIPTION
+ The `rmdir' function deletes a specified directory. It returns
+ 0 upon success or -1 upon error and sets `errno' accordingly.
+
+ NOTES
+ The directory must be empty before it can be removed.
+
+ SEE ALSO
+ rename, remove, mkdir
+--------------------------------------------------------------
+
+stat_file
+
+ SYNOPSIS
+ Get information about a file
+
+ USAGE
+ Struct_Type stat_file (String_Type file)
+
+ DESCRIPTION
+ The `stat_file' function returns information about `file'
+ through the use of the system `stat' call. If the stat call
+ fails, the function returns `NULL' and sets errno accordingly.
+ If it is successful, it returns a stat structure with the following
+ integer fields:
+
+ st_dev
+ st_ino
+ st_mode
+ st_nlink
+ st_uid
+ st_gid
+ st_rdev
+ st_size
+ st_atime
+ st_mtime
+ st_ctime
+
+ See the man page for `stat' for a discussion of these fields.
+
+ EXAMPLE
+ The following example shows how the `stat_file' function may be
+ used to get the size of a file:
+
+ define file_size (file)
+ {
+ variable st;
+ st = stat_file(file);
+ if (st == NULL) verror ("Unable to stat %s", file);
+ return st.st_size;
+ }
+
+
+ SEE ALSO
+ lstat_file, stat_is
+--------------------------------------------------------------
+
+stat_is
+
+ SYNOPSIS
+ Parse the var{st_mode
+
+ USAGE
+ Char_Type stat_is (String_Type type, Integer_Type st_mode)
+
+ DESCRIPTION
+ The `stat_is' function returns a signed character value about
+ the type of file specified by `st_mode'. Specifically,
+ `type' must be one of the strings:
+
+ "sock" (socket)
+ "fifo" (fifo)
+ "blk" (block device)
+ "chr" (character device)
+ "reg" (regular file)
+ "lnk" (link)
+ "dir" (dir)
+
+ It returns a non-zero value if `st_mode' corresponds to
+ `type'.
+
+ EXAMPLE
+ The following example illustrates how to use the `stat_is'
+ function to determine whether or not a file is a directory:
+
+ define is_directory (file)
+ {
+ variable st;
+
+ st = stat_file (file);
+ if (st == NULL) return 0;
+ return stat_is ("dir", st.st_mode);
+ }
+
+
+ SEE ALSO
+ stat_file, lstat_file
+--------------------------------------------------------------
+
+autoload
+
+ SYNOPSIS
+ Load a function from a file
+
+ USAGE
+ autoload (String_Type funct, String_Type file)
+
+ DESCRIPTION
+ The `autoload' function is used to declare `funct' to the
+ interpreter and indicate that it should be loaded from `file' when
+ it is actually used.
+
+ EXAMPLE
+ Suppose `bessel_j0' is a function defined in the file
+ `bessel.sl'. Then the statement
+
+ autoload ("bessel_j0", "bessel.sl");
+
+ will cause `bessel.sl' to be loaded prior to the execution of
+ `bessel_j0'
+
+ SEE ALSO
+ evalfile
+--------------------------------------------------------------
+
+byte_compile_file
+
+ SYNOPSIS
+ Compile a file to byte-code for faster loading.
+
+ USAGE
+ byte_compile_file (String_Type file, Integer_Type method)
+
+ DESCRIPTION
+ The `byte_compile_file' function byte-compiles `file'
+ producing a new file with the same name except a `'c'' is added
+ to the output file name. For example, `file' is
+ `"site.sl"', then the function produces a new file named
+ `site.slc'.
+
+ NOTES
+ The `method' parameter is not used in the current
+ implementation. Its use is reserved for the future. For now, set
+ it to `0'.
+
+ SEE ALSO
+ evalfile
+--------------------------------------------------------------
+
+eval
+
+ SYNOPSIS
+ Interpret a string as slang code
+
+ USAGE
+ eval (String_Type expression, [,String_Type namespace])
+
+ DESCRIPTION
+ The `eval' function parses a string as S-Lang code and executes the
+ result. If called with the optional namespace argument, then the
+ string will be evaluated in the specified namespace.
+
+ This is a useful function in many contexts such as dynamically
+ generating function definitions where there is no way to generate
+ them otherwise.
+
+ EXAMPLE
+
+ if (0 == is_defined ("my_function"))
+ eval ("define my_function () { message (\"my_function\"); }");
+
+
+ SEE ALSO
+ is_defined, autoload, evalfile
+--------------------------------------------------------------
+
+evalfile
+
+ SYNOPSIS
+ Interpret a file containing slang code.
+
+ USAGE
+ Integer_Type evalfile (String_Type file, [,String_Type namespace])
+
+ DESCRIPTION
+ The `evalfile' function loads `file' into the interpreter
+ and executes it. If called with the optional namespace argument,
+ the file will be loaded into the specified namespace, which will be
+ created if necessary. If no errors were encountered, `1' will
+ be returned; otherwise, a S-Lang error will be generated and the
+ function will return zero.
+
+ EXAMPLE
+
+ define load_file (file)
+ {
+ ERROR_BLOCK { _clear_error (); }
+ () = evalfile (file);
+ }
+
+
+ NOTES
+ For historical reasons, the return value of this function is not
+ really useful.
+
+ The file is searched along an application-defined load-path. The
+ `get_slang_load_path' and `set_slang_load_path' functions
+ may be used to set and query the path.
+
+ SEE ALSO
+ eval, autoload, set_slang_load_path, get_slang_load_path
+--------------------------------------------------------------
+
+get_slang_load_path
+
+ SYNOPSIS
+ Get the value of the interpreter's load-path
+
+ USAGE
+ String_Type get_slang_load_path ()
+
+ DESCRIPTION
+ This function retrieves the value of the delimiter-separated search
+ path used for loading files.
+
+ NOTES
+ Some applications may not support the built-in load-path searching
+ facility provided by the underlying library.
+
+ SEE ALSO
+
+--------------------------------------------------------------
+
+set_slang_load_path
+
+ SYNOPSIS
+ Set the value of the interpreter's load-path
+
+ USAGE
+ set_slang_load_path (String_Type path)
+
+ DESCRIPTION
+ This function may be used to set the value of the
+ delimiter-separated search path used by the `evalfile' and
+ `autoload' functions for locating files.
+
+ EXAMPLE
+
+ public define prepend_to_slang_load_path (p)
+ {
+ variable s = stat_file (p);
+ if (s == NULL) return;
+ if (0 == stat_is ("dir", s.st_mode))
+ return;
+
+ variable d = path_get_delimiter ();
+ set_slang_load_path (strcat (p, d, get_slang_load_path ()));
+ }
+
+
+ NOTES
+ Some applications may not support the built-in load-path searching
+ facility provided by the underlying library.
+
+ SEE ALSO
+ get_slang_load_path, path_get_delimiter, evalfile, autoload
+--------------------------------------------------------------
+
+get_import_module_path
+
+ SYNOPSIS
+ Get the search path for dynamically loadable objects
+
+ USAGE
+ String_Type get_import_module_path ()
+
+ DESCRIPTION
+ The `get_import_module_path' may be used to get the search path
+ for dynamically shared objects. Such objects may be made accessable
+ to the application via the `import' function.
+
+ SEE ALSO
+ import, set_import_module_path
+--------------------------------------------------------------
+
+import
+
+ SYNOPSIS
+ Dynamically link to a specified module
+
+ USAGE
+ import (String_Type module [, String_Type namespace])
+
+ DESCRIPTION
+ The `import' function causes the run-time linker to dynamically
+ link to the shared object specified by the `module' parameter.
+ It seaches for the shared object as follows: First a search is
+ performed along all module paths specified by the application. Then
+ a search is made along the paths defined via the
+ `set_import_module_path' function. If not found, a search is
+ performed along the paths given by the `SLANG_MODULE_PATH'
+ environment variable. Finally, a system dependent search is
+ performed (e.g., using the `LD_LIBRARY_PATH' environment
+ variable).
+
+ The optional second parameter may be used to specify a namespace
+ for the intrinsic functions and variables of the module. If this
+ parameter is not present, the intrinsic objects will be placed into
+ the global namespace.
+
+ This function signals an error if the specified module is not found.
+
+ NOTES
+ The `import' function is not available on all systems.
+
+ SEE ALSO
+ set_import_module_path, use_namespace, current_namespace, getenv, evalfile
+--------------------------------------------------------------
+
+set_import_module_path
+
+ SYNOPSIS
+ Set the search path for dynamically loadable objects
+
+ USAGE
+ set_import_module_path (String_Type path_list)
+
+ DESCRIPTION
+ The `set_import_module_path' may be used to set the search path
+ for dynamically shared objects. Such objects may be made accessable
+ to the application via the `import' function.
+
+ The actual syntax for the specification of the set of paths will
+ vary according to the operating system. Under Unix, a colon
+ character is used to separate paths in `path_list'. For win32
+ systems a semi-colon is used.
+
+ SEE ALSO
+ import, get_import_module_path
+--------------------------------------------------------------
+
+_NARGS
+
+ SYNOPSIS
+ The number of parameters passed to a function
+
+ USAGE
+ Integer_Type _NARGS
+
+ EXAMPLE
+ This example uses the `_NARGS' variable to print the list of
+ values passed to the function:
+
+ define print_values ()
+ {
+ variable arg;
+
+ if (_NARGS == 0)
+ {
+ message ("Nothing to print");
+ return;
+ }
+ foreach (__pop_args (_NARGS))
+ {
+ arg = ();
+ vmessage ("Argument value is: %S", arg.value);
+ }
+ }
+
+
+ SEE ALSO
+ __pop_args, __push_args, typeof
+--------------------------------------------------------------
+
+__get_defined_symbols
+
+ SYNOPSIS
+ Get the symbols defined by the preprocessor
+
+ USAGE
+ Integer_Type __get_defined_symbols ()
+
+ DESCRIPTION
+ The `__get_defined_symbols' functions is used to get the list of
+ all the symbols defined by the S-Lang preprocessor. It pushes each
+ of the symbols on the stack followed by the number of items pushed.
+
+ SEE ALSO
+ is_defined, _apropos, _get_namespaces
+--------------------------------------------------------------
+
+__is_initialized
+
+ SYNOPSIS
+ Determine whether or not a variable has a value
+
+ USAGE
+ Integer_Type __is_initialized (Ref_Type r)
+
+ DESCRIPTION
+ This function returns non-zero of the object referenced by `r'
+ is initialized, i.e., whether it has a value. It returns 0 if the
+ referenced object has not been initialized.
+
+ EXAMPLE
+ For example, the function:
+
+ define zero ()
+ {
+ variable f;
+ return __is_initialized (&f);
+ }
+
+ will always return zero, but
+
+ define one ()
+ {
+ variable f = 0;
+ return __is_initialized (&f);
+ }
+
+ will return one.
+
+ NOTES
+ It is easy to see why a reference to the variable must be passed to
+ `__is_initialized' and not the variable itself; otherwise, the
+ value of the variable would be passed and the variable may have no
+ value if it was not initialized.
+
+ SEE ALSO
+ __get_reference, __uninitialize, is_defined, typeof, eval
+--------------------------------------------------------------
+
+_apropos
+
+ SYNOPSIS
+ Generate a list of functions and variables
+
+ USAGE
+ Array_Type _apropos (String_Type ns, String_Type s, Integer_Type flags)
+
+ DESCRIPTION
+ The `_apropos' function may be used to get a list of all defined
+ objects in the namespace `ns' whose name matches the regular
+ expression `s' and whose type matches those specified by
+ `flags'. It returns an array of strings representing the
+ matches.
+
+ The second parameter `flags' is a bit mapped value whose bits
+ are defined according to the following table
+
+ 1 Intrinsic Function
+ 2 User-defined Function
+ 4 Intrinsic Variable
+ 8 User-defined Variable
+
+
+ EXAMPLE
+
+ define apropos (s)
+ {
+ variable n, name, a;
+ a = _apropos ("Global", s, 0xF);
+
+ vmessage ("Found %d matches:", length (a));
+ foreach (a)
+ {
+ name = ();
+ message (name);
+ }
+ }
+
+ prints a list of all matches.
+
+ NOTES
+ If the namespace specifier `ns' is the empty string `""',
+ then the namespace will default to the static namespace of the
+ current compilation unit.
+
+ SEE ALSO
+ is_defined, sprintf, _get_namespaces
+--------------------------------------------------------------
+
+_function_name
+
+ SYNOPSIS
+ Returns the name of the currently executing function
+
+ USAGE
+ String_Type _function_name ()
+
+ DESCRIPTION
+ This function returns the name of the currently executing function.
+ If called from top-level, it returns the empty string.
+
+ SEE ALSO
+ _trace_function, is_defined
+--------------------------------------------------------------
+
+_get_namespaces
+
+ SYNOPSIS
+ Returns a list of namespace names
+
+ USAGE
+ String_Type[] _get_namespaces ()
+
+ DESCRIPTION
+ This function returns a string array containing the names of the
+ currently defined namespaces.
+
+ SEE ALSO
+ _apropos, use_namespace, implements, __get_defined_symbols
+--------------------------------------------------------------
+
+_slang_doc_dir
+
+ SYNOPSIS
+ Installed documentation directory
+
+ USAGE
+ String_Type _slang_doc_dir;
+
+ DESCRIPTION
+ The `_slang_doc_dir' variable is a read-only whose value
+ specifies the installation location of the S-Lang documentation.
+
+ SEE ALSO
+ get_doc_string_from_file
+--------------------------------------------------------------
+
+_slang_version
+
+ SYNOPSIS
+ The S-Lang library version number
+
+ USAGE
+ Integer_Type _slang_version
+
+ DESCRIPTION
+ The `_slang_version' variable is read-only and whose
+ value represents the number of the S-Lang library.
+
+ SEE ALSO
+ _slang_version_string
+--------------------------------------------------------------
+
+_slang_version_string
+
+ SYNOPSIS
+ The S-Lang library version number as a string
+
+ USAGE
+ String_Type _slang_version_string
+
+ DESCRIPTION
+ The `_slang_version_string' variable is read-only and whose
+ value represents the version number of the S-Lang library.
+
+ SEE ALSO
+ _slang_version
+--------------------------------------------------------------
+
+get_doc_string_from_file
+
+ SYNOPSIS
+ Read documentation from a file
+
+ USAGE
+ String_Type get_doc_string_from_file (String_Type f, String_Type t)
+
+ DESCRIPTION
+ `get_doc_string_from_file' opens the documentation file `f'
+ and searches it for topic `t'. It returns the documentation for
+ `t' upon success, otherwise it returns `NULL' upon error.
+ It will fail if `f' could not be opened or does not contain
+ documentation for the topic.
+
+ SEE ALSO
+ stat_file
+
+ SEE ALSO
+ _slang_doc_dir
+--------------------------------------------------------------
+
+is_defined
+
+ SYNOPSIS
+ Indicate whether a variable or function defined.
+
+ USAGE
+ Integer_Type is_defined (String_Type obj)
+
+ DESCRIPTION
+ This function is used to determine whether or not a function or
+ variable whose name is `obj' has been defined. If `obj' is not
+ defined, the function returns 0. Otherwise, it returns a non-zero
+ value that defpends on the type of object `obj' represents.
+ Specifically, it returns one of the following values:
+
+ +1 if an intrinsic function
+ +2 if user defined function
+ -1 if intrinsic variable
+ -2 if user defined variable
+ 0 if undefined
+
+
+ EXAMPLE
+ For example, consider the function:
+
+ define runhooks (hook)
+ {
+ if (2 == is_defined(hook)) eval(hook);
+ }
+
+ This function could be called from another S-Lang function to
+ allow customization of that function, e.g., if the function
+ represents a mode, the hook could be called to setup keybindings
+ for the mode.
+
+ SEE ALSO
+ typeof, eval, autoload, __get_reference, __is_initialized
+--------------------------------------------------------------
+
+Conj
+
+ SYNOPSIS
+ Compute the complex conjugate of a number
+
+ USAGE
+ z1 = Conj (z)
+
+ DESCRIPTION
+ The `Conj' function returns the complex conjugate of a number.
+ If its argument is an array, the `Conj' function will be applied to each
+ element and the result returned as an array.
+
+ SEE ALSO
+ Real, Imag, abs
+--------------------------------------------------------------
+
+Imag
+
+ SYNOPSIS
+ Compute the imaginary part of a number
+
+ USAGE
+ i = Imag (z)
+
+ DESCRIPTION
+ The `Imag' function returns the imaginary part of a number.
+ If its argument is an array, the `Imag' function will be applied to each
+ element and the result returned as an array.
+
+ SEE ALSO
+ Real, Conj, abs
+--------------------------------------------------------------
+
+Real
+
+ SYNOPSIS
+ Compute the real part of a number
+
+ USAGE
+ r = Real (z)
+
+ DESCRIPTION
+ The `Real' function returns the real part of a number. If its
+ argument is an array, the `Real' function will be applied to
+ each element and the result returned as an array.
+
+ SEE ALSO
+ Imag, Conj, abs
+--------------------------------------------------------------
+
+abs
+
+ SYNOPSIS
+ Compute the absolute value of a number
+
+ USAGE
+ y = abs(x)
+
+ DESCRIPTION
+ The `abs' function returns the absolute value of an arithmetic
+ type. If its argument is a complex number (`Complex_Type'),
+ then it returns the modulus. If the argument is an array, a new
+ array will be created whose elements are obtained from the original
+ array by using the `abs' function.
+
+ SEE ALSO
+ sign, sqr
+--------------------------------------------------------------
+
+acos
+
+ SYNOPSIS
+ Compute the arc-cosine of an number
+
+ USAGE
+ y = acos (x)
+
+ DESCRIPTION
+ The `acos' function computes the arc-cosine of a number and
+ returns the result as an array. If its argument is an array, the
+ `acos' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+acosh
+
+ SYNOPSIS
+ Compute the inverse cosh of an number
+
+ USAGE
+ y = acosh (x)
+
+ DESCRIPTION
+ The `acosh' function computes the inverse cosh of a number and
+ returns the result as an array. If its argument is an array, the
+ `acosh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+asin
+
+ SYNOPSIS
+ Compute the arc-sine of an number
+
+ USAGE
+ y = asin (x)
+
+ DESCRIPTION
+ The `asin' function computes the arc-sine of a number and
+ returns the result as an array. If its argument is an array, the
+ `asin' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+asinh
+
+ SYNOPSIS
+ Compute the inverse-sinh of an number
+
+ USAGE
+ y = asinh (x)
+
+ DESCRIPTION
+ The `asinh' function computes the inverse-sinh of a number and
+ returns the result as an array. If its argument is an array, the
+ `asinh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+atan
+
+ SYNOPSIS
+ Compute the arc-tangent of an number
+
+ USAGE
+ y = atan (x)
+
+ DESCRIPTION
+ The `atan' function computes the arc-tangent of a number and
+ returns the result as an array. If its argument is an array, the
+ `atan' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+atanh
+
+ SYNOPSIS
+ Compute the inverse-tanh of an number
+
+ USAGE
+ y = atanh (x)
+
+ DESCRIPTION
+ The `atanh' function computes the inverse-tanh of a number and
+ returns the result as an array. If its argument is an array, the
+ `atanh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+cos
+
+ SYNOPSIS
+ Compute the cosine of an number
+
+ USAGE
+ y = cos (x)
+
+ DESCRIPTION
+ The `cos' function computes the cosine of a number and
+ returns the result as an array. If its argument is an array, the
+ `cos' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+cosh
+
+ SYNOPSIS
+ Compute the hyperbolic cosine of an number
+
+ USAGE
+ y = cosh (x)
+
+ DESCRIPTION
+ The `cosh' function computes the hyperbolic cosine of a number and
+ returns the result as an array. If its argument is an array, the
+ `cosh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+exp
+
+ SYNOPSIS
+ Compute the exponential of an number
+
+ USAGE
+ y = exp (x)
+
+ DESCRIPTION
+ The `exp' function computes the exponential of a number and
+ returns the result as an array. If its argument is an array, the
+ `exp' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+log
+
+ SYNOPSIS
+ Compute the logarithm of an number
+
+ USAGE
+ y = log (x)
+
+ DESCRIPTION
+ The `log' function computes the logarithm of a number and
+ returns the result as an array. If its argument is an array, the
+ `log' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+log10
+
+ SYNOPSIS
+ Compute the base-10 logarithm of an number
+
+ USAGE
+ y = log10 (x)
+
+ DESCRIPTION
+ The `log10' function computes the base-10 logarithm of a number and
+ returns the result as an array. If its argument is an array, the
+ `log10' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+mul2
+
+ SYNOPSIS
+ Multiply a number by 2
+
+ USAGE
+ y = mul2(x)
+
+ DESCRIPTION
+ The `mul2' function multiplies an arithmetic type by two and
+ returns the result. If its argument is an array, a new array will
+ be created whose elements are obtained from the original array by
+ using the `mul2' function.
+
+ SEE ALSO
+ sqr, abs
+--------------------------------------------------------------
+
+polynom
+
+ SYNOPSIS
+ Evaluate a polynomial
+
+ USAGE
+ Double_Type polynom(Double_Type a, b, ...c, Integer_Type n, Double_Type x)
+
+ DESCRIPTION
+ The `polynom' function returns the value of the polynomial expression:
+
+ ax^n + bx^(n - 1) + ... c
+
+
+ NOTES
+ The `polynom' function should be extended to work with complex
+ and array data types. The current implementation is limited to
+ `Double_Type' quantities.
+
+ SEE ALSO
+ exp
+--------------------------------------------------------------
+
+set_float_format
+
+ SYNOPSIS
+ Set the format for printing floating point values.
+
+ USAGE
+ set_float_format (String_Type fmt)
+
+ DESCRIPTION
+ The `set_float_format' function is used to set the floating
+ point format to be used when floating point numbers are printed.
+ The routines that use this are the traceback routines and the
+ `string' function. The default value is `"%f"'
+
+ EXAMPLE
+
+ s = string (PI); % --> s = "3.14159"
+ set_float_format ("%16.10f");
+ s = string (PI); % --> s = "3.1415926536"
+ set_float_format ("%10.6e");
+ s = string (PI); % --> s = "3.141593e+00"
+
+
+ SEE ALSO
+ string, sprintf, double
+--------------------------------------------------------------
+
+sign
+
+ SYNOPSIS
+ Compute the sign of a number
+
+ USAGE
+ y = sign(x)
+
+ DESCRIPTION
+ The `sign' function returns the sign of an arithmetic type. If
+ its argument is a complex number (`Complex_Type'), it returns
+ the sign of the imaginary part of the number. If the argument is an
+ array, a new array will be created whose elements are obtained from
+ the original array by using the `sign' function.
+
+ When applied to a real number or an integer, the `sign' function
+ returns -1, 0, or `+1' according to whether the number is
+ less than zero, equal to zero, or greater than zero, respectively.
+
+ SEE ALSO
+ abs
+--------------------------------------------------------------
+
+sin
+
+ SYNOPSIS
+ Compute the sine of an number
+
+ USAGE
+ y = sin (x)
+
+ DESCRIPTION
+ The `sin' function computes the sine of a number and
+ returns the result as an array. If its argument is an array, the
+ `sin' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+sinh
+
+ SYNOPSIS
+ Compute the hyperbolic sine of an number
+
+ USAGE
+ y = sinh (x)
+
+ DESCRIPTION
+ The `sinh' function computes the hyperbolic sine of a number and
+ returns the result as an array. If its argument is an array, the
+ `sinh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+sqr
+
+ SYNOPSIS
+ Compute the square of a number
+
+ USAGE
+ y = sqr(x)
+
+ DESCRIPTION
+ The `sqr' function returns the square of an arithmetic type. If its
+ argument is a complex number (`Complex_Type'), then it returns
+ the square of the modulus. If the argument is an array, a new array
+ will be created whose elements are obtained from the original array
+ by using the `sqr' function.
+
+ SEE ALSO
+ abs, mul2
+--------------------------------------------------------------
+
+sqrt
+
+ SYNOPSIS
+ Compute the square root of an number
+
+ USAGE
+ y = sqrt (x)
+
+ DESCRIPTION
+ The `sqrt' function computes the square root of a number and
+ returns the result as an array. If its argument is an array, the
+ `sqrt' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ sqr, cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+tan
+
+ SYNOPSIS
+ Compute the tangent of an number
+
+ USAGE
+ y = tan (x)
+
+ DESCRIPTION
+ The `tan' function computes the tangent of a number and
+ returns the result as an array. If its argument is an array, the
+ `tan' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+tanh
+
+ SYNOPSIS
+ Compute the hyperbolic tangent of an number
+
+ USAGE
+ y = tanh (x)
+
+ DESCRIPTION
+ The `tanh' function computes the hyperbolic tangent of a number and
+ returns the result as an array. If its argument is an array, the
+ `tanh' function will be applied to each element and the result returned
+ as an array.
+
+ SEE ALSO
+ cos, atan, acosh, cosh
+--------------------------------------------------------------
+
+error
+
+ SYNOPSIS
+ Generate an error condition
+
+ USAGE
+ error (String_Type msg
+
+ DESCRIPTION
+ The `error' function generates a S-Lang error condition causing
+ the interpreter to start unwinding to top-level. It takes a single
+ string parameter which is displayed on the stderr output device.
+ The error condition may be cleared via an `ERROR_BLOCK' with the
+ `_clear_error' function. Consult \user-manual for more
+ information.
+
+ EXAMPLE
+
+ define add_txt_extension (file)
+ {
+ if (typeof (file) != String_Type)
+ error ("add_extension: parameter must be a string");
+ file += ".txt";
+ return file;
+ }
+
+
+ SEE ALSO
+ verror, _clear_error, message
+--------------------------------------------------------------
+
+message
+
+ SYNOPSIS
+ Print a string onto the message device
+
+ USAGE
+ message (String_Type s
+
+ DESCRIPTION
+ The `message' function will print the string specified by
+ `s' onto the message device.
+
+ EXAMPLE
+
+ define print_current_time ()
+ {
+ message (time ());
+ }
+
+
+ NOTES
+ The message device will depend upon the application. For example,
+ the output message device for the `jed' editor correspond to the
+ line at the bottom of the display window. The default message
+ device is the standard output device.
+
+ SEE ALSO
+ vmessage, sprintf, error
+--------------------------------------------------------------
+
+usage
+
+ SYNOPSIS
+ Generate a usage error
+
+ USAGE
+ usage (String_Type msg)
+
+ DESCRIPTION
+ The `usage' function generates a usage exception and displays
+ `msg' to the message device.
+
+ EXAMPLE
+ Suppose that some function `plot' plots an array of `x' and
+ `y' values. The such a function could be written to issue a
+ usage message if the wrong number of arguments were passed:
+
+ define plot ()
+ {
+ variable x, y;
+
+ if (_NARGS != 2)
+ usage ("plot (x, y)");
+
+ (x, y) = ();
+ % Now do the hard part
+ .
+ .
+ }
+
+
+ SEE ALSO
+ error, message
+--------------------------------------------------------------
+
+verror
+
+ SYNOPSIS
+ Generate an error condition
+
+ USAGE
+ verror (String_Type fmt, ...)
+
+ DESCRIPTION
+ The `verror' function performs the same role as the `error'
+ function. The only difference is that instead of a single string
+ argument, `verror' takes a sprintf style argument list.
+
+ EXAMPLE
+
+ define open_file (file)
+ {
+ variable fp;
+
+ fp = fopen (file, "r");
+ if (fp == NULL) verror ("Unable to open %s", file);
+ return fp;
+ }
+
+
+ NOTES
+ In the current implementation, strictly speaking, the `verror'
+ function is not an intrinsic function. Rather it is a predefined
+ S-Lang function using a combination of `Sprintf' and
+ `error'.
+
+ SEE ALSO
+ error, Sprintf, vmessage
+--------------------------------------------------------------
+
+vmessage
+
+ SYNOPSIS
+ Print a formatted string onto the message device
+
+ USAGE
+ vmessage (String_Type fmt, ...)
+
+ DESCRIPTION
+ The `vmessage' function formats a sprintf style argument list
+ and displays the resulting string onto the message device.
+
+ NOTES
+ In the current implementation, strictly speaking, the `vmessage'
+ function is not an intrinsic function. Rather it is a predefined
+ S-Lang function using a combination of `Sprintf' and
+ `message'.
+
+ SEE ALSO
+ message, Sprintf, verror
+--------------------------------------------------------------
+
+__class_id
+
+ SYNOPSIS
+ Return the class-id of a specified type
+
+ USAGE
+ Int_Type __class_id (DataType_Type type))
+
+ DESCRIPTION
+ This function returns the internal class-id of a specified data type.
+
+ SEE ALSO
+ typeof, _typeof, __class_type
+--------------------------------------------------------------
+
+__class_type
+
+ SYNOPSIS
+ Return the class-type of a specified type
+
+ USAGE
+ Int_Type __class_type (DataType_Type type))
+
+ DESCRIPTION
+ Internally S-Lang objects are classified according to four types:
+ scalar, vector, pointer, and memory managed types. For example, an
+ integer is implemented as a scalar, a complex number as a vector,
+ and a string is represented as a pointer. The `__class_type'
+ function returns an integer representing the class-type associated
+ with the specified data type. Specifically, it returns:
+
+ 0 memory-managed
+ 1 scalar
+ 2 vector
+ 3 pointer
+
+
+ SEE ALSO
+ typeof, _typeof, __class_id
+--------------------------------------------------------------
+
+__eqs
+
+ SYNOPSIS
+ Test for equality between two objects
+
+ USAGE
+ Int_Type __eqs (a, b)
+
+ DESCRIPTION
+ This function tests its two arguments for equalit and returns 1
+ if they are equal, and 0 otherwise. To be equal, the data type of
+ the arguments must match and the values of the objects must
+ reference the same underlying object.
+
+ EXAMPLE
+ __eqs (1, 1) ===> 1
+ __eqs (1, 1.0) ===> 0
+ __eqs ("a", 1) ===> 0
+ __eqs ([1,2], [1,2]) ===> 0
+
+ SEE ALSO
+ typeof, __get_reference
+
+ NOTES
+ This function should be thought of as a test for "sameness".
+--------------------------------------------------------------
+
+__get_reference
+
+ SYNOPSIS
+ Get a reference to a global object
+
+ USAGE
+ Ref_Type __get_reference (String_Type nm)
+
+ DESCRIPTION
+ This function returns a reference to a global variable or function
+ whose name is specified by `nm'. If no such object exists, it
+ returns `NULL', otherwise it returns a reference.
+
+ EXAMPLE
+ For example, consider the function:
+
+ define runhooks (hook)
+ {
+ variable f;
+ f = __get_reference (hook);
+ if (f != NULL)
+ @f ();
+ }
+
+ This function could be called from another S-Lang function to
+ allow customization of that function, e.g., if the function
+ represents a mode, the hook could be called to setup keybindings
+ for the mode.
+
+ SEE ALSO
+ is_defined, typeof, eval, autoload, __is_initialized, __uninitialize
+--------------------------------------------------------------
+
+__uninitialize
+
+ SYNOPSIS
+ Uninitialize a variable
+
+ USAGE
+ __uninitialize (Ref_Type x)
+
+ DESCRIPTION
+ The `__uninitialize' function may be used to uninitialize the
+ variable referenced by the parameter `x'.
+
+ EXAMPLE
+ The following two lines are equivalent:
+
+ () = __tmp(z);
+ __uninitialize (&z);
+
+
+ SEE ALSO
+ __tmp, __is_initialized
+--------------------------------------------------------------
+
+_auto_declare
+
+ SYNOPSIS
+ Set automatic variable declaration mode
+
+ USAGE
+ Integer_Type _auto_declare
+
+ DESCRIPTION
+ The `_auto_declare' may be used to have all undefined variables
+ implicitely declared as `static'. If set to zero, any variable
+ must be declared witha `variable' declaration before it can be
+ used. If set to one, then any undeclared variabled will be declared
+ as a `static' global variable.
+
+ The `_auto_declare' variable is local to each compilation unit and
+ setting its value in one unit has no effect upon its value in other
+ units. The value of this variable has no effect upon the variables
+ in a function.
+
+ EXAMPLE
+ The following code will not compile if `X' not been
+ declared:
+
+ X = 1;
+
+ However,
+
+ _auto_declare = 1; % declare variables as static.
+ X = 1;
+
+ is equivalent to
+
+ static variable X = 1;
+
+
+ NOTES
+ This variable should be used sparingly and is intended primarily for
+ interactive applications where one types S-Lang commands at a prompt.
+--------------------------------------------------------------
+
+current_namespace
+
+ SYNOPSIS
+ Get the name of the current namespace
+
+ USAGE
+ String_Type current_namespace ()
+
+ DESCRIPTION
+ The `current_namespace' function returns the name of the
+ current namespace. If the current namespace is anonymous, that is,
+ has not been given a name via the `implements' function, the
+ empty string `""' will be returned.
+
+ SEE ALSO
+ implements, use_namespace, import
+--------------------------------------------------------------
+
+getenv
+
+ SYNOPSIS
+ Get the value of an environment variable
+
+ USAGE
+ String_Type getenv(String_Type var)
+
+ DESCRIPTION
+ The `getenv' function returns a string that represents the
+ value of an environment variable `var'. It will return
+ `NULL' if there is no environment variable whose name is given
+ by `var'.
+
+ EXAMPLE
+
+ if (NULL != getenv ("USE_COLOR"))
+ {
+ set_color ("normal", "white", "blue");
+ set_color ("status", "black", "gray");
+ USE_ANSI_COLORS = 1;
+ }
+
+
+ SEE ALSO
+ putenv, strlen, is_defined
+--------------------------------------------------------------
+
+implements
+
+ SYNOPSIS
+ Name a private namespace
+
+ USAGE
+ implements (String_Type name);
+
+ DESCRIPTION
+ The `implements' function may be used to name the private
+ namespace associated with the current compilation unit. Doing so
+ will enable access to the members of the namespace from outside the
+ unit. The name of the global namespace is `Global'.
+
+ EXAMPLE
+ Suppose that some file `t.sl' contains:
+
+ implements ("Ts_Private");
+ static define message (x)
+ {
+ Global->vmessage ("Ts_Private message: %s", x);
+ }
+ message ("hello");
+
+ will produce `"Ts_Private message: hello"'. This `message'
+ function may be accessed from outside via:
+
+ Ts_Private->message ("hi");
+
+
+ NOTES
+ Since `message' is an intrinsic function, it is global and may
+ not be redefined in the global namespace.
+
+ SEE ALSO
+ use_namespace, current_namespace, import
+--------------------------------------------------------------
+
+putenv
+
+ SYNOPSIS
+ Add or change an environment variable
+
+ USAGE
+ putenv (String_Type s)
+
+ DESCRIPTION
+ This functions adds string `s' to the environment. Typically,
+ `s' should of the form `"name=value"'. The function
+ signals a S-Lang error upon failure.
+
+ NOTES
+ This function is not available on all systems.
+
+ SEE ALSO
+ getenv, sprintf
+--------------------------------------------------------------
+
+use_namespace
+
+ SYNOPSIS
+ Change to another namespace
+
+ USAGE
+ use_namespace (String_Type name)
+
+ DESCRIPTION
+ The `use_namespace' function changes the current namespace to
+ the one specified by the parameter. If the specified namespace
+ does not exist, an error will be generated.
+
+ SEE ALSO
+ implements, current_namespace, import
+--------------------------------------------------------------
+
+path_basename
+
+ SYNOPSIS
+ Get the basename part of a pathname
+
+ USAGE
+ String_Type path_basename (String_Type path)
+
+ DESCRIPTION
+ The `path_basename' function returns the basename associated
+ with the `path' parameter. The basename is the non-directory
+ part of the filename, e.g., on unix `c' is the basename of
+ `/a/b/c'.
+
+ SEE ALSO
+ path_dirname, path_extname, path_concat, path_is_absolute
+--------------------------------------------------------------
+
+path_concat
+
+ SYNOPSIS
+ Combine elements of a pathname
+
+ USAGE
+ String_Type path_concat (String_Type dir, String_Type basename)
+
+ DESCRIPTION
+ The `path_concat' function combines the arguments `dir' and
+ `basename' to produce a pathname. For example, on unix is
+ `dir' is `x/y' and `basename' is `z', then the
+ function will return `x/y/z'.
+
+ SEE ALSO
+ path_dirname, path_basename, path_extname, path_is_absolute
+--------------------------------------------------------------
+
+path_dirname
+
+ SYNOPSIS
+ Get the directory name part of a pathname
+
+ USAGE
+ String_Type path_dirname (String_Type path)
+
+ DESCRIPTION
+ The `path_dirname' function returns the directory name
+ associated with a specified pathname.
+
+ NOTES
+ On systems that include a drive specifier as part of the pathname,
+ the value returned by this function will include the driver
+ specifier.
+
+ SEE ALSO
+ path_basename, path_extname, path_concat, path_is_absolute
+--------------------------------------------------------------
+
+path_extname
+
+ SYNOPSIS
+ Return the extension part of a pathname
+
+ USAGE
+ String_Type path_extname (String_Type path)
+
+ DESCRIPTION
+ The `path_extname' function returns the extension portion of a
+ specified pathname. If an extension is present, this function will
+ also include the dot as part of the extension, i.e., if `path'
+ is `file.c', then this function returns `".c"'. If no
+ extension is present, the function returns an empty string `""'.
+
+ NOTES
+ Under VMS, the file version number is not returned as part of the
+ extension.
+
+ SEE ALSO
+ path_sans_extname, path_dirname, path_basename, path_concat, path_is_absolute
+--------------------------------------------------------------
+
+path_get_delimiter
+
+ SYNOPSIS
+ Get the value of a search-path delimiter
+
+ USAGE
+ Char_Type path_get_delimiter ()
+
+ DESCRIPTION
+ This function returns the value of the character used to delimit
+ fields of a search-path.
+
+ SEE ALSO
+ set_slang_load_path, get_slang_load_path
+--------------------------------------------------------------
+
+path_is_absolute
+
+ SYNOPSIS
+ Determine whether or not a pathname is absolute
+
+ USAGE
+ Int_Type path_is_absolute (String_Type path)
+
+ DESCRIPTION
+ The `path_is_absolute' function will return non-zero is
+ `path' refers to an absolute pathname, otherwise it returns zero.
+
+ SEE ALSO
+ path_dirname, path_basename, path_extname, path_concat
+--------------------------------------------------------------
+
+path_sans_extname
+
+ SYNOPSIS
+ Strip the extension from a pathname
+
+ USAGE
+ String_Type path_sans_extname (String_Type path)
+
+ DESCRIPTION
+ The `path_sans_extname' function removes the file name extension
+ (including the dot) from the path and returns the result.
+
+ SEE ALSO
+ path_extname, path_basename, path_dirname, path_concat
+--------------------------------------------------------------
+
+close
+
+ SYNOPSIS
+ Close an open file descriptor
+
+ USAGE
+ Int_Type close (FD_Type fd)
+
+ DESCRIPTION
+ The `close' function is used to open file descriptor of type
+ `FD_Type'. Upon success 0 is returned, otherwise the function
+ returns -1 and sets `errno' accordingly.
+
+ SEE ALSO
+ open, fclose, read, write
+--------------------------------------------------------------
+
+dup_fd
+
+ SYNOPSIS
+ Duplicate a file descriptor
+
+ USAGE
+ FD_Type dup_fd (FD_Type fd)
+
+ DESCRIPTION
+ The `dup_fd' function duplicates and file descriptor and returns
+ its duplicate. If the function fails, NULL will be returned and
+ `errno' set accordingly.
+
+ NOTES
+ This function is essentually a wrapper around the POSIX `dup'
+ function.
+
+ SEE ALSO
+ open, close
+--------------------------------------------------------------
+
+fileno
+
+ SYNOPSIS
+ Convert a stdio File_Type object to a FD_Type descriptor
+
+ USAGE
+ FD_Type fileno (File_Type fp)
+
+ DESCRIPTION
+ The `fileno' function returns the `FD_Type' descriptor
+ associated with the `File_Type' file pointer. Upon failure,
+ NULL is returned.
+
+ SEE ALSO
+ fopen, open, fclose, close, dup_fd
+--------------------------------------------------------------
+
+isatty
+
+ SYNOPSIS
+ Determine if an open file descriptor refers to a terminal
+
+ USAGE
+ Int_Type isatty (FD_Type or File_Type fd)
+
+ DESCRIPTION
+ This function returns 1 if the file descriptor `fd' refers to a
+ terminal; otherwise it returns 0. The object `fd' may either
+ be a `File_Type' stdio descriptor or an `FD_Type' object.
+
+ SEE ALSO
+ fopen, fclose, fileno
+--------------------------------------------------------------
+
+lseek
+
+ SYNOPSIS
+ Reposition a file descriptor's file pointer
+
+ USAGE
+ Long_Type lseek (FD_Type fd, Long_Type ofs, int mode)
+
+ SEEK_SET Set the offset to ofs
+ SEEK_CUR Add ofs to the current offset
+ SEEK_END Add ofs to the current file size
+
+
+ NOTES
+ Not all file descriptors are capable of supporting the seek
+ operation, e.g., a descriptor associated with a pipe.
+
+ By using `SEEK_END' with a positive value of the `ofs'
+ parameter, it is possible to position the file pointer beyond the
+ current size of the file.
+
+ SEE ALSO
+ fseek, ftell, open, close
+--------------------------------------------------------------
+
+open
+
+ SYNOPSIS
+ Open a file
+
+ USAGE
+ FD_Type open (String_Type filename, Int_Type flags [,Int_Type mode])
+
+ DESCRIPTION
+ The `open' function attempts to open a file specified by the
+ `filename' parameter according to the `flags' parameter,
+ which must be one of the following values:
+
+ O_RDONLY (read-only)
+ O_WRONLY (write-only)
+ O_RDWR (read/write)
+
+ In addition, `flags' may also be bitwise-or'd with any of the
+ following:
+
+ O_BINARY (open the file in binary mode)
+ O_TEXT (open the file in text mode)
+ O_CREAT (create file if it does not exist)
+ O_EXCL (fail if the file already exists)
+ O_NOCTTY (do not make the device the controlling terminal)
+ O_TRUNC (truncate the file if it exists)
+ O_APPEND (open the file in append mode)
+ O_NONBLOCK (open the file in non-blocking mode)
+
+ Some of these flags only make sense when combined with other flags.
+ For example, if O_EXCL is used, then O_CREAT must also be
+ specified, otherwise unpredictable behavior may result.
+
+ If `O_CREAT' is used for the `flags' parameter then the
+ `mode' parameter must be present. `mode' specifies the
+ permissions to use if a new file is created. The actual file
+ permissions will be affected by the process's `umask' via
+ `mode&~umask'. The `mode' parameter's value is
+ constructed via bitwise-or of the following values:
+
+ S_IRWXU (Owner has read/write/execute permission)
+ S_IRUSR (Owner has read permission)
+ S_IWUSR (Owner has write permission)
+ S_IXUSR (Owner has execute permission)
+ S_IRWXG (Group has read/write/execute permission)
+ S_IRGRP (Group has read permission)
+ S_IWGRP (Group has write permission)
+ S_IXGRP (Group has execute permission)
+ S_IRWXO (Others have read/write/execute permission)
+ S_IROTH (Others have read permission)
+ S_IWOTH (Others have write permission)
+ S_IXOTH (Others have execute permission)
+
+ Upon success `open' returns a file descriptor object
+ (`FD_Type'), otherwise `NULL' is returned and `errno'
+ is set.
+
+ NOTES
+ If you are not familiar with the `open' system call, then it
+ is recommended that you use `fopen' instead.
+
+ SEE ALSO
+ fopen, close, read, write, stat_file
+--------------------------------------------------------------
+
+read
+
+ SYNOPSIS
+ Read from an open file descriptor
+
+ USAGE
+ UInt_Type read (FD_Type fd, Ref_Type buf, UInt_Type num)
+
+ DESCRIPTION
+ The `read' function attempts to read at most `num' bytes
+ into the variable indicated by `buf' from the open file
+ descriptor `fd'. It returns the number of bytes read, or -1
+ and sets `errno' upon failure. The number of bytes read may be
+ less than `num', and will be zero if an attempt is made to read
+ past the end of the file.
+
+ NOTES
+ `read' is a low-level function and may return -1 for a variety
+ of reasons. For example, if non-blocking I/O has been specified for
+ the open file descriptor and no data is available for reading then
+ the function will return -1 and set `errno' to `EAGAIN'.
+
+ SEE ALSO
+ fread, open, close, write
+--------------------------------------------------------------
+
+write
+
+ SYNOPSIS
+ Write to an open file descriptor
+
+ USAGE
+ UInt_Type write (FD_Type fd, BString_Type buf)
+
+ DESCRIPTION
+ The `write' function attempts to write the bytes specified by
+ the `buf' parameter to the open file descriptor `fd'. It
+ returns the number of bytes successfully written, or -1 and sets
+ `errno' upon failure. The number of bytes written may be less
+ than `length(buf)'.
+
+ SEE ALSO
+ read, fwrite, open, close
+--------------------------------------------------------------
+
+errno
+
+ SYNOPSIS
+ Error code set by system functions.
+
+ USAGE
+ Integer_Type errno
+
+ DESCRIPTION
+ A system function can fail for a variety of reasons. For example, a
+ file operation may fail because lack of disk space, or the process
+ does not have permission to perform the operation. Such functions
+ will return `-1' and set the variable `errno' to an error
+ code describing the reason for failure.
+
+ Particular values of `errno' may be specified by the following
+ symbolic constants (read-only variables) and the corresponding
+ `errno_string' value:
+
+ EPERM "Not owner"
+ ENOENT "No such file or directory"
+ ESRCH "No such process"
+ ENXIO "No such device or address"
+ ENOEXEC "Exec format error"
+ EBADF "Bad file number"
+ ECHILD "No children"
+ ENOMEM "Not enough core"
+ EACCES "Permission denied"
+ EFAULT "Bad address"
+ ENOTBLK "Block device required"
+ EBUSY "Mount device busy"
+ EEXIST "File exists"
+ EXDEV "Cross-device link"
+ ENODEV "No such device"
+ ENOTDIR "Not a directory"
+ EISDIR "Is a directory"
+ EINVAL "Invalid argument"
+ ENFILE "File table overflow"
+ EMFILE "Too many open files"
+ ENOTTY "Not a typewriter"
+ ETXTBSY "Text file busy"
+ EFBIG "File too large"
+ ENOSPC "No space left on device"
+ ESPIPE "Illegal seek"
+ EROFS "Read-only file system"
+ EMLINK "Too many links"
+ EPIPE "Broken pipe"
+ ELOOP "Too many levels of symbolic links"
+ ENAMETOOLONG "File name too long"
+
+
+ EXAMPLE
+ The `mkdir' function will attempt to create a directory. If
+ that directory already exists, the function will fail and set
+ `errno' to `EEXIST'.
+
+ define create_dir (dir)
+ {
+ if (0 == mkdir (dir)) return;
+ if (errno != EEXIST)
+ error ("mkdir %s failied: %s", dir, errno_string);
+ }
+
+
+ SEE ALSO
+ errno_string, error, mkdir
+--------------------------------------------------------------
+
+errno_string
+
+ SYNOPSIS
+ Return a string describing an errno.
+
+ USAGE
+ String_Type errno_string (Integer_Type err)
+
+ DESCRIPTION
+ The `errno_string' function returns a string describing the
+ integer error code `err'. The variable `err' usually
+ corresponds to the `errno' intrinsic function. See the
+ description for `errno' for more information.
+
+ EXAMPLE
+ The `errno_string' function may be used as follows:
+
+ define sizeof_file (file)
+ {
+ variable st = stat (file);
+ if (st == NULL)
+ verror ("%s: %s", file, errno_string (errno);
+ return st.st_size;
+ }
+
+
+ SEE ALSO
+ errno, stat, verror
+--------------------------------------------------------------
+
+getegid
+
+ SYNOPSIS
+ Get the effective group id
+
+ USAGE
+ Int_Type getegid ()
+
+ DESCRIPTION
+ The `getegid' function returns the effective group ID of the
+ current process.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getgid, geteuid, setgid
+--------------------------------------------------------------
+
+geteuid
+
+ SYNOPSIS
+ Get the effective user-id of the current process
+
+ USAGE
+ Int_Type geteuid ()
+
+ DESCRIPTION
+ The `geteuid' function returns the effective user-id of the
+ current process.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getuid, setuid, setgid
+--------------------------------------------------------------
+
+getgid
+
+ SYNOPSIS
+ Get the group id
+
+ USAGE
+ Integer_Type getgid ()
+
+ DESCRIPTION
+ The `getgid' function returns the real group id of the current
+ process.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getpid, getppid
+--------------------------------------------------------------
+
+getpid
+
+ SYNOPSIS
+ Get the current process id
+
+ USAGE
+ Integer_Type getpid ()
+
+ DESCRIPTION
+ The `getpid' function returns the current process identification
+ number.
+
+ SEE ALSO
+ getppid, getgid
+--------------------------------------------------------------
+
+getppid
+
+ SYNOPSIS
+ Get the parent process id
+
+ USAGE
+ Integer_Type getppid ()
+
+ DESCRIPTION
+ The `getpid' function returns the process identification
+ number of the parent process.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getpid, getgid
+--------------------------------------------------------------
+
+getuid
+
+ SYNOPSIS
+ Get the user-id of the current process
+
+ USAGE
+ Int_Type getuid ()
+
+ DESCRIPTION
+ The `getuid' function returns the user-id of the current
+ process.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getuid, getegid
+--------------------------------------------------------------
+
+kill
+
+ SYNOPSIS
+ Send a signal to a process
+
+ USAGE
+ Integer_Type kill (Integer_Type pid, Integer_Type sig)
+
+ DESCRIPTION
+ This function may be used to send a signal given by the integer `sig'
+ to the process specified by `pid'. The function returns zero upon
+ success and `-1' upon failure setting errno accordingly.
+
+ EXAMPLE
+ The `kill' function may be used to determine whether or not
+ a specific process exists:
+
+ define process_exists (pid)
+ {
+ if (-1 == kill (pid, 0))
+ return 0; % Process does not exist
+ return 1;
+ }
+
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getpid
+--------------------------------------------------------------
+
+mkfifo
+
+ SYNOPSIS
+ Create a named pipe
+
+ USAGE
+ Int_Type mkfifo (String_Type name, Int_Type mode)
+
+ DESCRIPTION
+ The `mkfifo' attempts to create a named pipe with the specified
+ name and mode (modified by the process's umask). The function
+ returns 0 upon success, or -1 and sets `errno' upon failure.
+
+ NOTES
+ Not all systems support the `mkfifo' function and even on
+ systems that do implement the `mkfifo' system call, the
+ underlying file system may not support the concept of a named pipe,
+ e.g, an NFS filesystem.
+
+ SEE ALSO
+ stat_file
+--------------------------------------------------------------
+
+setgid
+
+ SYNOPSIS
+ Set the group-id of the current process
+
+ USAGE
+ Int_Type setgid (Int_Type gid)
+
+ DESCRIPTION
+ The `setgid' function sets the effective group-id of the current
+ process. It returns zero upon success, or -1 upon error and sets
+ `errno' appropriately.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ getgid, setuid
+--------------------------------------------------------------
+
+setpgid
+
+ SYNOPSIS
+ Set the process group-id
+
+ USAGE
+ Int_Type setpgid (Int_Type pid, Int_Type gid)
+
+ DESCRIPTION
+ The `setpgid' function sets the group-id `gid' of the
+ process whose process-id is `pid'. If `pid' is 0, then the
+ current process-id will be used. If `pgid' is 0, then the pid
+ of the affected process will be used.
+
+ If successful zero will be returned, otherwise the function will
+ return -1 and set `errno' accordingly.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ setgid, setuid
+--------------------------------------------------------------
+
+setuid
+
+ SYNOPSIS
+ Set the user-id of the current process
+
+ USAGE
+ Int_Type setuid (Int_Type id)
+
+ DESCRIPTION
+ The `setuid' function sets the effective user-id of the current
+ process. It returns zero upon success, or -1 upon error and sets
+ `errno' appropriately.
+
+ NOTES
+ This function is not supported by all systems.
+
+ SEE ALSO
+ setgid, setpgid, getuid, geteuid
+--------------------------------------------------------------
+
+sleep
+
+ SYNOPSIS
+ Pause for a specified number of seconds
+
+ USAGE
+ sleep (Double_Type n)
+
+ DESCRIPTION
+ The `sleep' function delays the current process for the
+ specified number of seconds. If it is interrupted by a signal, it
+ will return prematurely.
+
+ NOTES
+ Not all system support sleeping for a fractional part of a second.
+--------------------------------------------------------------
+
+system
+
+ SYNOPSIS
+ Execute a shell command
+
+ USAGE
+ Integer_Type system (String_Type cmd)
+
+ DESCRIPTION
+ The `system' function may be used to execute the string
+ expression `cmd' in an inferior shell. This function is an
+ interface to the C `system' function which returns an
+ implementation-defined result. On Linux, it returns 127 if the
+ inferior shell could not be invoked, -1 if there was some other
+ error, otherwise it returns the return code for `cmd'.
+
+ EXAMPLE
+
+ define dir ()
+ {
+ () = system ("DIR");
+ }
+
+ displays a directory listing of the current directory under MSDOS or
+ VMS.
+
+ SEE ALSO
+ popen, listdir
+--------------------------------------------------------------
+
+umask
+
+ SYNOPSIS
+ Set the file creation mask
+
+ USAGE
+ Int_Type umask (Int_Type m)
+
+ DESCRIPTION
+ The `umask' function sets the file creation mask to `m' and
+ returns the previous mask.
+
+ SEE ALSO
+ stat_file
+--------------------------------------------------------------
+
+uname
+
+ SYNOPSIS
+ Get the system name
+
+ USAGE
+ Struct_Tye uname ()
+
+ DESCRIPTION
+ The `uname' function returns a structure containing information
+ about the operating system. The structure contains the following
+ fields:
+
+ sysname (Name of the operating system)
+ nodename (Name of the node within the network)
+ release (Release level of the OS)
+ version (Current version of the release)
+ machine (Name of the hardware)
+
+
+ NOTES
+ Not all systems support this function.
+
+ SEE ALSO
+ getenv, pack, unpack
+--------------------------------------------------------------
+
+__pop_args
+
+ SYNOPSIS
+ Remove n function arguments from the stack
+
+ USAGE
+ variable args = __pop_args(Integer_Type n);
+
+ DESCRIPTION
+ This function together with the companion function `__push_args'
+ is useful for passing the arguments of a function to another function.
+ `__pop_args' returns an array of `n' structures with a
+ single structure field called `value', which represents the value
+ of the argument.
+
+ EXAMPLE
+ Consider the following `print' function. It prints all its
+ arguments to `stdout' separated by spaces:
+
+ define print ()
+ {
+ variable i;
+ variable args = __pop_args (_NARGS);
+
+ for (i = 0; i < _NARGS; i++)
+ {
+ () = fputs (string (args[i].value), stdout);
+ () = fputs (" ", stdout);
+ }
+ () = fputs ("\n", stdout);
+ () = fflush (stdout);
+ }
+
+ Now consider the problem of defining a function called `ones'
+ that returns a multi-dimensional array with all the elements set to
+ 1. For example, `ones(10)' should return a 1-d array of ones,
+ whereas `ones(10,20)' should return a 10x20 array.
+
+ define ones ()
+ {
+ !if (_NARGS) return 1;
+ variable a;
+
+ a = __pop_args (_NARGS);
+ return @Array_Type (Integer_Type, [__push_args (a)]) + 1;
+ }
+
+ Here, `__push_args' was used to push on the arguments passed to
+ the `ones' function onto the stack to be used when dereferencing
+ `Array_Type'.
+
+ SEE ALSO
+ __push_args, typeof, _pop_n
+--------------------------------------------------------------
+
+__push_args
+
+ SYNOPSIS
+ Remove n function arguments onto the stack
+
+ USAGE
+ __push_args (Struct_Type args);
+
+ DESCRIPTION
+ This function together with the companion function `__pop_args'
+ is useful for passing the arguments of one function to another.
+ See the desription of `__pop_args' for more information.
+
+ SEE ALSO
+ __pop_args, typeof, _pop_n
+--------------------------------------------------------------
+
+_pop_n
+
+ SYNOPSIS
+ Remove objects from the stack
+
+ USAGE
+ _pop_n (Integer_Type n);
+
+ DESCRIPTION
+ The `_pop_n' function pops `n' objects from the top of the
+ stack.
+
+ EXAMPLE
+
+ define add3 ()
+ {
+ variable x, y, z;
+ if (_NARGS != 3)
+ {
+ _pop_n (_NARGS);
+ error ("add3: Expecting 3 arguments");
+ }
+ (x, y, z) = ();
+ return x + y + z;
+ }
+
+
+ SEE ALSO
+ _stkdepth, pop
+--------------------------------------------------------------
+
+_print_stack
+
+ SYNOPSIS
+ print the values on the stack.
+
+ USAGE
+ _print_stack ()
+
+ DESCRIPTION
+ This function dumps out what is currently on the S-Lang. It does not
+ alter the stack and it is usually used for debugging purposes.
+
+ SEE ALSO
+ _stkdepth, string
+--------------------------------------------------------------
+
+_stk_reverse
+
+ SYNOPSIS
+ Reverse the order of the objects on the stack.
+
+ USAGE
+ _stk_reverse (Integer_Type n)
+
+ DESCRIPTION
+ The `_stk_reverse' function reverses the order of the top
+ `n' items on the stack.
+
+ SEE ALSO
+ _stkdepth, _stk_roll
+--------------------------------------------------------------
+
+_stk_roll
+
+ SYNOPSIS
+ Roll items on the stack
+
+ USAGE
+ _stk_roll (Integer_Type n);
+
+ DESCRIPTION
+ This function may be used to alter the arrangement of objects on the
+ stack. Specifically, if the integer `n' is positive, the top
+ `n' items on the stack are rotated up. If
+ `n' is negative, the top `abs(n)' items on the stack are
+ rotated down.
+
+ EXAMPLE
+ If the stack looks like:
+
+ item-0
+ item-1
+ item-2
+ item-3
+
+ where `item-0' is at the top of the stack, then
+ `_stk_roll(-3)' will change the stack to:
+
+ item-2
+ item-0
+ item-1
+ item-3
+
+
+ NOTES
+ This function only has an effect for `abs(n) > 1'.
+
+ SEE ALSO
+ _stkdepth, _stk_reverse, _pop_n, _print_stack
+--------------------------------------------------------------
+
+_stkdepth
+
+ USAGE
+ Get the number of objects currently on the stack.
+
+ SYNOPSIS
+ Integer_Type _stkdepth ()
+
+ DESCRIPTION
+ The `_stkdepth' function returns number of items on stack prior
+ to the call of `_stkdepth'.
+
+ SEE ALSO
+ _print_stack, _stk_reverse, _stk_roll
+--------------------------------------------------------------
+
+dup
+
+ SYNOPSIS
+ Duplicate the value at the top of the stack
+
+ USAGE
+ dup ()
+
+ DESCRIPTION
+ This function returns an exact duplicate of the object on top of the
+ stack. For some objects such as arrays or structures, it creates a
+ new reference to the array. However, for simple scalar S-Lang types such
+ as strings, integers, and doubles, it creates a new copy of the
+ object.
+
+ SEE ALSO
+ pop, typeof
+--------------------------------------------------------------
+
+exch
+
+ SYNOPSIS
+ Exchange two items on the stack
+
+ USAGE
+ exch ()
+
+ DESCRIPTION
+ The `exch' swaps the two top items on the stack.
+
+ SEE ALSO
+ pop, _stk_reverse, _stk_roll
+--------------------------------------------------------------
+
+pop
+
+ SYNOPSIS
+ Discard an item from the stack
+
+ USAGE
+ pop ()
+
+ DESCRIPTION
+ The `pop' function removes the top item from the stack.
+
+ SEE ALSO
+ _pop_n
+--------------------------------------------------------------
+
+clearerr
+
+ SYNOPSIS
+ Clear the error of a file stream
+
+ USAGE
+ clearerr (File_Type fp
+
+ DESCRIPTION
+ The `clearerr' function clears the error and end-of-file flags
+ associated with the open file stream `fp'.
+
+ SEE ALSO
+ ferror, feof, fopen
+--------------------------------------------------------------
+
+fclose
+
+ SYNOPSIS
+ Close a file
+
+ USAGE
+ Integer_Type fclose (File_Type fp)
+
+ DESCRIPTION
+ The `fclose' function may be used to close an open file pointer
+ `fp'. Upon success it returns zero, and upon failure it sets
+ `errno' and returns `-1'. Failure usually indicates a that
+ the file system is full or that `fp' does not refer to an open file.
+
+ NOTES
+ Many C programmers call `fclose' without checking the return
+ value. The S-Lang language requires the programmer to explicitly
+ handle any value returned by a S-Lang function. The simplest way to
+ handle the return value from `fclose' is to use it as:
+
+ () = fclose (fp);
+
+
+ SEE ALSO
+ fopen, fgets, fflush, pclose, errno
+--------------------------------------------------------------
+
+fdopen
+
+ SYNOPSIS
+ Convert a FD_Type file descriptor to a stdio File_Type object
+
+ USAGE
+ File_Type fdopen (FD_Type, String_Type mode)
+
+ DESCRIPTION
+ The `fdopen' function creates and returns a stdio
+ `File_Type' object from the open `FD_Type'
+ descriptor `fd'. The `mode' parameter corresponds to the
+ `mode' parameter of the `fopen' function and must be
+ consistent with the mode of the descriptor `fd'. The function
+ returns NULL upon failure and sets `errno'.
+
+ NOTES
+ The `fclose' function does not close the `File_Type' object
+ returned from this function. The underlying file object must be
+ closed by the `close' function.
+
+ SEE ALSO
+ fileno, fopen, open, close, fclose
+--------------------------------------------------------------
+
+feof
+
+ SYNOPSIS
+ Get the end-of-file status
+
+ USAGE
+ Integer_Type feof (File_Type fp)
+
+ DESCRIPTION
+ This function may be used to determine the state of the end-of-file
+ indicator of the open file descriptor `fp'. It returns `0'
+ if the indicator is not set, or non-zero if it is. The end-of-file
+ indicator may be cleared by the `clearerr' function.
+
+ SEE ALSO
+ ferror, clearerr, fopen
+--------------------------------------------------------------
+
+ferror
+
+ SYNOPSIS
+ Determine the error status of an open file descriptor
+
+ USAGE
+ Integer_Type ferror (File_Type fp)
+
+ DESCRIPTION
+ This function may be used to determine the state of the error
+ indicator of the open file descriptor `fp'. It returns `0'
+ if the indicator is not set, or non-zero if it is. The error
+ indicator may be cleared by the `clearerr' function.
+
+ SEE ALSO
+ feof, clearerr, fopen
+--------------------------------------------------------------
+
+fflush
+
+ SYNOPSIS
+ Flush an output stream
+
+ USAGE
+ Integer_Type fflush (File_Type fp)
+
+ DESCRIPTION
+ The `fflush' function may be used to update the _output_
+ stream specified by `fp'. It returns `0' upon success, or
+ `-1' upon failure and sets `errno' accordingly. In
+ particular, this function will fail if `fp' does not represent
+ an output stream, or if `fp' is associated with a disk file and
+ there is insufficient disk space.
+
+ EXAMPLE
+ This example illustrates how to use the `fflush' function
+ without regard to the return value:
+
+ () = fputs ("Enter value> ", stdout);
+ () = fflush (stdout);
+
+
+ NOTES
+ Many C programmers disregard the return value from the `fflush'
+ function. The above example illustrates how to properly do this in
+ the S-Lang langauge.
+
+ SEE ALSO
+ fopen, fclose
+--------------------------------------------------------------
+
+fgets
+
+ SYNOPSIS
+ Read a line from a file.
+
+ USAGE
+ Integer_Type fgets (SLang_Ref_Type ref, File_Type fp)
+
+ DESCRIPTION
+ `fgets' reads a line from the open file specified by `fp'
+ and places the characters in the variable whose reference is
+ specified by `ref'.
+ It returns `-1' if `fp' is not associated with an open file
+ or an attempt was made to read at the end the file; otherwise, it
+ returns the number of characters read.
+
+ EXAMPLE
+ The following example returns the lines of a file via a linked list:
+
+ define read_file (file)
+ {
+ variable buf, fp, root, tail;
+ variable list_type = struct { text, next };
+
+ root = NULL;
+
+ fp = fopen(file, "r");
+ if (fp == NULL)
+ error("fopen %s failed." file);
+ while (-1 != fgets (&buf, fp))
+ {
+ if (root == NULL)
+ {
+ root = @list_type;
+ tail = root;
+ }
+ else
+ {
+ tail.next = @list_type;
+ tail = tail.next;
+ }
+ tail.text = buf;
+ tail.next = NULL;
+ }
+ () = fclose (fp);
+ return root;
+ }
+
+
+ SEE ALSO
+ fopen, fclose, fputs, fread, error
+--------------------------------------------------------------
+
+fgetslines
+
+ SYNOPSIS
+ Read all the lines from an open file
+
+ USAGE
+ String_Type[] fgetslines (File_Type fp)
+
+ DESCRIPTION
+ The `fgetslines' function returns all the remaining lines as an
+ array of strings in the file specified by the open file pointer
+ `fp'. If the file is empty, an empty string array will be
+ returned. The function returns `NULL' upon error.
+
+ EXAMPLE
+ The following function returns the number of lines in a file:
+
+ define count_lines_in_file (file)
+ {
+ variable fp, lines;
+
+ fp = fopen (file, "r");
+ if (fp == NULL)
+ return -1;
+
+ lines = fgetslines (fp);
+ if (lines == NULL)
+ return -1;
+
+ return length (lines);
+ }
+
+ Note that the file was implicitly closed by the function.
+
+ NOTES
+ This function should not be used if the file contains many lines
+ since that would require that all the lines be read into memory.
+
+ SEE ALSO
+ fgets, fread, fopen
+--------------------------------------------------------------
+
+fopen
+
+ SYNOPSIS
+ Open a file
+
+ USAGE
+ File_Type fopen (String_Type f, String_Type m)
+
+ DESCRIPTION
+ The `fopen' function opens a file `f' according to the mode
+ string `m'. Allowed values for `m' are:
+
+ "r" Read only
+ "w" Write only
+ "a" Append
+ "r+" Reading and writing at the beginning of the file.
+ "w+" Reading and writing. The file is created if it does not
+ exist; otherwise, it is truncated.
+ "a+" Reading and writing at the end of the file. The file is created
+ if it does not already exist.
+
+ In addition, the mode string can also include the letter `'b''
+ as the last character to indicate that the file is to be opened in
+ binary mode.
+
+ Upon success, `fopen' a `File_Type' object which is meant to
+ be used in other operations that require an open file. Upon
+ failure, the function returns `NULL'.
+
+ EXAMPLE
+ The following function opens a file in append mode and writes a
+ string to it:
+
+ define append_string_to_file (file, str)
+ {
+ variable fp = fopen (file, "a");
+ if (fp == NULL) verror ("%s could not be opened", file);
+ () = fputs (string, fp);
+ () = fclose (fp);
+ }
+
+ Note that the return values from `fputs' and `fclose' are
+ ignored.
+
+ NOTES
+ There is no need to explicitly close a file opened with `fopen'.
+ If the returned `File_Type' object goes out of scope, S-Lang
+ will automatically close the file. However, explicitly closing a
+ file after use is recommended.
+
+ SEE ALSO
+ fclose, fgets, fputs, popen
+--------------------------------------------------------------
+
+fprintf
+
+ SYNOPSIS
+ Create and write a formatted string to a file
+
+ USAGE
+ Int_Type fprintf (File_Type fp, String_Type fmt, ...)
+
+ DESCRIPTION
+ `fprintf' formats the objects specified by the variable argument
+ list according to the format `fmt' and write the result to the
+ open file pointer `fp'.
+
+ The format string obeys the same syntax and semantics as the
+ `sprintf' format string. See the description of the
+ `sprintf' function for more information.
+
+ `fprintf' returns the number of characters written to the file,
+ or -1 upon error.
+
+ SEE ALSO
+ fputs, printf, fwrite, message
+--------------------------------------------------------------
+
+fputs
+
+ SYNOPSIS
+ Write a string to an open stream
+
+ USAGE
+ Integer_Type fputs (String_Type s, File_Type fp);
+
+ DESCRIPTION
+ The `fputs' function writes the string `s' to the open file
+ pointer `fp'. It returns -1 upon failure and sets `errno',
+ otherwise it returns the length of the string.
+
+ EXAMPLE
+ The following function opens a file in append mode and uses the
+ `fputs' function to write to it.
+
+ define append_string_to_file (str, file)
+ {
+ variable fp;
+ fp = fopen (file, "a");
+ if (fp == NULL) verror ("Unable to open %s", file);
+ if ((-1 == fputs (s, fp))
+ or (-1 == fclose (fp)))
+ verror ("Error writing to %s", file);
+ }
+
+
+ NOTES
+ One must not disregard the return value from the `fputs'
+ function, as many C programmers do. Doing so may lead to a stack
+ overflow error.
+
+ To write an object that contains embedded null characters, use the
+ `fwrite' function.
+
+ SEE ALSO
+ fclose, fopen, fgets, fwrite
+--------------------------------------------------------------
+
+fread
+
+ SYNOPSIS
+ Read binary data from a file
+
+ USAGE
+ UInt_Type fread (Ref_Type b, DataType_Type t, UInt_Type n, File_Type fp)
+
+ DESCRIPTION
+ The `fread' function may be used to read `n' objects of type
+ `t' from an open file pointer `fp'. Upon success, it
+ returns the number of objects read from the file and places the
+ objects in the variable specified by `b'. Upon error or end of
+ file, it returns `-1'. If more than one object is read from the
+ file, those objects will be placed in an array of the appropriate
+ size. The exception to this is when reading `Char_Type' or
+ `UChar_Type' objects from a file, in which case the data will be
+ returned as an `n' character BString_Type binary string, but
+ only if `n'>1.
+
+ EXAMPLE
+ The following example illustrates how to read 50 bytes from a file:
+
+ define read_50_bytes_from_file (file)
+ {
+ variable fp, n, buf;
+
+ fp = fopen (file, "rb");
+ if (fp == NULL) error ("Open failed");
+ n = fread (&buf, Char_Type, 50, fp);
+ if (n == -1)
+ error ("fread failed");
+ () = fclose (fp);
+ return buf;
+ }
+
+
+ NOTES
+ Use the `pack' and `unpack' functions to read data with a
+ specific byte-ordering.
+
+ SEE ALSO
+ fwrite, fgets, fopen, pack, unpack
+--------------------------------------------------------------
+
+fseek
+
+ SYNOPSIS
+ Reposition a stream
+
+ USAGE
+ Integer_Type fseek (File_Type fp, Integer_Type ofs, Integer_Type whence
+
+ DESCRIPTION
+ The `fseek' function may be used to reposition the file position
+ pointer associated with the open file stream `fp'. Specifically,
+ it moves the pointer `ofs' bytes relative to the position
+ indicated by `whence'. If whence is set to one of the symbolic
+ constants `SEEK_SET', `SEEK_CUR', or `SEEK_END', the
+ offset is relative to the start of the file, the current position
+ indicator, or end-of-file, respectively.
+
+ The function return zero upon success, or -1 upon failure and sets
+ `errno' accordingly.
+
+ EXAMPLE
+ define rewind (fp)
+ {
+ if (0 == fseek (fp, 0, SEEK_SET)) return;
+ vmessage ("rewind failed, reason: %s", errno_string (errno));
+ }
+
+ NOTES
+ The current implementation uses an integer to specify the offset.
+ One some systems, a long integer may be required making this
+ function fail for very large files, i.e., files that are longer than
+ the maximum value of an integer.
+
+ SEE ALSO
+ ftell, fopen
+--------------------------------------------------------------
+
+ftell
+
+ SYNOPSIS
+ Obtain the current position in an open stream
+
+ USAGE
+ Integer_Type ftell (File_Type fp)
+
+ DESCRIPTION
+ The ftell function may be used to obtain the current position in the
+ stream associated with the open file pointer `fp'. It returns
+ the position of the pointer measured in bytes from the beginning of
+ the file. Upon error, it returns `-1' and sets `errno'.
+
+ SEE ALSO
+ fseek, fopen
+--------------------------------------------------------------
+
+fwrite
+
+ SYNOPSIS
+ Write binary data to a file
+
+ USAGE
+ UInt_Type fwrite (b, File_Type fp)
+
+ DESCRIPTION
+ The `fwrite' may be used to write the object represented by
+ `b' to an open file. If `b' is a string or an array, the
+ function will attempt to write all elements of the object to the
+ file. It returns the number of objects successfully written,
+ otherwise it returns -1 upon error and sets `errno'
+ accordingly.
+
+ EXAMPLE
+ The following example illustrates how to write an integer array to a
+ file. In this example, `fp' is an open file descriptor:
+
+ variable a = [1:50]; % 50 element integer array
+ if (50 != fwrite (a, fp))
+ error ("fwrite failed");
+
+ Here is how to write the array one element at a time:
+
+ variable a = [1:50];
+ foreach (a)
+ {
+ variable ai = ();
+ if (1 != fwrite(ai, fp))
+ error ("fwrite failed");
+ }
+
+
+ NOTES
+ Not all data types may support the `fwrite' operation. However,
+ it is supported by all vector, scalar, and string objects.
+
+ SEE ALSO
+ fread, fputs, fopen, pack, unpack
+--------------------------------------------------------------
+
+pclose
+
+ SYNOPSIS
+ Close an object opened with popen
+
+ USAGE
+ Integer_Type pclose (File_Type fp)
+
+ DESCRIPTION
+ The `pclose' function waits for the process associated with
+ `fp' to exit and the returns the exit status of the command.
+
+ SEE ALSO
+ pclose, fclose
+--------------------------------------------------------------
+
+popen
+
+ SYNOPSIS
+ Open a process
+
+ USAGE
+ File_Type popen (String_Type cmd, String_Type mode)
+
+ DESCRIPTION
+ The `popen' function executes a process specified by `cmd'
+ and opens a unidirectional pipe to the newly created process. The
+ `mode' indicates whether or not the pipe is open for reading
+ or writing. Specifically, if `mode' is `"r"', then the
+ pipe is opened for reading, or if `mode' is `"w"', then the
+ pipe will be open for writing.
+
+ Upon success, a `File_Type' pointer will be returned, otherwise
+ the function failed and `NULL' will be returned.
+
+ NOTES
+ This function is not available on all systems.
+
+ SEE ALSO
+ pclose, fopen
+--------------------------------------------------------------
+
+printf
+
+ SYNOPSIS
+ Create and write a formatted string to stdout
+
+ USAGE
+ Int_Type printf (String_Type fmt, ...)
+
+ DESCRIPTION
+ `fprintf' formats the objects specified by the variable argument
+ list according to the format `fmt' and write the result to
+ `stdout'. This function is equivalent to `fprintf' used
+ with the `stdout' file pointer. See `fprintf' for more
+ information.
+
+ `printf' returns the number of characters written to the file,
+ or -1 upon error.
+
+ NOTES
+ Many C programmers do not check the return status of the
+ `printf' C library function. Make sure that if you do not care
+ about whether or not the function succeeds, then code it as in the
+ following example:
+
+ () = printf ("%s laid %d eggs\n", chicken_name, num_egg);
+
+
+ SEE ALSO
+ fputs, printf, fwrite, message
+--------------------------------------------------------------
+
+Sprintf
+
+ SYNOPSIS
+ Format objects into a string
+
+ USAGE
+ String_Type Sprintf (String_Type format, ..., Integer_Type n)
+
+ DESCRIPTION
+ `Sprintf' formats a string from `n' objects according to
+ `format'. Unlike `sprintf', the `Sprintf' function
+ requires the number of items to format.
+
+ The format string is a C library `sprintf' style format
+ descriptor. Briefly, the format string may consist of ordinary
+ characters (not including the `%' character), which are copied
+ into the output string as-is, and a conversion specification
+ introduced by the `%' character. The `%' character must be
+ followed by at least one other character to specify the conversion:
+
+ s value is a string
+ f value is a floating point number
+ e print float in exponential form, e.g., 2.345e08
+ g print float as e or g, depending upon its value
+ c value is an ascii character
+ % print the percent character
+ d print a signed decimal integer
+ u print an unsigned decimal integer
+ o print an integer as octal
+ X print an integer as hexadecimal
+ S convert value to a string and format as string
+
+ Note that `%S' is a S-Lang extension which will cause the value
+ to be formatted as string. In fact, `sprintf("%S",x)' is
+ equivalent to `sprintf("%s",string(x))'.
+
+ s = Sprintf("%f is greater than %f but %s is better than %s\n",
+ PI, E, "Cake" "Pie", 4);
+
+ The final argument to `Sprintf' is the number of items to format; in
+ this case, there are 4 items.
+
+ SEE ALSO
+ sprintf, string, sscanf
+--------------------------------------------------------------
+
+create_delimited_string
+
+ SYNOPSIS
+ Concatenate strings using a delimiter
+
+ USAGE
+ String_Type create_delimited_string (delim, s_1, s_2, ..., s_n, n)
+
+ String_Type delim, s_1, ..., s_n
+ Integer_Type n
+
+
+ DESCRIPTION
+ `create_delimited_string' performs a concatenation operation on
+ the `n' strings `s_1', ...,`s_n', using the string
+ `delim' as a delimiter. The resulting string is equivalent to
+ one obtained via
+
+ s_1 + delim + s_2 + delim + ... + s_n
+
+
+ EXAMPLE
+ One use for this function is to construct path names, e.g.,
+
+ create_delimited_string ("/", "user", "local", "bin", 3);
+
+ will produce `"usr/local/bin"'.
+
+ NOTES
+ The expression `strcat(a,b)' is equivalent to
+ `create_delimited_string("", a, b, 2)'.
+
+ SEE ALSO
+ strjoin, is_list_element, extract_element, strchop, strcat
+--------------------------------------------------------------
+
+extract_element
+
+ SYNOPSIS
+ Extract the nth element of a string with delimiters
+
+ USAGE
+ String_Type extract_element (String_Type list, Integer_Type nth, Integer_Type delim);
+
+ DESCRIPTION
+ The `extract_element' function may be used to extract the
+ `nth' element of the `delim' delimited list of strings
+ `list'. The function will return the `nth' element of the
+ list, unless `nth' specifies more elements than the list
+ contains, in which case `NULL' will be returned.
+ Elements in the list are numbered from `0'.
+
+ EXAMPLE
+ The expression
+
+ extract_element ("element 0, element 1, element 2", 1, ',')
+
+ returns the string `" element 1"', whereas
+
+ extract_element ("element 0, element 1, element 2", 1, ' ')
+
+ returns `"0,"'.
+
+ The following function may be used to compute the number of elements
+ in the list:
+
+ define num_elements (list, delim)
+ {
+ variable nth = 0;
+ while (NULL != extract_element (list, nth, delim))
+ nth++;
+ return nth;
+ }
+
+
+ Alternatively, the `strchop' function may be more useful. In
+ fact, `extract_element' may be expressed in terms of the
+ function `strchop' as
+
+ define extract_element (list, nth, delim)
+ {
+ list = strchop(list, delim, 0);
+ if (nth >= length (list))
+ return NULL;
+ else
+ return list[nth];
+ }
+
+ and the `num_elements' function used above may be recoded more
+ simply as:
+
+ define num_elements (list, delim)
+ {
+ return length (strchop (length, delim, 0));
+ }
+
+
+ SEE ALSO
+ is_list_element, is_substr, strtok, strchop, create_delimited_string
+--------------------------------------------------------------
+
+is_list_element
+
+ SYNOPSIS
+ Test whether a delimited string contains a specific element
+
+ USAGE
+ Integer_Type is_list_element (String_Type list, String_Type elem, Integer_Type delim)
+
+ DESCRIPTION
+ The `is_list_element' function may be used to determine whether
+ or not a delimited list of strings, `list', contains the element
+ `elem'. If `elem' is not an element of `list', the function
+ will return zero, otherwise, it returns 1 plus the matching element
+ number.
+
+ EXAMPLE
+ The expression
+
+ is_list_element ("element 0, element 1, element 2", "0,", ' ');
+
+ returns `2' since `"0,"' is element number one of the list
+ (numbered from zero).
+
+ SEE ALSO
+ extract_element, is_substr, create_delimited_string
+--------------------------------------------------------------
+
+is_substr
+
+ SYNOPSIS
+ Test for a specified substring within a string.
+
+ USAGE
+ Integer_Type is_substr (String_Type a, String_Type b)
+
+ DESCRIPTION
+ This function may be used to determine if `a' contains the
+ string `b'. If it does not, the function returns 0; otherwise it
+ returns the position of the first occurance of `b' in `a'.
+
+ NOTES
+ It is important to remember that the first character of a string
+ corresponds to a position value of `1'.
+
+ SEE ALSO
+ substr, string_match, strreplace
+--------------------------------------------------------------
+
+make_printable_string
+
+ SYNOPSIS
+ Format a string suitable for parsing
+
+ USAGE
+ String_Type make_printable_string(String_Type str)
+
+ DESCRIPTION
+ This function formats a string in such a way that it may be used as
+ an argument to the `eval' function. The resulting string is
+ identical to `str' except that it is enclosed in double quotes and the
+ backslash, newline, and double quote characters are expanded.
+
+ SEE ALSO
+ eval, str_quote_string
+--------------------------------------------------------------
+
+sprintf
+
+ SYNOPSIS
+ Format objects into a string
+
+ USAGE
+ String sprintf (String format, ...);
+
+ DESCRIPTION
+ This function performs a similar task as the C function with the same
+ name. It differs from the S-Lang function `Sprintf' in that it
+ does not require the number of items to format.
+ See the documentation for `Sprintf' for more information.
+
+ SEE ALSO
+ Sprintf, string, sscanf, vmessage
+--------------------------------------------------------------
+
+sscanf
+
+ SYNOPSIS
+ Parse a formatted string
+
+ USAGE
+ Int_Type sscanf (s, fmt, r1, ... rN)
+
+ String_Type s, fmt;
+ Ref_Type r1, ..., rN
+
+
+ DESCRIPTION
+ The `sscanf' function parses the string `s' according to the
+ format `fmt' and sets the variables whose references are given by
+ `r1', ..., `rN'. The function returns the number of
+ references assigned, or `-1' upon error.
+
+ The format string `fmt' consists of ordinary characters and
+ conversion specifiers. A conversion specifier begins with the
+ special character `%' and is described more fully below. A white
+ space character in the format string matches any amount of whitespace
+ in the input string. Parsing of the format string stops whenever a
+ match fails.
+
+ The `%' is used to denote a conversion specifier whose general
+ form is given by `%[*][width][type]format' where the brackets
+ indicate optional items. If `*' is present, then the conversion
+ will be performed by no assignment to a reference will be made. The
+ `width' specifier specifies the maximum field width to use for
+ the conversion. The `type' modifier is used to indicate size of
+ the object, e.g., a short integer, as follows.
+
+ If _type_ is given as the character `h', then if the format
+ conversion is for an integer (`dioux'), the object assigned will
+ be a short integer. If _type_ is `l', then the conversion
+ will be to a long integer for integer conversions, or to a double
+ precession floating point number for floating point conversions.
+
+ The format specifier is a character that specifies the conversion:
+
+ % Matches a literal percent character. No assigment is
+ performed.
+ d Matches a signed decimal integer.
+ D Matches a long decimal integer (equiv to `ld')
+ u Matches an unsigned decimal integer
+ U Matches an unsigned long decimal integer (equiv to `lu')
+ i Matches either a hexidecimal integer, decimal integer, or
+ octal integer.
+ I Equivalent to `li'.
+ x Matches a hexidecimal integer.
+ X Matches a long hexidecimal integer (same as `lx').
+ e,f,g Matches a decimal floating point number (Float_Type).
+ E,F,G Matches a double precision floating point number, same as `lf'.
+ s Matches a string of non-whitespace characters (String_Type).
+ c Matches one character. If width is given, width
+ characters are matched.
+ n Assigns the number of characters scanned so far.
+ [...] Matches zero or more characters from the set of characters
+ enclosed by the square brackets. If '^' is given as the
+ first character, then the complement set is matched.
+
+
+ EXAMPLE
+ Suppose that `s' is `"Coffee: (3,4,12.4)"'. Then
+
+ n = sscanf (s, "%[a-zA-Z]: (%d,%d,%lf)", &item, &x, &y, &z);
+
+ will set `n' to 4, `item' to `"Coffee"', `x' to 3,
+ `y' to 4, and `z' to the double precision number
+ `12.4'. However,
+
+ n = sscanf (s, "%s: (%d,%d,%lf)", &item, &x, &y, &z);
+
+ will set `n' to 1, `item' to `"Coffee:"' and the
+ remaining variables will not be assigned.
+
+ SEE ALSO
+ sprintf, unpack, string, atof, int, integer, string_match
+--------------------------------------------------------------
+
+str_delete_chars
+
+ SYNOPSIS
+ Delete characters from a string
+
+ USAGE
+ String_Type str_delete_chars (String_Type str, String_Type del_set
+
+ DESCRIPTION
+ This function may be used to delete the set of characters specified
+ by `del_set' from the string `str'. The result is returned.
+
+ EXAMPLE
+
+ str = str_delete_chars (str, "^A-Za-z");
+
+ will remove all characters except `A-Z' and `a-z' from
+ `str'.
+--------------------------------------------------------------
+
+str_quote_string
+
+ SYNOPSIS
+ Escape characters in a string.
+
+ USAGE
+ String_Type str_quote_string(String_Type str, String_Type qlis, Integer_Type quote)
+
+ DESCRIPTION
+ The `str_quote_string' returns a string identical to `str'
+ except that all characters in the set specified by the string
+ `qlis' are escaped with the `quote' character, including the
+ quote character itself. This function is useful for making a
+ string that can be used in a regular expression.
+
+ EXAMPLE
+ Execution of the statements
+
+ node = "Is it [the coat] really worth $100?";
+ tag = str_quote_string (node, "\\^$[]*.+?", '\\');
+
+ will result in `tag' having the value:
+
+ Is it \[the coat\] really worth \$100\?
+
+
+ SEE ALSO
+ str_uncomment_string, make_printable_string
+--------------------------------------------------------------
+
+str_replace
+
+ SYNOPSIS
+ Replace a substring of a string
+
+ USAGE
+ Integer_Type str_replace (String_Type a, String_Type b, String_Type c)
+
+ DESCRIPTION
+ The `str_replace' function replaces the first occurance of `b' in
+ `a' with `c' and returns an integer that indicates whether a
+ replacement was made or not. If `b' does not occur in `a', zero is
+ returned. However, if `b' occurs in `a', a non-zero integer is
+ returned as well as the new string resulting from the replacement.
+
+ NOTES
+ This function has been superceded by `strreplace'.
+
+ SEE ALSO
+ strreplace
+--------------------------------------------------------------
+
+str_uncomment_string
+
+ SYNOPSIS
+ Remove comments from a string
+
+ USAGE
+ String_Type str_uncomment_string(String_Type s, String_Type beg, String_Type end)
+
+ DESCRIPTION
+ This function may be used to remove comments from a string `s'.
+ The parameters, `beg' and `end', are strings of equal length
+ whose corresponding characters specify the begin and end comment
+ characters, respectively. It returns the uncommented string.
+
+ EXAMPLE
+ The expression
+
+ str_uncomment_string ("Hello (testing) 'example' World", "'(", "')")
+
+ returns the string `"Hello World"'.
+
+ NOTES
+ This routine does not handle multicharacter comment delimiters and it
+ assumes that comments are not nested.
+
+ SEE ALSO
+ str_quote_string
+--------------------------------------------------------------
+
+strcat
+
+ SYNOPSIS
+ Concatenate strings
+
+ USAGE
+ String_Type strcat (String_Type a_1, ..., String_Type a_N)
+
+ DESCRIPTION
+ The `strcat' function concatenates its N `String_Type'
+ arguments `a_1', ... `a_N' together and returns the result.
+
+ EXAMPLE
+
+ strcat ("Hello", " ", "World");
+
+ produces the string `"Hello World"'.
+
+ NOTES
+ This function is equivalent to the binary operation `a_1+...+a_N'.
+ However, `strcat' is much faster making it the preferred method
+ to concatenate string.
+
+ SEE ALSO
+ sprintf, create_delimited_string
+--------------------------------------------------------------
+
+strchop
+
+ SYNOPSIS
+ Chop or split a string into substrings.
+
+ USAGE
+ String_Type[] strchop (String_Type str, Integer_Type delim, Integer_Type quote)
+
+ DESCRIPTION
+ The `strchop' function may be used to split-up a string
+ `str' that consists of substrings delimited by the character
+ specified by `delim'. If the integer `quote' is non-zero,
+ it will be taken as a quote character for the delimiter. The
+ function returns the substrings as an array.
+
+ EXAMPLE
+ The following function illustrates how to sort a comma separated
+ list of strings:
+
+ define sort_string_list (a)
+ {
+ variable i, b, c;
+ b = strchop (a, ',', 0);
+
+ i = array_sort (b, &strcmp);
+ b = b[i]; % rearrange
+
+ % Convert array back into comma separated form
+ return strjoin (b, ",");
+ }
+
+
+ NOTES
+ The semantics of this `strchop' and `strchopr' have been
+ changed since version 1.2.x of the interpreter. Old versions of
+ these functions returned the values on the stack, which meant that
+ one could not chop up arbitrarily long strings that consist of
+ many substrings.
+
+ The function `strchopr' should be used if it is desired to have
+ the string chopped-up in the reverse order.
+
+ SEE ALSO
+ strchopr, extract_element, strjoin, strtok
+--------------------------------------------------------------
+
+strchopr
+
+ SYNOPSIS
+ Chop or split a string into substrings.
+
+ USAGE
+ String_Type[] strchopr (String_Type str, String_Type delim, String_Type quote)
+
+ DESCRIPTION
+ This routine performs exactly the same function as `strchop' except
+ that it returns the substrings in the reverse order. See the
+ documentation for `strchop' for more information.
+
+ SEE ALSO
+ strchop, extract_element, strtok, strjoin
+--------------------------------------------------------------
+
+strcmp
+
+ SYNOPSIS
+ Compare two strings
+
+ USAGE
+ Interpret strcmp (String_Type a, String_Type b)
+
+ DESCRIPTION
+ The `strcmp' function may be used to perform a case-sensitive
+ string comparison, in the lexicongraphic sense, on strings `a' and
+ `b'. It returns 0 if the strings are identical, a negative integer
+ if `a' is less than `b', or a positive integer if `a' is greater
+ than `b'.
+
+ EXAMPLE
+ The `strup' function may be used to perform a case-insensitive
+ string comparison:
+
+ define case_insensitive_strcmp (a, b)
+ {
+ return strcmp (strup(a), strup(b));
+ }
+
+
+ NOTES
+ One may also use one of the binary comparison operators, e.g.,
+ `a > b'.
+
+ SEE ALSO
+ strup, strncmp
+--------------------------------------------------------------
+
+strcompress
+
+ SYNOPSIS
+ Remove excess whitespace characters from a string
+
+ USAGE
+ String_Type strcompress (String_Type s, String_Type white)
+
+ DESCRIPTION
+ The `strcompress' function compresses the string `s' by
+ replacing a sequence of one or more characters from the set
+ `white' by the first character of `white'. In addition, it
+ also removes all leading and trailing characters from `s' that
+ are part of `white'.
+
+ EXAMPLE
+ The expression
+
+ strcompress (",;apple,,cherry;,banana", ",;");
+
+ returns the string `"apple,cherry,banana"'.
+
+ SEE ALSO
+ strtrim, strtrans
+--------------------------------------------------------------
+
+string_match
+
+ SYNOPSIS
+ Match a string against a regular expression
+
+ USAGE
+ Integer_Type string_match(String_Type str, String_Type pat, Integer_Type pos)
+
+ DESCRIPTION
+ The `string_match' function returns zero if `str' does not
+ match regular expression specified by `pat'. This function
+ performs the match starting at position `pos' (numbered from 1) in
+ `str'. This function returns the position of the start of the
+ match. To find the exact substring actually matched, use
+ `string_match_nth'.
+
+ SEE ALSO
+ string_match_nth, strcmp, strncmp
+--------------------------------------------------------------
+
+string_match_nth
+
+ SYNOPSIS
+ Get the result of the last call to string_match
+
+ USAGE
+ (Integer_Type, Integer_Type) = string_match_nth(Integer_Type nth)
+
+ DESCRIPTION
+ The `string_match_nth' function returns two integers describing
+ the result of the last call to `string_match'. It returns both
+ the offset into the string and the length of characters matches by
+ the `nth' submatch.
+
+ By convention, `nth' equal to zero means the entire match.
+ Otherwise, `nth' must be an integer with a value 1 through 9,
+ and refers to the set of characters matched by the `nth' regular
+ expression enclosed by the pairs `\(, \)'.
+
+ EXAMPLE
+ Consider:
+
+ variable matched, pos, len;
+ matched = string_match("hello world", "\\([a-z]+\\) \\([a-z]+\\)", 1);
+ if (matched) (pos, len) = string_match_nth(2);
+
+ This will set `matched' to 1 since a match will be found at the
+ first position, `pos' to 6 since `w' is offset 6 characters
+ from the beginning of the string, and `len' to 5 since
+ `"world"' is 5 characters long.
+
+ NOTES
+ The position offset is _not_ affected by the value of the offset
+ parameter to the `string_match' function. For example, if the
+ value of the last parameter to the `string_match' function had
+ been 3, `pos' would still have been set to 6.
+
+ Note also that `string_match_nth' returns the _offset_ from
+ the beginning of the string and not the position of the match.
+
+ SEE ALSO
+ string_match
+--------------------------------------------------------------
+
+strjoin
+
+ SYNOPSIS
+ Concatenate elements of a string array
+
+ USAGE
+ String_Type strjoin (Array_Type a, String_Type delim)
+
+ DESCRIPTION
+ The `strjoin' function operates on an array of strings by joining
+ successive elements together separated with a delimiter `delim'.
+ If `delim' is the empty string `""', then the result will
+ simply be the concatenation of the elements.
+
+ EXAMPLE
+ Suppose that
+
+ days = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
+
+ Then `strjoin (days,"+")' will produce
+ `"Sun+Mon+Tue+Wed+Thu+Fri+Sat+Sun"'. Similarly,
+ `strjoin (["","",""], "X")' will produce `"XX"'.
+
+ SEE ALSO
+ create_delimited_string, strchop, strcat
+--------------------------------------------------------------
+
+strlen
+
+ SYNOPSIS
+ Compute the length of a string
+
+ USAGE
+ Integer_Type strlen (String_Type a)
+
+ DESCRIPTION
+ The `strlen' function may be used to compute the length of a string.
+
+ EXAMPLE
+ After execution of
+
+ variable len = strlen ("hello");
+
+ `len' will have a value of `5'.
+
+ SEE ALSO
+ bstrlen, length, substr
+--------------------------------------------------------------
+
+strlow
+
+ SYNOPSIS
+ Convert a string to lowercase
+
+ USAGE
+ String_Type strlow (String_Type s)
+
+ DESCRIPTION
+ The `strlow' function takes a string `s' and returns another
+ string identical to `s' except that all upper case characters
+ that comprise `s' will be converted to lower case.
+
+ EXAMPLE
+ The function
+
+ define Strcmp (a, b)
+ {
+ return strcmp (strlow (a), strlow (b));
+ }
+
+ performs a case-insensitive comparison operation of two strings by
+ converting them to lower case first.
+
+ SEE ALSO
+ strup, tolower, strcmp, strtrim, define_case
+--------------------------------------------------------------
+
+strncmp
+
+ SYNOPSIS
+ Compare the first few characters of two strings
+
+ USAGE
+ Integer_Type strncmp (String_Type a, String_Type b, Integer_Type n)
+
+ DESCRIPTION
+ This function behaves like `strcmp' except that it compares only the
+ first `n' characters in the strings `a' and `b'. See
+ the documentation for `strcmp' for information about the return
+ value.
+
+ EXAMPLE
+ The expression
+
+ strcmp ("apple", "appliance", 3);
+
+ will return zero since the first three characters match.
+
+ SEE ALSO
+ strcmp, strlen
+--------------------------------------------------------------
+
+strreplace
+
+ SYNOPSIS
+ Replace one or more substrings
+
+ USAGE
+ (new, n) = strreplace (a, b, c, max_n)
+
+ String_Type a, b, c, rep;
+ Int_Type n, max_n;
+
+
+ DESCRIPTION
+ The `strreplace' function may be used to replace one or more
+ occurances of `b' in `a' with `c'. If the integer
+ `max_n' is positive, then the first `max_n' occurances of
+ `b' in `a' will be replaced. Otherwise, if `max_n' is
+ negative, then the last `abs(max_n)' occurances will be replaced.
+
+ The function returns the resulting string and an integer indicating
+ how many replacements were made.
+
+ EXAMPLE
+ The following function illustrates how `strreplace' may be used
+ to remove all occurances of a specified substring
+
+ define delete_substrings (a, b)
+ {
+ (a, ) = strreplace (a, b, "", strlen (a));
+ return a;
+ }
+
+
+ SEE ALSO
+ is_substr, strsub, strtrim, strtrans, str_delete_chars
+--------------------------------------------------------------
+
+strsub
+
+ SYNOPSIS
+ Replace a character with another in a string.
+
+ USAGE
+ String_Type strsub (String_Type s, Integer_Type pos, Integer_Type ch)
+
+ DESCRIPTION
+ The `strsub' character may be used to substitute the character
+ `ch' for the character at position `pos' of the string
+ `s'. The resulting string is returned.
+
+ EXAMPLE
+
+ define replace_spaces_with_comma (s)
+ {
+ variable n;
+ while (n = is_substr (s, " "), n) s = strsub (s, n, ',');
+ return s;
+ }
+
+ For uses such as this, the `strtrans' function is a better choice.
+
+ NOTES
+ The first character in the string `s' is specified by `pos'
+ equal to 1.
+
+ SEE ALSO
+ is_substr, strreplace, strlen
+--------------------------------------------------------------
+
+strtok
+
+ SYNOPSIS
+ Extract tokens from a string
+
+ USAGE
+ String_Type[] strtok (String_Type str [,String_Type white])
+
+ DESCRIPTION
+ `strtok' breaks the string `str' into a series of tokens and
+ returns them as an array of strings. If the second parameter
+ `white' is present, then it specifies the set of characters that
+ are to be regarded as whitespace when extracting the tokens, and may
+ consist of the whitespace characters or a range of such characters.
+ If the first character of `white' is `'^'', then the
+ whitespace characters consist of all characters except those in
+ `white'. For example, if `white' is `" \t\n,;."',
+ then those characters specifiy the whitespace characters. However,
+ if `white' is given by `"^a-zA-Z0-9_"', then any character
+ is a whitespace character except those in the ranges `a-z',
+ `A-Z', `0-9', and the underscore character.
+
+ If the second parameter is not present, then it defaults to
+ `" \t\r\n\f"'.
+
+ EXAMPLE
+ The following example may be used to count the words in a text file:
+
+ define count_words (file)
+ {
+ variable fp, line, count;
+
+ fp = fopen (file, "r");
+ if (fp == NULL) return -1;
+
+ count = 0;
+ while (-1 != fgets (&line, fp))
+ {
+ line = strtok (line, "^a-zA-Z");
+ count += length (line);
+ }
+ () = fclose (fp);
+ return count;
+ }
+
+
+ SEE ALSO
+ strchop, strcompress, extract_element, strjoin
+--------------------------------------------------------------
+
+strtrans
+
+ SYNOPSIS
+ Replace characters in a string
+
+ USAGE
+ String_Type strtrans (str, old_set, new_set)
+
+ String_Type str, old_set, new_set;
+
+
+ DESCRIPTION
+ The `strtrans' function may be used to replace all the characters
+ from the set `old_set' with the corresponding characters from
+ `new_set' in the string `str'. If `new_set' is empty,
+ then the characters in `old_set' will be removed from `str'.
+ This function returns the result.
+
+ EXAMPLE
+
+ str = strtrans (str, "A-Z", "a-z"); % lower-case str
+ str = strtrans (str, "^0-9", " "); % Replace anything but 0-9 by space
+
+
+ SEE ALSO
+ strreplace, strtrim, strup, strlow
+--------------------------------------------------------------
+
+strtrim
+
+ SYNOPSIS
+ Remove whitespace from the ends of a string
+
+ USAGE
+ String_Type strtrim (String_Type s [,String_Type w])
+
+ DESCRIPTION
+ The `strtrim' function removes all leading and trailing whitespace
+ characters from the string `s' and returns the result. The
+ optional second parameter specifies the set of whitespace
+ characters. If the argument is not present, then the set defaults
+ to `" \t\r\n"'.
+
+ SEE ALSO
+ strtrim_beg, strtrim_end, strcompress
+--------------------------------------------------------------
+
+strtrim_beg
+
+ SYNOPSIS
+ Remove leading whitespace from a string
+
+ USAGE
+ String_Type strtrim_beg (String_Type s [,String_Type w])
+
+ DESCRIPTION
+ The `strtrim_beg' function removes all leading whitespace
+ characters from the string `s' and returns the result. The
+ optional second parameter specifies the set of whitespace
+ characters. If the argument is not present, then the set defaults
+ to `" \t\r\n"'.
+
+ SEE ALSO
+ strtrim, strtrim_end, strcompress
+--------------------------------------------------------------
+
+strtrim_end
+
+ SYNOPSIS
+ Remove trailing whitespace from a string
+
+ USAGE
+ String_Type strtrim_end (String_Type s [,String_Type w])
+
+ DESCRIPTION
+ The `strtrim_end' function removes all trailing whitespace
+ characters from the string `s' and returns the result. The
+ optional second parameter specifies the set of whitespace
+ characters. If the argument is not present, then the set defaults
+ to `" \t\r\n"'.
+
+ SEE ALSO
+ strtrim, strtrim_beg, strcompress
+--------------------------------------------------------------
+
+strup
+
+ SYNOPSIS
+ Convert a string to uppercase
+
+ USAGE
+ String_Type strup (String_Type s)
+
+ DESCRIPTION
+ The `strup' function takes a string `s' and returns another
+ string identical to `s' except that all lower case characters
+ that comprise `s' will be converted to upper case.
+
+ EXAMPLE
+ The function
+
+ define Strcmp (a, b)
+ {
+ return strcmp (strup (a), strup (b));
+ }
+
+ performs a case-insensitive comparison operation of two strings by
+ converting them to upper case first.
+
+ SEE ALSO
+ strlow, toupper, strcmp, strtrim, define_case, strtrans
+--------------------------------------------------------------
+
+substr
+
+ SYNOPSIS
+ Extract a substring from a string
+
+ USAGE
+ String_Type substr (String_Type s, Integer_Type n, Integer_Type len)
+
+ DESCRIPTION
+ The `substr' function returns a substring with length `len'
+ of the string `s' beginning at position `n'. If `len' is
+ `-1', the entire length of the string `s' will be used for
+ `len'. The first character of `s' is given by `n' equal
+ to 1.
+
+ EXAMPLE
+
+ substr ("To be or not to be", 7, 5);
+
+ returns `"or no"'
+
+ NOTES
+ In many cases it is more convenient to use array indexing rather
+ than the `substr' function. In fact, `substr(s,i+1,strlen(s))' is
+ equivalent to `s[[i:]]'.
+
+ SEE ALSO
+ is_substr, strlen
+--------------------------------------------------------------
+
+_push_struct_field_values
+
+ SYNOPSIS
+ Push the values of a structure's fields onto the stack
+
+ USAGE
+ Integer_Type num = _push_struct_field_values (Struct_Type s)
+
+ DESCRIPTION
+ The `_push_struct_field_values' function pushes the values of
+ all the fields of a structure onto the stack, returning the
+ number of items pushed. The fields are pushed such that the last
+ field of the structure is pushed first.
+
+ SEE ALSO
+ get_struct_field_names, get_struct_field
+--------------------------------------------------------------
+
+get_struct_field
+
+ SYNOPSIS
+ Get the value associated with a structure field
+
+ USAGE
+ x = get_struct_field (Struct_Type s, String field_name)
+
+ DESCRIPTION
+ The `get_struct_field' function gets the value of the field
+ whose name is specified by `field_name' of the structure `s'.
+
+ EXAMPLE
+ The following example illustrates how this function may be used to
+ to print the value of a structure.
+
+ define print_struct (s)
+ {
+ variable name;
+
+ foreach (get_struct_field_names (s))
+ {
+ name = ();
+ value = get_struct_field (s, name);
+ vmessage ("s.%s = %s\n", name, string(value));
+ }
+ }
+
+
+ SEE ALSO
+ set_struct_field, get_struct_field_names, array_info
+--------------------------------------------------------------
+
+get_struct_field_names
+
+ SYNOPSIS
+ Retrieve the field names associated with a structure
+
+ USAGE
+ String_Type[] = get_struct_field_names (Struct_Type s)
+
+ DESCRIPTION
+ The `get_struct_field_names' function returns an array of
+ strings whose elements specify the names of the fields of the
+ struct `s'.
+
+ EXAMPLE
+ The following example illustrates how the
+ `get_struct_field_names' function may be used to print the
+ value of a structure.
+
+ define print_struct (s)
+ {
+ variable name, value;
+
+ foreach (get_struct_field_names (s))
+ {
+ name = ();
+ value = get_struct_field (s, name);
+ vmessage ("s.%s = %s\n", name, string (value));
+ }
+ }
+
+
+ SEE ALSO
+ _push_struct_field_values, get_struct_field
+--------------------------------------------------------------
+
+is_struct_type
+
+ SYNOPSIS
+ Determine whether or not an object is a structure
+
+ USAGE
+ Integer_Type is_struct_type (X)
+
+ DESCRIPTION
+ The `is_struct_type' function returns 1 if the parameter
+ refers to a structure or a user-defined type. If the object is
+ neither, 0 will be returned.
+
+ SEE ALSO
+ typeof, _typeof
+--------------------------------------------------------------
+
+set_struct_field
+
+ SYNOPSIS
+ Set the value associated with a structure field
+
+ USAGE
+ set_struct_field (s, field_name, field_value)
+
+ Struct_Type s;
+ String_Type field_name;
+ Generic_Type field_value;
+
+
+ DESCRIPTION
+ The `set_struct_field' function sets the value of the field
+ whose name is specified by `field_name' of the structure
+ `s' to `field_value'.
+
+ SEE ALSO
+ get_struct_field, get_struct_field_names, set_struct_fields, array_info
+--------------------------------------------------------------
+
+set_struct_fields
+
+ SYNOPSIS
+ Set the fields of a structure
+
+ USAGE
+ set_struct_fields (Struct_Type s, ...)
+
+ DESCRIPTION
+ The `set_struct_fields' function may be used to set zero or more
+ fields of a structure. The fields are set in the order in which
+ they were created when the structure was defined.
+
+ EXAMPLE
+
+ variable s = struct { name, age, height };
+ set_struct_fields (s, "Bill", 13, 64);
+
+
+ SEE ALSO
+ set_struct_field, get_struct_field_names
+--------------------------------------------------------------
+
+_time
+
+ SYNOPSIS
+ Get the current time in seconds
+
+ USAGE
+ ULong_Type _time ()
+
+ DESCRIPTION
+ The `_time' function returns the number of elapsed seconds since
+ 00:00:00 GMT, January 1, 1970. The `ctime' function may be used
+ to convert this into a string representation.
+
+ SEE ALSO
+ ctime, time, localtime, gmtime
+--------------------------------------------------------------
+
+ctime
+
+ SYNOPSIS
+ Convert a calendar time to a string
+
+ USAGE
+ String_Type ctime(ULong_Type secs)
+
+ DESCRIPTION
+ This function returns a string representation of the time as given
+ by `secs' seconds since 1970.
+
+ SEE ALSO
+ time, _time, localtime, gmtime
+--------------------------------------------------------------
+
+gmtime
+
+ SYNOPSIS
+ Break down a time in seconds to GMT timezone
+
+ USAGE
+ Struct_Type gmtime (Long_Type secs)
+
+ DESCRIPTION
+ The `gmtime' function is exactly like `localtime' except
+ that the values in the structure it returns are with respect to GMT
+ instead of the local timezone. See the documentation for
+ `localtime' for more information.
+
+ NOTES
+ On systems that do not support the `gmtime' C library function,
+ this function is the same as `localtime'.
+
+ SEE ALSO
+ localtime, _time
+--------------------------------------------------------------
+
+localtime
+
+ SYNOPSIS
+ Break down a time in seconds to local timezone
+
+ USAGE
+ Struct_Type localtime (Long_Type secs)
+
+ DESCRIPTION
+ The `localtime' function takes a parameter `secs'
+ representing the number of seconds since 00:00:00, January 1 1970
+ UTC and returns a structure containing information about `secs'
+ in the local timezone. The structure contains the following
+ `Int_Type' fields:
+
+ `tm_sec' The number of seconds after the minute, normally
+ in the range 0 to 59, but can be up to 61 to allow for
+ leap seconds.
+
+ `tm_min' The number of minutes after the hour, in the
+ range 0 to 59.
+
+ `tm_hour' The number of hours past midnight, in the range
+ 0 to 23.
+
+ `tm_mday' The day of the month, in the range 1 to 31.
+
+ `tm_mon' The number of months since January, in the range
+ 0 to 11.
+
+ `tm_year' The number of years since 1900.
+
+ `tm_wday' The number of days since Sunday, in the range 0
+ to 6.
+
+ `tm_yday' The number of days since January 1, in the
+ range 0 to 365.
+
+ `tm_isdst' A flag that indicates whether daylight saving
+ time is in effect at the time described. The value is
+ positive if daylight saving time is in effect, zero if it
+ is not, and negative if the information is not available.
+
+ SEE ALSO
+ gmtime, _time, ctime
+--------------------------------------------------------------
+
+tic
+
+ SYNOPSIS
+ Start timing
+
+ USAGE
+ void tic ()
+
+ DESCRIPTION
+ The `tic' function restarts the internal clock used for timing
+ the execution of commands. To get the elapsed time of the clock,
+ use the `toc' function.
+
+ SEE ALSO
+ toc, times
+--------------------------------------------------------------
+
+time
+
+ SYNOPSIS
+ Return the current data and time as a string
+
+ USAGE
+ String_Type time ()
+
+ DESCRIPTION
+ This function returns the current time as a string of the form:
+
+ Sun Apr 21 13:34:17 1996
+
+
+ SEE ALSO
+ ctime, message, substr
+--------------------------------------------------------------
+
+times
+
+ SYNOPSIS
+ Get process times
+
+ USAGE
+ Struct_Type times ()
+
+ DESCRIPTION
+ The `times' function returns a structure containing the
+ following fields:
+
+ tms_utime (user time)
+ tms_stime (system time)
+ tms_cutime (user time of child processes)
+ tms_cstime (system time of child processes)
+
+
+ NOTES
+ Not all systems support this function.
+
+ SEE ALSO
+ tic, toc, _times
+--------------------------------------------------------------
+
+toc
+
+ SYNOPSIS
+ Get elapsed CPU time
+
+ USAGE
+ Double_Type toc ()
+
+ DESCRIPTION
+ The `toc' function returns the elapsed CPU time in seconds since
+ the last call to `tic'. The CPU time is the amount of time the
+ CPU spent running the code of the current process.
+
+ EXAMPLE
+ The `tic' and `toc' functions are ideal for timing the
+ execution of the interpreter:
+
+ variable a = "hello", b = "world", c, n = 100000, t;
+
+ tic (); loop (n) c = a + b; t = toc ();
+ vmessage ("a+b took %f seconds\n", t);
+ tic (); loop (n) c = strcat(a,b); t = toc ();
+ vmessage ("strcat took %f seconds\n", t);
+
+
+ NOTES
+ This function may not be available on all systems.
+
+ The implementation of this function is based upon the `times'
+ system call. The precision of the clock is system dependent.
+
+ SEE ALSO
+ tic, times, _time
+--------------------------------------------------------------
+
+_slang_guess_type
+
+ SYNOPSIS
+ Guess the data type that a string represents.
+
+ USAGE
+ DataType_Type _slang_guess_type (String_Type s)
+
+ DESCRIPTION
+ This function tries to determine whether its argument `s'
+ represents an integer (short, int, long), floating point (float,
+ double), or a complex number. If it appears to be none of these,
+ then a string is assumed. It returns one of the following values
+ depending on the format of the string `s':
+
+ Short_Type : short integer (e.g., "2h")
+ UShort_Type : unsigned short integer (e.g., "2hu")
+ Integer_Type : integer (e.g., "2")
+ UInteger_Type : unsigned integer (e.g., "2")
+ Long_Type : long integer (e.g., "2l")
+ ULong_Type : unsigned long integer (e.g., "2l")
+ Float_Type : float (e.g., "2.0f")
+ Double_Type : double (e.g., "2.0")
+ Complex_Type : imaginary (e.g., "2i")
+ String_Type : Anything else. (e.g., "2foo")
+
+ For example, `_slang_guess_type("1e2")' returns
+ `Double_Type' but `_slang_guess_type("e12")' returns
+ `String_Type'.
+
+ SEE ALSO
+ integer, string, double, atof
+--------------------------------------------------------------
+
+_typeof
+
+ SYNOPSIS
+ Get the data type of an object
+
+ USAGE
+ DataType_Type _typeof (x)
+
+ DESCRIPTION
+ This function is similar to the `typeof' function except in the
+ case of arrays. If the object `x' is an array, then the data
+ type of the array will be returned. otherwise `_typeof' returns
+ the data type of `x'.
+
+ EXAMPLE
+
+ if (Integer_Type == _typeof (x))
+ message ("x is an integer or an integer array");
+
+
+ SEE ALSO
+ typeof, array_info, _slang_guess_type, typecast
+--------------------------------------------------------------
+
+atof
+
+ SYNOPSIS
+ Convert a string to a double precision number
+
+ USAGE
+ Double_Type atof (String_Type s)
+
+ DESCRIPTION
+ This function converts a string `s' to a double precision value
+ and returns the result. It performs no error checking on the format
+ of the string. The function `_slang_guess_type' may be used to
+ check the syntax of the string.
+
+ EXAMPLE
+
+ define error_checked_atof (s)
+ {
+ switch (_slang_guess_type (s))
+ {
+ case Double_Type:
+ return atof (s);
+ }
+ {
+ case Integer_Type:
+ return double (integer (s));
+ }
+
+ verror ("%s is not a double", s);
+ }
+
+
+ SEE ALSO
+ typecast, double, _slang_guess_type
+--------------------------------------------------------------
+
+char
+
+ SYNOPSIS
+ Convert an ascii value into a string
+
+ USAGE
+ String_Type char (Integer_Type c)
+
+ DESCRIPTION
+ The `char' function converts an integer ascii value `c' to a string
+ of unit length such that the first character of the string is `c'.
+ For example, `char('a')' returns the string `"a"'.
+
+ SEE ALSO
+ integer, string, typedef
+--------------------------------------------------------------
+
+define_case
+
+ SYNOPSIS
+ Define upper-lower case conversion.
+
+ USAGE
+ define_case (Integer_Type ch_up, Integer_Type ch_low);
+
+ DESCRIPTION
+ This function defines an upper and lowercase relationship between two
+ characters specified by the arguments. This relationship is used by
+ routines which perform uppercase and lowercase conversions.
+ The first integer `ch_up' is the ascii value of the uppercase character
+ and the second parameter `ch_low' is the ascii value of its
+ lowercase counterpart.
+
+ SEE ALSO
+ strlow, strup
+--------------------------------------------------------------
+
+double
+
+ SYNOPSIS
+ Convert an object to double precision
+
+ USAGE
+ result = double (x)
+
+ DESCRIPTION
+ The `double' function typecasts an object `x' to double
+ precision. For example, if `x' is an array of integers, an
+ array of double types will be returned. If an object cannot be
+ converted to `Double_Type', a type-mismatch error will result.
+
+ NOTES
+ The `double' function is equivalent to the typecast operation
+
+ typecast (x, Double_Type)
+
+ To convert a string to a double precision number, use the `atof'
+ function.
+
+ SEE ALSO
+ typecast, atof, int
+--------------------------------------------------------------
+
+int
+
+ SYNOPSIS
+ Typecast an object to an integer
+
+ USAGE
+ int (s)
+
+ DESCRIPTION
+ This function performs a typecast of `s' from its data type to
+ an object of `Integer_Type'. If `s' is a string, it returns
+ returns the ascii value of the first character of the string
+ `s'. If `s' is `Double_Type', `int' truncates the
+ number to an integer and returns it.
+
+ EXAMPLE
+ `int' can be used to convert single character strings to
+ integers. As an example, the intrinsic function `isdigit' may
+ be defined as
+
+ define isdigit (s)
+ {
+ if ((int (s) >= '0') and (int (s) <= '9')) return 1;
+ return 0;
+ }
+
+
+ NOTES
+ This function is equalent to `typecast (s, Integer_Type)';
+
+ SEE ALSO
+ typecast, double, integer, char, isdigit
+--------------------------------------------------------------
+
+integer
+
+ SYNOPSIS
+ Convert a string to an integer
+
+ USAGE
+ Integer_Type integer (String_Type s)
+
+ DESCRIPTION
+ The `integer' function converts a string representation of an
+ integer back to an integer. If the string does not form a valid
+ integer, a type-mismatch error will be generated.
+
+ EXAMPLE
+ `integer ("1234")' returns the integer value `1234'.
+
+ NOTES
+ This function operates only on strings and is not the same as the
+ more general `typecast' operator.
+
+ SEE ALSO
+ typecast, _slang_guess_type, string, sprintf, char
+--------------------------------------------------------------
+
+isdigit
+
+ SYNOPSIS
+ Tests for a decimal digit character
+
+ USAGE
+ Integer_Type isdigit (String_Type s)
+
+ DESCRIPTION
+ This function returns a non-zero value if the first character in the
+ string `s' is a digit; otherwise, it returns zero.
+
+ EXAMPLE
+ A simple, user defined implementation of `isdigit' is
+
+ define isdigit (s)
+ {
+ return ((s[0] <= '9') and (s[0] >= '0'));
+ }
+
+ However, the intrinsic function `isdigit' executes many times faster
+ than the equivalent representation defined above.
+
+ NOTES
+ Unlike the C function with the same name, the S-Lang function takes
+ a string argument.
+
+ SEE ALSO
+ int, integer
+--------------------------------------------------------------
+
+string
+
+ SYNOPSIS
+ Convert an object to a string representation.
+
+ USAGE
+ Integer_Type string (obj)
+
+ DESCRIPTION
+ The `string' function may be used to convert an object
+ `obj' of any type to a string representation.
+ For example, `string(12.34)' returns `"12.34"'.
+
+ EXAMPLE
+
+ define print_anything (anything)
+ {
+ message (string (anything));
+ }
+
+
+ NOTES
+ This function is _not_ the same as typecasting to a `String_Type'
+ using the `typecast' function.
+
+ SEE ALSO
+ typecast, sprintf, integer, char
+--------------------------------------------------------------
+
+tolower
+
+ SYNOPSIS
+ Convert a character to lowercase.
+
+ USAGE
+ Integer_Type lower (Integer_Type ch)
+
+ DESCRIPTION
+ This function takes an integer `ch' and returns its lowercase
+ equivalent.
+
+ SEE ALSO
+ toupper, strup, strlow, int, char, define_case
+--------------------------------------------------------------
+
+toupper
+
+ SYNOPSIS
+ Convert a character to uppercase.
+
+ USAGE
+ Integer_Type toupper (Integer_Type ch)
+
+ DESCRIPTION
+ This function takes an integer `ch' and returns its uppercase
+ equivalent.
+
+ SEE ALSO
+ tolower, strup, strlow, int, char, define_case
+--------------------------------------------------------------
+
+typecast
+
+ SYNOPSIS
+ Convert an object from one data type to another.
+
+ USAGE
+ typecast (x, new_type)
+
+ DESCRIPTION
+ The `typecast' function performs a generic typecast operation on
+ `x' to convert it to `new_type'. If `x' represents an
+ array, the function will attempt to convert all elements of `x'
+ to `new_type'. Not all objects can be converted and a
+ type-mismatch error will result upon failure.
+
+ EXAMPLE
+
+ define to_complex (x)
+ {
+ return typecast (x, Complex_Type);
+ }
+
+ defines a function that converts its argument, `x' to a complex
+ number.
+
+ SEE ALSO
+ int, double, typeof
+--------------------------------------------------------------
+
+typeof
+
+ SYNOPSIS
+ Get the data type of an object.
+
+ USAGE
+ DataType_Type typeof (x)
+
+ DESCRIPTION
+ This function returns the data type of `x'.
+
+ EXAMPLE
+
+ if (Integer_Type == typeof (x)) message ("x is an integer");
+
+
+ SEE ALSO
+ _typeof, is_struct_type, array_info, _slang_guess_type, typecast
+--------------------------------------------------------------
+