aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/doc/text/cslang.txt
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/doc/text/cslang.txt')
-rw-r--r--libslang/doc/text/cslang.txt2989
1 files changed, 2989 insertions, 0 deletions
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
+
+
+