[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. Bigloo Common Library

3.1 Introduction  
3.2 regex  internationalized basic and extended regular expression matching
3.3 The GNU DBM interface  
3.4 MzScheme compatibility module  MzScheme compatibility procedures
3.5 Dynamic linking library  Dynamic link support
3.6 SRFI-1 List Library  
3.7 SRFI-13 String Library  
3.8 Miscellaneous stuff  assorted stuff
3.11 cgen - bigloo preprocessor  bigloo preprocessor
3.9 iconv - charset conversion procedures  charset conversion procedures
3.10 Time-related procedures  times and dates
3.12 Advanced afile utility  advanced afile utility
3.13 Command-line applications support  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 Introduction

The bigloo-common library is a set of miscellaneous types and procedures. Some other bigloo-lib's libraries rely on it. This library includes:

At the moment, the stuff was selected based only on my own practical needs in course of working on some Web-related projects. By this reason, the library is not (and probably never will be) completed.

Also, though a few Bigloo procedures are re-implemented in this library, in no case this library replaces the Bigloo runtime library.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 regex

This section describes the regex module, which provides an interface to C runtime regex functions.

The regex module is optional, i.e. you can disable its compilation by using --without-regexp flag for configure. Also note that configure script can detect that regexps are broken on your system and disable this feature.

To help you detect whether you have regexps while in interpreter, the 'regexp symbol is defined through the register-eval-srfi! construct, so you may test it with cond-expand. For example, the common library test script conditionally includes the regexp-test call:

 
(cond-expand (regexp (regexp-test))
	     (else (print "regexps are disabled by configure")))


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2.1 Regexp Matching

The procedures described here, are intended for end-user applications. They are compatible to those provided by MzScheme.

procedure: regexp rexp-or-string #!optional flags::regcomp-flags => regexp

If a regex object was passed as the rexp-or-string argument, just return it.

If a string was passed as the rexp-or-string argument, allocates a new regexp object and compiles rexp-or-string into regular expression object with regcomp, passing the optional flags arguments along. Signals an error if something went wrong during the compilation.

It is an error if the rexp-or-string was neither regexp nor string.

Simple regexp example:

 
(regexp "q") => #<foreign:REGEXP:21490>
(regexp "(") error--> "( ) or \( \) imbalance -- ("

Simple vs. case insensitive match example:

 
(define rexp(regexp "qwerty"))
(regexp-match rexp "QWERTY")
=> #f

(define rexp(regexp "qwerty" 'icase))
(regexp-match rexp "QWERTY")
=> (QWERTY)

Basic vs. Extended regexp match example:

 
(define rexp(regexp "a|b" 'basic))
(regexp-match rexp "a|b")
=> ("a|b")

(define rexp(regexp "a|b")) ;; 'extended flag set by default
(regexp-match rexp "a|b")
=> ("a")

Using of nosub flag example:

 
(define rexp(regexp "qwerty" 'nosub))
(regexp-match rexp "qwerty")
=> ()

procedure: regexp-match rexp-or-string str::bstring #!optional offset::int eflags::regexec-flags => #f or pair

Return #f if string str does not match pattern. Otherwise return the list object. Unless the nosub flag was given, the list has at least one element, the whole match substring found. The rest elements are partial sub-matches. The pattern argument must be either regexp or scheme string. In later case pattern is compiled into temporary regexp object, which is automatically released.

Example:

 
(regexp-match "q" "asdf")
=> #f
(regexp-match "q" "qwerty")
=> (q)
(regexp-match "([a-z]+)([0-9]+)" "qwerty1234")
=> (qwerty1234 qwerty 1234)

The optional argument offset allows to skip first offset characters from the beginning of matched string, for example:

 
(regexp-match "[a-z]+" "qwerty")  ;; offset=0
=> (qwerty)
(regexp-match "[a-z]+" "qwerty" 2)
=> (erty)

The optional eflag arguments may be any of the following symbols :

notbol
The match-beginning-of-line operator always fails to match (but see the compilation flag newline above). This flag may be used when different portions of a string are passed to regexp-match and the beginning of the string should not be interpreted as the beginning of the line.

noteol
The match-end-of-line operator always fails to match (but see the compilation flag newline above)

 
(define rexp(regexp "^qwerty"))
(regexp-match rexp "qwerty")  ;; BOL matches as usual
=> ("qwerty")

(regexp-match-positions rexp "qwerty" 0 'notbol)
=> #f                  ;; BOL match suppressed

procedure: regexp-match-positions pattern rexp-or-string str::bstring #!optional offset::int => #f or pair

Same as regexp-match, but returns the matched substrings position inside the source string instead of substrings itself, for example:

 
(regexp-match-positions "q" "asdf")
=> #f
(regexp-match-positions "q" "qwerty")
=> ((0 . 1))
(regexp-match-positions "([a-z]+)([0-9]+)" "qwerty1234")
=> ((0 . 10) (0 . 6) (6 . 10))

regexp-match-positions does not imply copying of strings, thus it is extremely useful when applyed to long strings.

procedure: regexp-replace* pattern src::bstring insert::bstring => bstring

Return copy of src string where all occurrences of pattern are replaces by insert string.

 
(regexp-replace* "[a-z]" "1a2b3c" " Letter ")
=> "1 Letter 2 Letter 3 Letter "

Note: no context replacements are currently implemented. For example:

 
(regexp-replace* "[a-z]" "1a2b3c" " Letter &")
=> "Letter &2 Letter &3 Letter &"

but not "1 Letter a2 Letter b3 Letter c", as one may expect.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2.2 C runtime API

Procedures described here are direct interfaces to corresponding C runtime calls. You woudn't want to use them in end-user applications.

procedure: regcomp preg::regexp rexp-or-string #!optional flags::regcomp-flags => regcomp-error

Compile pattern string into previously allocated preg regexp structure. Once compiled, the regexp object may be reused multiple time.

The optional flags arguments may be any of the following symbols in any sequence (see regcomp manual page) :

basic
Use POSIX Basic Regular Expression syntax when interpreting regex. If not set, POSIX Extended Regular Expression syntax is used. See manual page regex(7) for details.

icase
Do not differentiate case. Subsequent regexec searches using this pattern buffer will be case insensitive (2).

nosub
Support for substring addressing of matches is not required. The list resulted from successful match will be always empty. Use it if you only want to know whether the match was found.

newline
Match-any-character operators don't match a newline.

A non-matching list ([^...]) not containing a newline does not match a newline.

Match-beginning-of-line operator (^) matches the empty string immediately after a newline, regardless of whether the flags argument of regexp-match or regexp-match, contains notbol.

Match-end-of-line operator ($) matches the empty string immediately before a newline, regardless of whether the flags argument of regexp-match or regexp-match contains noteol.

procedure: regerror errorid::regcomp-error rexp::regexp => bstring

Given the error code, returned by regcomp or regexec, return the error description.

 
(regerror 'erange (regexp " "))
=> "invalid endpoint in range"

procedure: regfree rexp::regexp => #unspecified

Free the memory allocated to the rexp by the regcomp.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 The GNU DBM interface

As stated in GNU dbm documentation:

GNU dbm (gdbm)is a library of database functions that use extendible hashing and works similar to the standard UNIX dbm functions. These routines are provided to a programmer needing to create and manipulate a hashed database.

The basic use of gdbm is to store key/data pairs in a data file. Each key must be unique and each key is paired with only one data item. The keys can not be directly accessed in sorted order.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.1 Opening and closing the database

procedure: gdbm-open filename::string #!optional flags::pair-nil #!key block-size::int mode::int onerror::procedure => gdbm-file

The procedure gdbm-open opens or creates gdbm database file filename.

The parameters are:

filename
The name of the file to open.

#!optional flag::pair-nil
If flags includes the reader symbol only, the user wants to just read the database and any call to gdbm-store or gdbm-delete will fail. Many readers can access the database at the same time. If flags includes the writer symbol, the user wants both read and write access to the database and requires exclusive access. If flags includes the wrcreat, the user wants both read and write access to the database and if the database does not exist, create a new one. If flags includes the newdb, the user want a new database created, regardless of whether one existed, and wants read and write access to the new database. The following may also be added to the flags: the sync symbol, which causes all database operations to be synchronized to the disk, and the nolock symbol, which prevents the library from performing any locking on the database file.

#!key block-size
It is used during initialization to determine the size of various constructs. It is the size of a single transfer from disk to memory. This parameter is ignored if the file has been previously initialized. The minimum size is 512. If the value is omitted or less than 512, the file system blocksize is used, otherwise the value of block-size is used.

#!key mode
File mode (see chmod(2) and open(2) man pages) if the file is created).

#!key onerror
A procedure for gdbm to call if it detects a fatal error. The only parameter of this function is a string.

This feature is is not implemented yet.

The return value is the object needed by all other functions to access that gdbm file.

For example:
 
(let((conn(gdbm-open "test.db")))
  ...
  (gdbm-close conn))

procedure: gdbm-close gdbm::gdbm-file

The procedure gdbm-close closes the gdbm file and frees all memory associated with it. It also updates the reader/writer count on the file.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.2 Storing and fetching data

procedure: gdbm-store gdbm::gdbm-file key::bstring value::bstring #!optional replace?

The procedure gdbm-store inserts or replaces records in the database.

The key argument is the key data in a form of Bigloo string object. The value argument holds the data to be associated with the key.

If the replace? argument is not given, then if any data was already associated with the key, no action is performed, and the procedure returns #t.

If the replace? argument evaluates to scheme true value, the old data associated with the key, if any, is always replaced by the new one.

For example:
 
;; Create a new GDBM storage file named `test.db'
(define gdbm (gdbm-open "test.db" '(wrcreat)))

;; store the key "key" associated with the "value" string. The false
;; return value means no data was previously associated with the word
;; "key"
(gdbm-store gdbm "key" "value")
=> #f

;; Try to store a new value for same key, no replacement is
;; allowed. The true return value means no action was taken since data
;; is already associated with this key
(gdbm-store gdbm "key" "newvalue")
=> #t

;; This assures no replacement occured
(gdbm-fetch gdbm "key")
=> "value"

;; Replace the value in a database. Note the optional `replace?'
;; argument is now #t
(gdbm-store gdbm "key" "newvalue" #t)

;; Check the replacement was successfull
(gdbm-fetch gdbm "key")
=> "newvalue"
=>

procedure: gdbm-delete gdbm::gdbm-file key::bstring => bool

Delete the record associated with the key if any. Return #f if the record wasn't found, #t otherwise.

For example:
 
(gdbm-store gdbm "newkey" "newvalue")

(gdbm-delete gdbm "newkey")
=> #f

(gdbm-delete gdbm "newkey")
=> #t

procedure: gdbm-fetch gdbm::gdbm-file key::bstring

Look up the data associated with the key. Return the data string found or #f if the key wasn't found in a database.

procedure: gdbm-exists gdbm::gdbm-file key::bstring

Unlike the gdbm-fetch procedure, this procedure does not retrieve any data, and simply returns true of false, depending on whether the key exists, or not.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.3 Enumerating database entries

procedure: gdbm-firstkey gdbm::gdbm-file
procedure: gdbm-nextkey gdbm::gdbm-file key::bstring

Enumerate database records.

Example: print all database records.

 
(let loop ((key(gdbm-firstkey gdbm)))
  (when key
	(print key " -> "(gdbm-fetch gdbm key))
	(loop (gdbm-nextkey gdbm key))))


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.4 Miscellanea

procedure: gdbm-reorganize gdbm::gdbm-file

Try to shrink the database after multiple deletions were done. See GDBM documentation for details.

procedure: gdbm-sync gdbm::gdbm-file

The procedure gdbm-sync assures all data flushed to the disk. Instead you may use the sync flag when opening the database with gdbm-open.

procedure: gdbm-setopt gdbm::gdbm-file option::gdbm-setopt-flags value
conn option value

The procedure gdbm-setopt sets certain options on an already open database. The valid options are:

cachesize
Set the size of the internal bucket cache. This option may only be set once on each gdbm descriptor, and is set automatically to 100 upon the first access to the database.

fastmode
Set fast mode to either on or off. This allows fast mode to be toggled on an already open and active database.

syncmode
Turn on or off file system synchronization operations.

centfree
Set central free block pool to either on or off. The default is off, which is how previous versions of Gdbm handled free blocks. If set, this option causes all subsequent free blocks to be placed in the global pool, allowing (in theory) more file space to be reused more quickly.

coalesceblks
Set free block merging to either on or off. The default is off, which is how previous versions of Gdbm handled free blocks. If set, this option causes adjacent free blocks to be merged. This can become a CPU expensive process with time, though, especially if used in conjunction with centfree.

Example: force a database to use a cache of 10, after opening it with gdbm-open.

 
(gdbm-setopt gdbm 'cachesize 10)

procedure: gdbm-fdesc gdbm::gdbm-file => int

The procedure gdbm-fdesc returns the file descriptor of the database.

procedure: gdbm-version => string

The procedure gdbm-version returns the underlying GDBM library version description.

For example:
 
(gdbm-version)
=> This is GDBM version 1.8.0, as of May 19, 1999.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 MzScheme compatibility module

This section describes the mzcompat module, which provides a few procedures to facilitate reuse of code written for MzScheme.

The mzcompat module is optional, its compilation is disabled by default. To enable it, call configure with --with-compat switch.

To detect whether you have mzcompat module enabled when in interpreter, test 'mzscheme-compat symbol with cond-expand. For example:

 
(cond-expand (mzscheme-compat (mzscheme-test))
	     (else (print "MzScheme compatibility is disabled by configure")))

macro: case-lambda patterns

The analog of match-lambda construct. Differs from match-lambda in that the execution flow only depends on number of arguments, but not on their types.

Example:
 
(define print-args
  (case-lambda
   (()
    (print "no args was given"))
   ((a)
    (print "only one argument was given: " a))
   (args
    (print (length args) " arguments were given"))))

(print-args)
-| no args was given
(print-args 'one)
-| only one argument was given: ONE
(print-args 'one 'two 'three)
-| 3 arguments were given

inline procedure: load-relative-extension fname::bstring

Means nothing in bigloo-lib.

procedure: make-parameter value #!optional filter => procedure

Creates a closure, which being called without arguments returns the value value, being called with one argument arg, sets the variable value to arg. If filter procedure is provided, the new value is passed to that procedure, and the value returned by filter is stored in value variable.

Example:

 
(define my-value (make-parameter 0))
=> #<procedure:400edad0.-1>
(my-value)
=> 0
(my-value 1)
(my-value)
=> 1

The following procedure always converts its argument to string before remembering it:

 
(define my-string-value
  (make-parameter
   ""
   (lambda(o)
     (cond((string? o)
	   o)
	  ((number? o)
	   (number->string o))
	  (else(error "my-string-value" "invalid argument"o))))))

(my-string-value 1)
(pp(my-string-value))
-| #"1"

In MzScheme parameters have their own types and are scoped to execution threads. Since Bigloo does not provide multi-threading, bigloo-lib parameters eare implemented as ordinary scheme procedures.

inline procedure: directory-exists? path::bstring => #unspecified

Aliases Bigloo directory? procedure

procedure: make-directory path::bstring #!optional mask::int

Create the new directory path with access mask mask. The default value of mask is #o0777.

procedure: current-directory #!optional newdir

Get or set the application process current directory.

 
(current-directory)
=> /usr/local/bin

(current-directory "/home/wowa")
=> #unspecified

(current-directory)
=> /home/wowa

procedure: build-path dir::bstring chunks => #unspecified

Construct a directory name from chunks. Each chunk may be the path by itself, i.e. include the slash character. Chunk should not start with slash character, i.e. all sub-paths must be relative.

Example:

 
(build-path "/a/b/c" "d/e/f" "y")
=> "/a/b/c/d/e/f/y"

(build-path "/a/b/c" "/d/e/f" "y")
error--> absolute paths should not be appended: /d/e/f


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5 Dynamic linking library

This section describes the dl module, which provides an interface to libdl.so system library.

With the use of this module, you can load shared objects dynamically and retrieve values of the symbols registered in that objects.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.1 Types

foreign: dl

An open shared object handle as returned by dlopen

foreign: dlsym

A symbol object as returned by dlsym.

enum: dlopen-flags

A set of possible values for the mode argument of dlopen procedure.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.2 Procedures

procedure: dlopen #!optional (path "") #!rest dlopen-flags => dl

The procedure dlopen loads a dynamic library from the file path and returns an opaque "handle" for the dynamic library. The dlopen-flags argument is a list of flags. Each flag must be one of the following scheme symbols: lazy, now or global. See the dlopen man page for the meaning of these arguments.

procedure: dlsym handle::dl name::string => dlsym

TBD


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6 SRFI-1 List Library

TBD


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7 SRFI-13 String Library

Bigloo-lib provides a limited support for string-lib, the SRFI-13 string library. The limitations are as follows:

The rest of this chapter is based mostly on original SRFI document, copyrighted by Olin Shivers.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.1 Procedure specifications

In the following procedure specifications:

Passing values to procedures with these parameters that do not satisfy these types is an error.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.2 Predicates

procedure: string-null? s::bstring => bool

Is s the empty string?

 
(string-null? "")
=> #t

procedure: string-every pred::procedure s::string #!optional start end

Checks to see if predicate pred is true of every character in S, proceeding from left (index start) to right (index end).

If STRING-EVERY returns true, the returned true value is the one produced by the final application of pred to S[end]. If STRING-EVERY is applied to an empty sequence of characters, it simply returns #t.

procedure: string-any pred::procedure s::string #!optional start end

Checks to see if predicate pred is true of any character in S, proceeding from left (index start) to right (index end).

If string-any returns true, the returned true value is the one produced by the application of pred.

 
(string-every values "qwerty")
=>


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.3 Constructors

procedure: string-tabulate proc::procedure len::int => bstring
proc is an integer->char procedure. Construct a string of size len by applying proc to each index to produce the corresponding string element. The order in which proc is applied to the indices is not specified.

Example:
 
(string-tabulate (lambda(i)(integer->char(+fx i 32))) 20)
=> " !\"#$%&'()*+,-./0123"


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.4 List & string conversion

procedure: string->list s::bstring #!optional start end => pair-nil

string->list returns a newly allocated list of the characters that make up the given string. list->string returns a newly allocated string formed from the characters in the list char-list, which must be a list of characters. string->list and list->string are inverses so far as equal? is concerned.

string->list is extended from the R5RS definition to take optional start/end arguments.

 
(string->list "asdf")
=> (#\a #\s #\d #\f)

procedure: reverse-list->string char-list::pair-nil => bstring

An efficient implementation of (compose string->list reverse):

 
(reverse-list->string '(#\a #\B #\c))
=> "cBa"

This is a common idiom in the epilog of string-processing loops that accumulate an answer in a reverse-order list. (See also reverse-string-concatenate for the "chunked" variant.)

procedure: string-join string-list::pair-nil #!optional delimiter grammar => bstring

This procedure is a simple unparser - it pastes strings together using the delimiter string.

The grammar argument is a symbol that determines how the delimiter is used, and defaults to 'infix.

The delimiter is the string used to delimit elements; it defaults to a single space " ".

Example:

 
(join-strings '("foo" "bar" "baz") ":")         => "foo:bar:baz"
(join-strings '("foo" "bar" "baz") ":" 'suffix) => "foo:bar:baz:"

;; Infix grammar is ambiguous wrt empty list vs. empty string,
(join-strings '()   ":") => ""
(join-strings '("") ":") => ""

;; but suffix & prefix grammars are not.
(join-strings '()   ":" 'suffix) => ""
(join-strings '("") ":" 'suffix) => ":"


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.5 Selection

procedure: string-copy s::bstring #!optional start end => bstring

string-copy is extended from its R5RS definition by the addition of its optional start/end parameters. In contrast to SUBSTRING/SHARED, it is guaranteed to produce a freshly-allocated string.

Use string-copy when you want to indicate explicitly in your code that you wish to allocate new storage; use SUBSTRING/SHARED when you don't care if you get a fresh copy or share storage with the original string.

Example:
 
(string-copy "Beta substitution") => "Beta substitution"
(string-copy "Beta substitution" 1 10) 
=> "eta subst"
(string-copy "Beta substitution" 5) => "substitution"

procedure: substring/shared s::bstring #!optional start end => bstring

substring/shared returns a string whose contents are the characters of s beginning with index start (inclusive) and ending with index end (exclusive). It differs from the R5RS substring in two ways:

Example:
 
(let((s "Beta substitution"))
  (eq?(substring/shared s 0)s))
=> #t

procedure: string-copy! target::bstring tstart s #!optional start end => bstring

Copy the sequence of characters from index range (start,end) in string s to string target, beginning at index tstart. The characters are copied left-to-right or right-to-left as needed -- the copy is guaranteed to work, even if target and s are the same string.

It is an error if the copy operation runs off the end of the target string, e.g.

 
(string-copy! (string-copy "Microsoft") 0
"Regional Microsoft Operating Companies") error-->

Note: though the result of string-copy! is defined as unspecified by SRFI document, the implementation always returns the target argument.

Example:
 
(string-copy! "qwerty" 2 "asdf")
=> "qwasdf"

procedure: string-take s::bstring nchars::int => bstring

string-take returns the first ncharsof s;

If this procedure produces the entire string, it may return either s or a copy of s; in some implementations, proper substrings may share memory with s.

Example:
 
(string-take "Pete Szilagyi" 6) => "Pete S"

It is an error to take more characters than are in the string:
 
(string-take "foo" 37) error-->

inline procedure: string-drop s::bstring nchars::int => bstring

string-drop returns all but the first ncharsof s.

If this procedure produces the entire string, it may return either s or a copy of s; in some implementations, proper substrings may share memory with s.

Example:
 
(string-drop "Pete Szilagyi" 6) => "zilagyi"

It is an error to drop more characters than are in the string:
 
(string-drop "foo" 37) error-->

procedure: string-take-right s::bstring nchars::int => bstring

string-take-right returns the last ncharsof s.

If this procedure produces the entire string, it may return either s or a copy of s; in some implementations, proper substrings may share memory with s.

Example:
 
(string-take-right "Beta rules" 5) => "rules"
It is an error to take more characters than are in the string:
 
(string-take-right "foo" 37) error-->

procedure: string-drop-right s::bstring nchars::int => bstring

string-drop-right returns all but the last ncharsof s.

If this procedure produces the entire string, it may return either s or a copy of s; in some implementations, proper substrings may share memory with s.

Example:
 
(string-drop-right "Beta rules" 5) => "Beta "
It is an error to drop more characters than are in the string:
 
(string-drop-right "foo" 37) error-->

procedure: string-pad s::bstring len::int #!optional char start end => bstring

Build a string of length len comprised of s padded on the left by as many occurrences of the character char as needed. If s has more than len chars, it is truncated on the left to length len. char defaults to #\space.

If len <= end - start, the returned value is allowed to share storage with s, or be exactly s (if len = end - start).

Example:
 
(string-pad     "325" 5) => "  325"
(string-pad   "71325" 5) => "71325"
(string-pad "8871325" 5) => "71325"

procedure: string-pad-right s::bstring len::int #!optional char start end => bstring

Build a string of length len comprised of s padded on the right by as many occurrences of the character char as needed. If s has more than len chars, it is truncated on the right to length len. char defaults to #\space.

If len <= end - start, the returned value is allowed to share storage with s, or be exactly s (if len = end - start).

Example:
 
(string-pad-right     "325" 5) => "325  "
(string-pad-right   "71325" 5) => "71325"
(string-pad-right "8871325" 5) => "88713"

procedure: string-trim s::bstring #!optional char/char-set/pred start end => bstring

The string-trim, string-trim-right, string-trim-both procedures trim s by skipping over all characters on the left / on the right / on both sides that satisfy the second parameter char/char-set/pred:

char/char/set-pred defaults to the character set char-set:whitespace defined in SRFI-14.

If no trimming occurs, these functions return s.

Example:
 
(string-trim #"  The outlook wasn't brilliant,  \n\r")
=> #"The outlook wasn't brilliant,  \n\r"

procedure: string-trim-right s::bstring #!optional char/char-set/pred start end => bstring

See description of string-trim.

Example:
 
(string-trim-right #"  The outlook wasn't brilliant,  \n\r")
=> #"  The outlook wasn't brilliant,"

procedure: string-trim-both s::bstring #!optional char/char-set/pred start end => bstring

See description of string-trim.

Example:
 
(string-trim-both #"  The outlook wasn't brilliant,  \n\r")
=> #"The outlook wasn't brilliant,"


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.6 Modification

procedure: string-fill! s::bstring char::char #!optional start end

Stores char in every element of s and returns (in this implementation only) the s string.

string-fill! is extended from the R5RS definition to take optional start/end arguments.

Example:
 
(let((s "12345678"))
  (string-fill! s #\space 2 4)
  s)
=> "12  5678"


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.7 Comparison

These procedures are the lexicographic extensions to strings of the corresponding orderings on characters. For example, STRING< is the lexicographic ordering on strings induced by the ordering CHAR<? on characters. If two strings differ in length but are the same up to the length of the shorter string, the shorter string is considered to be lexicographically less than the longer string.

The optional start/end indices restrict the comparison to the indicated substrings of s1 and s2.

string-ci=, string-ci<>, string-ci<, string-ci>, string-ci<= and string-ci>= procedures are case-insensitive variants of string=, string<>, string<, string>, string<= and string>= correspondingly.

Comparison is simply done on individual code-points of the string. True text collation is not handled by this SRFI.

Case-insensitive comparison is done by case-folding characters with the operation (char-downcase (char-upcase c))

procedure: string= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test strings for equality. See notes at the beginning of this section.

procedure: string<> s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test strings for inequality. See notes at the beginning of this section.

procedure: string< s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is less than s2 string. See notes at the beginning of this section.

procedure: string> s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is greater than s2 string. See notes at the beginning of this section.

procedure: string<= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is less than or equal to s2 string. See notes at the beginning of this section.

procedure: string>= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is greater than or equal to s2 string. See notes at the beginning of this section.

procedure: string-ci= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test strings for equality case-insensitive. See notes at the beginning of this section.

procedure: string-ci<> s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test strings for inequality case-insensitive. See notes at the beginning of this section.

procedure: string-ci< s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is less than s2 string case-insensitive. See notes at the beginning of this section.

procedure: string-ci> s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is greater than s2 string case-insensitive. See notes at the beginning of this section.

procedure: string-ci<= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is less than or equal to s2 string case-insensitive. See notes at the beginning of this section.

procedure: string-ci>= s1::bstring s2::bstring #!optional start1 end1 start2 end2 => bool

Test if s1 string is greater than or equal to s2 string case-insensitive. See notes at the beginning of this section.

procedure: string-hash s::bstring #!optional bound start end => int

Compute a hash value for the string s. bound is either #f or a non-negative exact integer. If an integer, it gives the target range of the hash function -- the returned value will be in the range [0,bound].

If bound is either #f or not given, the implementation may use an implementation-specific default value, which might be chosen, for instance, to map all strings into the range of integers that can be efficiently represented.

The optional start/end indices restrict the hash operation to the indicated substring of s.

Invariants: (<= 0 (string-hash s b) (- b 1))

 
(string=    s1 s2)  =>  (= (string-hash s1 b)    (string-hash s2 b))

procedure: string-hash-ci s::bstring #!optional bound start end => int

string-hash-ci is the case-insensitive variant of string-hash.

Invariants: (<= 0 (string-hash-ci s b) (- b 1))

 
(string-ci= s1 s2)  =>  (= (string-hash-ci s1 b) (string-hash-ci s2 b))


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.8 Prefixes & suffixes

procedure: string-prefix-length s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Return the length of the longest common prefix of the two strings. This is equivalent to the "mismatch index" for the strings (modulo the starti index offsets).

The optional start/end indices restrict the comparison to the indicated substrings of s1 and s2.

Example:
 
(string-prefix-length "qwertyasdf" "qwertypoiuy")
=> 6

procedure: string-suffix-length s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Return the length of the longest common suffix of the two strings. This is equivalent to the "mismatch index" for the strings (modulo the starti index offsets).

The optional start/end indices restrict the comparison to the indicated substrings of s1 and s2.

Example:
 
(string-prefix-length "asdfqwerty" "poiuqwerty")
=> 6

procedure: string-prefix-length-ci s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Case-insensitive variant of string-prefix-length.

procedure: string-suffix-length-ci s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Case-insensitive variant of string-suffix-length.

procedure: string-prefix? s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Is s1 a prefix of s2?

Example:
 
(string-prefix? "qwerty" "qwertyasdf"
=> #t

procedure: string-suffix? s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Is s1 a suffix of s2?

Example:
 
(string-prefix? "qwerty" "asdfqwerty"
=> #t

procedure: string-prefix-ci? s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Case-insensitive variant of string-prefix?.

procedure: string-suffix-ci? s1::bstring s2::bstring #!optional start1 end1 start2 end2 => int

Case-insensitive variant of string-suffix?.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.9 Searching

procedure: string-index s::bstring char/char-set/pred #!optional start end => int or #f

string-index searches through the string from the left, returning the index of the first occurrence of a character which

If no match is found, the functions return #f.

The start and end parameters specify the beginning and end indices of the search; the search includes the start index, but not the end index. The first index considered is end-1.

procedure: string-index-right s::bstring char/char-set/pred #!optional start end => int or #f

string-index-right searches through the string from the right, returning the index of the first occurrence of a character which

If no match is found, the functions return #f.

The start and end parameters specify the beginning and end indices of the search; the search includes the start index, but not the end index. The first index considered is start.

procedure: string-skip s::bstring char/char-set/pred #!optional start end => int or #f

The string-skip functions is similar to string-index, but uses the complement of the criteria: is searches for the first char that *doesn't* satisfy the test. E.g., to skip over initial whitespace, say

 
(cond ((string-skip s char-set:whitespace) =>
  (lambda (i)
    ;; (string-ref s i) is not whitespace.
    ...)))

procedure: string-skip-right s::bstring char/char-set/pred #!optional start end => int or #f

The string-skip-right functions is similar to string-index-right, but uses the complement of the criteria: is searches for the first char that *doesn't* satisfy the test.

procedure: string-count s char/char-set/pred #!optional start end

TBD

procedure: string-contains s1::bstring s2::bstring #!optional start1 end1 start2 end2

TBD

procedure: string-contains-ci s1 s2 #!optional start1 end1 start2 end2

TBD

procedure: string-titlecase s #!optional start end

TBD

procedure: string-titlecase! s #!optional start end

TBD

procedure: string-upcase s #!optional start end => bstring

TBD

procedure: string-upcase! s #!optional start end

TBD

procedure: string-downcase s #!optional start end => bstring

TBD

procedure: string-downcase! s #!optional start end

TBD

procedure: string-reverse s #!optional start end => bstring

TBD

procedure: string-reverse! s #!optional start end

TBD

procedure: string-concatenate string-list::pair-nil => bstring

TBD

procedure: string-concatenate/shared string-list::pair-nil => bstring

TBD

procedure: string-append/shared string-list => bstring

TBD

procedure: reverse-string-concatenate string-list #!optional final-string end => bstring

TBD

procedure: reverse-string-concatenate/shared string-list #!optional final-string end => bstring

TBD

procedure: string-map proc s #!optional start end => bstring

TBD

procedure: string-map! proc s #!optional start end

TBD

procedure: string-fold kons knil s #!optional start end

TBD

procedure: string-fold-right kons knil s #!optional start end

TBD

procedure: string-unfold p f g seed #!optional base make-final => bstring

TBD

procedure: string-unfold-right p f g seed #!optional base make-final => bstring

TBD

procedure: string-for-each proc s #!optional start end

TBD

procedure: xsubstring s from #!optional to start end => bstring

TBD

procedure: string-xcopy! target tstart s sfrom #!optional sto start end

TBD

procedure: string-replace s1 s2 #!optional start1 end1 start2 end2 => bstring

TBD

procedure: string-tokenize s #!optional token-set start end => pair-nil

TBD

procedure: string-filter s char/char-set/pred #!optional start end => bstring

TBD

procedure: string-delete s char/char-set/pred #!optional start end => bstring

TBD

procedure: string-parse-start+end proc s args

TBD

procedure: string-parse-final-start+end proc s args

TBD

procedure: check-substring-spec proc s start end

TBD

procedure: substring-spec-ok? s start end => bool

TBD

procedure: make-kmp-restart-vector c= s #!optional start end => vector

TBD

procedure: kmp-step pat rv c= c i

TBD

procedure: string-search-kmp pat rv c= i s #!optional start end => int

TBD


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.8 Miscellaneous stuff

procedure: environ => pair-nil

Obtain the current environment as a list of name/value pairs. For example:

 
(pp(environ))
-| ((#"_" . #"/usr/local/bin/bigloo-common")
 (#"CONFIG_SITE" . #"/home/wowa/.autoconf")
 (#"HOME" . #"/home/wowa")
 (#"TERM" . #"emacs")
 (#"OSTYPE" . #"solaris2.7")
...

Probably you'll need this procedure for debugging only. Use getenv and setenv Bigloo procedures instead.

procedure: setenv name::string value::string

The setenv procedure makes the value of the environment variable name equal to value by altering an existing variable or creating a new one.

procedure: unsetenv name::string

The unsetenv procedure function deletes the variable name from the environment.

procedure: errno #!optional new-value => int

Return the value of libc errno variable. If the new-value parameter is present, set the value of errno to new-value.

 
(errno) => 0
;; try an illegal operation
(open "nonexistentfile")
-| *** ERROR:bigloo:open:
file opening error -- nonexistentfile

;; read error code and reset errno
(errno 0) => 2

procedure: mmap length #!key fd prot flags offset
=> bstring

The mmap procedure asks to map length bytes starting at offset offset from the file (or other object) specified by fd into memory.

length::int
The number of bytes to map. Since the mmap result is returned in form of Bigloo bstring, the length really passed to libc mmap() includes the bstring object overhead too.

#!key fd
Descriptor of file to map. Since the result always includes the overhead of bstring object, this mmap implementation is practical useless if you want to map anything but dummy devices such a /dev/zero.

If fd argument is omitted, the /dev/zero device is used to get a file descriptor.

#!key prot
List of protection flag symbols. The valid values are:

exec
Pages may be executed.
read
Pages may be read.
write
Pages may be written.
none
Pages may not be accessed.

#!key flags
List of mmap options. The valid values are fixed, shared and private. The values denywrite, executable and anonymous are also valid but have no effect on systems other than Linux. See the mmap manual pages for details.

#!key offset
Byte offset from beginning of file to be mapped.

This procedure may be useful if you want to temporary allocate the huge amount of memory which should be released and returned to operating system. Besides, the memory allocated with mmap is not accessed until you really use it, so the allocation is very fast.

In the following example we will illustrate this feature. First we measure how much memory the application process consumes, using the ps command:

 
bash$ ps u 17012
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COM
wowa     17012  2.1  5.7  7108 2236 ttyp4    S    20:32   0:00 /us

Then we mmap 16M of memory:

 
(define mem (mmap #x1000000))

As we may expect the process virtual memory increases now by 16M:
 
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COM
wowa     17012  0.1  5.8 23496 2260 ttyp4    S    20:32   0:00 /us

Now we do the unmap:

 
(munmap mem)

And measure the process memory again:

 
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COM
wowa     17012  0.0  5.7  7108 2252 ttyp4    S    20:32   0:00 /us

procedure: munmap mem::bstring

Release memory mapped by mmap.

procedure: stat what => stat

Return information about the specified file. The argument what should be either the name of the file or open file descriptor.

The result is of type stat, for which the following read accessor procedures are defined:

stat-mode
file protection mode flag list. See below.
stat-uid
User ID of the file's owner
stat-gid
Group ID of the file's group
stat-size
File size in bytes
stat-atime::double
Time of last access
stat-mtime::double
Time of last data modification
stat-ctime::double
Time of last file status change

The meaning of abovementioned stat-mode flag list is as follows:

fsock => file is a socket
flnk => file is a symbolic link
freg => file is a regular file
fblk => file is a block device
fdir => file is a directory
fchr => file is a character device
fifo => file is a fifo
suid => file has the UID bit set
sgid => file has the GID bit set
svtx => file has the sticky bit set
rusr => file owner has read permission
wusr => file owner has write permission
xusr => file owner has execute permission
rgrp => file group has read permission
wgrp => file group has write permission
xgrp => file group has execute permission
roth => file others have read permission
woth => file others have write permisson
xoth => file others have execute permission

 
(let((st(stat "/etc/passwd"))
     (pt(lambda(seconds)(strftime(localtime seconds)))))
  (print "User ID:         " (stat-uid st))
  (print "Group ID:        " (stat-gid st))
  (print "Size:            " (stat-size st))
  (print "Flags:           " (stat-mode st))
  (print "Accessed:        " (pt(stat-atime st)))
  (print "Data modified:   " (pt(stat-mtime st)))
  (print "Status modified: " (pt(stat-ctime st))))
-| User ID:         0
-| Group ID:        0
-| Size:            2110
-| Flags:           (roth rgrp wusr rusr freg)
-| Accessed:        10/01/01 18:54:05
-| Data modified:   09/21/01 17:21:52
-| Status modified: 09/21/01 17:21:52

procedure: isatty fd::int => bool

Test for a terminal device. Argument what should be open file descriptor. Example:

 
(isatty(open "/dev/tty"))
=> #t
(isatty(open "/etc/passwd"))
=> #f

procedure: open file-name::string . oflag => int

Open file name file-name, return the integer file descriptor.

The optional oflag arguments may be any of the following symbols: rdonly, wronly, rdwr, append, nonblock, creat, trunc, excl or noctty. See open(2) manual page for the meaning of the flag values.

Example:

 
(let*((fd(open "/etc/passwd"))
      (bytes(fdread fd 100)))
  (close fd)
  bytes)
-| root:XXXXXXXXX:0:0:root:/root:/bin/bash
-| bin:*:1:1:bin:/bin:
-| daemon:*:2:2:daemon:/sbin:
-| adm:*:3:4

procedure: close fd::int => int

Close a file descriptor, so that it no longer refers to any file and may be reused.

procedure: fdread fd::int arg => bstring

Read using the open file descriptor fd by calling libc read() function.

If argument arg is a string, it used to receive the bytes read, and the length of that string used as byte count. Otherwise is should be an integer number of bytes to read, and a fresh buffer will be allocated for each operation call.

procedure: fdwrite fd::int str::bstring => int

Try to write the str to specified file descriptor. Return the number of bytes really wrote.

procedure: getppid => int

getppid returns the process ID of the parent of the current process.

procedure: getpid => int

getpid returns the process ID of the current process. (This is often used by routines that generate unique temporary file names.)

procedure: getlogin => bstring or #f

The getlogin procedure returns a pointer to the login name as found in /var/adm/utmp. It may be used in conjunction when the same user ID is shared by several login names. See getlogin(3c) manual page for details.

If getlogin is called within a process that is not attached to a terminal, it returns #f. In later case use the cuserid procedure instead.

As example of how the getlogin works, we first run the utility from non-terminal xemacs window, and then from the rlogin shell:

 
bigloo-common
1:=> (getlogin)
=> #f
1:=> 
bash-2.03$ rlogin localhost
Password: 
Last login: Thu May  4 15:19:55 from localhost
bash-2.03$ bigloo-common
bigloo-common
1:=> (getlogin)
(getlogin)
=> wowa
1:=> 
bash-2.03$ 

procedure: getpwnam what::symbol #!optional name => #unspecified

The getpwnam procedure is used to obtain password entries. The what arguments controls which entry will be returned by the procedure. The valid values of what are:

name
user's login name (string)
uid
user's uid (integer)
gid
user's gid (integer)
gecos
typically user's full name (string)
dir
user's home dir (string)
shell
user's login shell (string)

The optional name argument may be integer user ID or string user name of the user in question. If omitted, the name of current user as returned by cuserid is used.

 
(getpwnam 'shell)
=> "/usr/bin/bash"
(getpwnam 'dir "adm")
=> "/var/adm"

procedure: cuserid => bstring
The cuserid procedure generates a character-string representation of the login name under which the owner of the current process is logged in.

 
(cuserid)
=> wowa

procedure: strxfrm src::bstring => bstring

The strxfrm procedure transforms the src string into a form such that the result of memcmp on two strings that have been transformed with strxfrm is the same as the result of locale-sensitive string-comparing procedures (string=?, string<? etc.) on the two strings before their transformation. (See setlocale).

 
(setlocale 'all "ru_RU.KOI8-R")
(pp(strxfrm "qwerty"))
-| #"\304\210\304\232\303\244"
(setlocale 'all "C")
(pp(strxfrm "qwerty"))
-| #"qwerty"

procedure: crypt passwd::bstring salt::bstring => bstring
crypt(3) is the password encryption function. It is based on the Data Encryption Standard algorithm with variations intended (among other things) to discourage use of hardware implementations of a key search.

passwd is a user's typed password.

salt is a two-character string chosen from the set [a-zA-Z0-9./]. This string is used to perturb the algorithm in one of 4096 different ways.

See the man pages for crypt(3).

 
(crypt "my-secret-password" "joe")
 => "jonhWNi0AD56g"

procedure: md5 data::bstring #!optional start end => bstring

Calculate digest using md5 algorithm. Return 16-byte long byte string. Optional start and end parameters may be used to work with substrings. For example:

 
(pp (md5 "qwerty"))
-| #"\330W\216\337\204X\316\006\373\305\273v\245\214\\\244"

md5 digest may include any characters, it is usually converted to printed form with string->hex, for example:

 
(string->hex (md5 "qwerty"))
=> "d8578edf8458ce06fbc5bb76a58c5ca4"

procedure: char->hex c::uchar => bstring

char->hex prints character c to hexadecimal string, for example:

 
(char->hex #\newline)
=> "0a"

procedure: string->hex str::bstring => bstring

string->hex prints string str using char->hex conversion, for example:

 
(string->hex "Hello")
=> "48656c6c6f"

procedure: string-grammar-apply s::bstring next-token::procedure => bstring

s string to parse. next-token procedure of one argument which must be a scheme input port.

The procedure string-grammar-apply translates strings. It creates an input port, and applies next-token to this port. The string output port is also created, and the result returned by next-token is printed to it using scheme display procedure. The operation repeats until the input is exausted.

The contents of an output port is returned.

For example an http-url-decode procedure in http library, which decodes URL uses this procedure:

 
(define (http-url-decode str)
  (string-grammar-apply
   str
   (lambda(port)
     (read/rp
      (regular-grammar
       ()
       ((: (in "%^") xdigit xdigit)
	(integer->char(string->number(the-substring 1 3)16)))
       (#\+ #\space))
      port))))

(http-url-decode "%61%62+%63%64") => "ab cd"

procedure: string*->string-list sp::string* => pair-nil
procedure: string-list->string* sl::pair-nil => string*

sp a pointer to a C array of C zero-terminated strings. The array must be terminated by NULL value.

The convenience procedures string*->string-list and string-list->string* converts an array of C strings to and from scheme list object correspondingly. Such arrays are very common in C APIs.

For example, the C-runtime environ global variable may be accessed in this way:

 
(pragma "extern char** environ")
(pp(string*->string-list(pragma::string* "environ")))
-|
("PWD=/home/wowa/"
 "HOSTNAME=duron"
 "LD_LIBRARY_PATH=/usr/X11R6/lib:/usr/local/lib"
 "HOSTDISPLAY=localhost:0.0"
 ...
)

procedure: apropos rexp::regexp-or-string

The procedure apropos returns the list of all Bigloo globals visible to eval procedure which match the given regular expression.

Examples:

Print all globals having "string->" in a name:

 
(pp(apropos "string->"))
-|
(string->keyword
  string->elong
  string->obj
  ieee-string->double
  ucs2-string->utf8-string
  string->hex
  string->integer
  string->symbol
  ieee-string->real
  string->0..2^x-1
  ieee-string->float
  string->0..255
  utf8-string->ucs2-string
  string->list
  string->number
  string->llong
  string->real
  ucs2-string->list
  string->symbol-ci)

Print all globals wich a name ending with "list":

 
(pp(apropos "list$"))
-|
(symbol-plist
  process-list
  directory->list
  list
  vector->list
  string*->string-list
  make-list
  circular-list
  unix-path->list
  path->list
  hashtable-key-list
  string->list
  hashtable->list
  ucs2-string->list
  flatten-list
  history-list)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.9 iconv - charset conversion procedures

This section describes the interface to iconv - a set of libc functions for character set conversion. See iconv(3) manual page for details.

The iconv module is optional, i.e. you can disable its compilation by using --without-iconv flag for configure. Or the configure may detect that your libc does not have iconv functions and automatically disable this feature.

To let you detect whether character conversion is supported by the library from inside the interpreted code, the 'iconv symbol is defined through the register-eval-srfi! mechanism, so you can check it with cond-expand.

foreign type: iconv

The structure holding the information about the source and target character sets and current state of conversion.

procedure: iconv-open tocode::string fromcode::string writer::procedure => iconv

The iconv-open procedure returns a conversion descriptor that describes a conversion from the codeset specified by the fromcode argument to the codeset specified by the tocode argument. For state-dependent encodings, the conversion descriptor will be in a codeset-dependent initial shift state, ready for immediate use with the iconv procedure.

The writer should be a one-argument procedure which handles partial conversion result strings during subsequent calls to the iconv-write.

In the folowing example the iconv objects is created which will display the converted strings to the current-output-port.

 
(iconv-open "KOI8-R" "UTF-8" display)
=> #<foreign:ICONV:21410>

procedure: iconv-write cd::iconv src::bstring

The iconv-write procedure converts the sequence of characters from the code set specified in parameter fromcode of iconv-open, in the array specified by src, into a sequence of corresponding characters in the code set specified in parameter tocode of iconv-open, in the return string. The code sets are those specified in the cd argument.

The result of conversion is passed to the procedure specified in parameter writer of iconv-open.

procedure: make-iconv-encoder from::bstring to::bstring => #unspecified

Returns the procedure of the form (lambda (#!optional s #!key from to onerror)). This procedure, being called with arguments returns the string s converted to the target encoding. The keyed arguments from and to may be used to make the translation on the substring of s.

You should close the iconv object used to perform the translation by calling this procedure with no parameters.

Examples:

Translate my name in Russian from KOI8-R (one of Cyrillic most widely used Russian code sets) to UTF-8:

 
(define koi8->utf8(make-iconv-encoder "KOI8-R" "UTF-8"))
(koi8->utf8 "÷Ï×Á")
=> "\320\222\320\276\320\262\320\260"

;; Now skip one character
(koi8->utf8 "÷Ï×Á" from: 1)
=> "\320\276\320\262\320\260"

;; Close the iconv structure
(koi8->utf8)

procedure: iconv-close cd::iconv => int

Release the cd object and all related resources.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.10 Time-related procedures

This section describes types and procedures, dealing with time. They let you measure calendar and UNIX process time, print time using locale settings, and also do some arithmetics with times and dates.

foreign: tm

A wrapper for C library struct tm structure, broken-down time representation.

The following read accessors are defined:

tm-sec
The number of seconds after the minute, normally in the range 0 to 59, but can be up to 61 to allow for leap seconds.

tm-min
The number of minutes after the hour, in the range 0 to 59.

tm-hour
The number of hours past midnight, in the range 0 to 23.

tm-mday
The day of the month, in the range 1 to 31.

tm-mon
The number of months since January, in the range 0 to 11.

tm-year
The number of years since 1900.

See also strftime procedure description to print these objects in human-readable form.

procedure: make-tm => tm

Allocate an uninitialized object of type tm. This procedure is used internally by other time-manipulation procedures. Perhaps, you do not want to call it explicitly.

procedure: gmtime seconds::double #!optional tm::tm => tm

Interface for C runtime gmtime call. Take number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC), and convert it to broken-down time representation, expressed in Coordinated Universal Time (UTC).

 
(strftime(gmtime(current-seconds)))
=> 04/16/00 17:56:54

procedure: localtime seconds::double #!optional tm::tm => tm

Same as gmtime, but the result is expressed relative to the user's specified time zone.

The procedure also sets the values returned by tzname and timezone and daylight.

procedure: timezone => int

Return number of seconds west of UTC. For example, here in Moscow:

 
(timezone)
=> -10800
(/ (timezone) 3600)
=> -3

procedure: tzname => 2 scheme values

Return names of time zone as two scheme values. See tzset manual pages for details. The values are also set by localtime. For example:

 
(define(tzprint)
  (multiple-value-bind
   (name name1)
   (tzname)
   (print name ", " name1)))

(tzprint)
(localtime 0.0) ;; this call for side effects only
(tzprint)
=> GMT, GMT
MSK, MSD

procedure: daylight => bool

A flag that indicates whether daylight saving time is in effect at the time described. Return positive value if daylight saving time is in effect, zero if it is not, and negative value if the information is not available.

procedure: strftime tm::tm #!optional format::bstring => bstring

The strftime procedure formats the broken-down time tm according to the format specification. If format argument is omitted, the "%x %X" string is used to format output. See strftime manual pages for details.

Examples:

 
(define now(localtime(current-seconds)))
=> #<foreign:TM:806dbd0>

(strftime now)
"04/16/00 23:38:14"

(strftime now "%Y%m%d%H%M%S")
"20000416233814"

procedure: current-seconds => double

Number of seconds as returned by gettimeofday C runtime call. The name of procedure chosen to be compatible with analogous procedure in MzScheme.

Example:

 
(current-seconds)
=> 955914618.43757

procedure: current-milliseconds => double

Defined as:

 
(define(current-milliseconds::double)
  (* (current-seconds) 1000.0))

procedure: ctime seconds::double => bstring

Interface for ctime_r C runtime procedure. Return 26-character string with fixed-format time representation, for example:

 
(ctime (current-seconds)) => "Mon Apr 17 12:28:54 2000"

procedure: mktime year month day #!optional hour minute second => tm

Constructor for objects of tm type. The arguments are:

year::int
The year, including the century number
month::int
Month in an year number from 1 to 12
day::int
Day in a month number
hour::int
Hour in day number from 0 to 23. Default is 0.
minute::int
Minute in a hour number from 0 to 59. Default is 0.
second::int
Second in a minute number. Default is 0.

Example:
 
(strftime(mktime 1960 12 27))
=> "12/27/60 00:00:00"

procedure: read-date fmt::bstring port::input-port => tm

Read date/time from port port using the specification fmt. The format of the specification is a subset that of strftime specification (only %S, %M, %H, %I, %d, %m, %Y, %p and %% escape sequences are supported).

Examples:

 
(strftime
  (read-date "%Y%m%d%H%M%S"
             (open-input-string "20000416233814")))
=> "04/16/00 23:38:14"
(strftime
  (read-date
    "%d.%m.%Y %H:%M:%S"
    (open-input-string "26.05.2002 14:16:01")))
=> "05/26/02 14:16:01"

procedure: times #!optional which? => long

The times procedure measures various time-accounting information. Depending on value of argument which? of symbol type it returns the following values:

utime
User time
stime
System time
cutime
User time of children
cstime
System time of children

If argument which? is absent, the times procedure returns five scheme values: the number of clock ticks that have elapsed since the system has been up, and all the values just described, i.e. utime, stime, cutime and cstime.

All the values are measured in system clock ticks. The length of one tick is system-dependent. Number of clocks per second may be obtained by calling clocks-per-second procedure.

Examples:

Here number of system clock ticks from the system start-up is measured:

 
(times)
=> 1720216

The same value but now in seconds:

 
(/(times)(clocks-per-second))
=> 17340.09

The following example is a complete utility that measures the external process times.

The initial times are measured and stored in local variables total, cutime and cstime, external process is spawned using bigloo run-process procedure See Info file `bigloo', node `Process support'. After the spawned process is finished, the statistics is printed to standard error port in form similar that of Unix time utility.

 
#!/usr/local/bin/bigloo-common

(multiple-value-bind
 (total utime stime cutime cstime)
 (times)
 (apply run-process
	(append (cddr(command-line))
		'(wait: #t)))
 (multiple-value-bind
  (ntotal nutime nstime ncutime ncstime)
  (times)
  (let((ticks(clocks-per-second))
       (user-ticks(- ncutime cutime))
       (system-ticks(- ncstime cstime))
       (elapsed-ticks(- ntotal total)))
    (fprintf
     (current-error-port)
     "~auser ~asystem ~aelapsed ~a%CPU~%"
     (/ user-ticks ticks)
     (/ system-ticks ticks)
     (/ elapsed-ticks ticks)
     (inexact->exact
      (*(/(+ user-ticks system-ticks) elapsed-ticks)100))))))

The utility usage example (provided the ./time is the script location):

 
bash$ ./time gzip -c /vmlinuz > /dev/null
1.17user 0.03system 1.2elapsed 100%CPU

procedure: tm->utctime time::tm => bstring

Print time argument in UTC time format.

 
(tm->utctime(localtime(current-seconds)))
=> 20000531123949Z

procedure: utctime->tm utc::bstring => tm
utc
 
(strftime(utctime->tm "20000531123949Z"))
=> 05/31/00 12:39:49


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11 cgen - bigloo preprocessor

This section describes cgen -- the utility for creating bigloo interfaces to C libraries.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.1 What is it for?

cgen allows you to create wrappers for external C functions and external C types, such as structures, enums, bit fields and opaque pointers.

cgen comes to you with bigloo-lib in common/ subdirectory. It should be automatically created before the creation of any of bigloo-lib libraries. All the external C interfaces in bigloo-lib are built with help of cgen.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.2 Why not bigloo foreign interface?

In course of evaluation of the foreign interface, I found it not always suitable for the following reasons :

cgen was developed in hope to achieve the following goals:

On the other hand, Bigloo has excellent capabilities of creating any new types, using the type and coerce statements in module declaration. The only bad thing with Bigloo type scheme is that it is absolutely undocumented (though the documented extern type interface is based upon that low-level layer).

cgen work is based upon these capabilities and it is alternative to Bigloo foreign interface.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.3 How does it works

cgen is a preprocessor for bigloo scheme code. It takes one or more files with C interface specification as input and produces the readable scheme file on output. The specification itself is bigloo scheme text with some special constructs. As result of processing this constructs the new procedures and bigloo module declarations are created. All scheme expressions, that cgen does not recognize, are printed back into output with no changes.

By convention, all the cgen input files have extension .defs in bigloo-lib, you may use it as cgen usage examples.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.4 cgen command line

Typically cgen is used in this form:

 
cgen -o <outfile> file1 [file2] ...

The other options are:

-o <filename>
Set the name of output file. cgen uses current-error-port if this option is not used.

-I <path>
Add the path to path list where cgen looks for input files. This option may occur more than once.

-e <expr>
Eval scheme expression. The side effects of the evaluation may be used in @if cgen directive to conditionally process code.

-v <number>
Set the verbosity level. Any positive number causes some additional information to be printed to current-error-port.

--version
cgen prints its version info and exits

--help
cgen prints its usage information and exits

The better way to learn cgen is to compile example code listed below and explore the output of cgen.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.5 Name conversions


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.5.1 Defining a type names

Among other things, cgen creates new bigloo type definitions. Each type definition requires knowing of two names: C name, i.e. the name which will be used for underlaying C object, and scheme name, which will be used in scheme code.

This names might be derived from either symbol, string or list of exactly two elements.

If it a two-element list, then the first list element (case-sensitive symbol) is used as the scheme type name , and the second list element(string or case-sensitive symbol) as the C type name.

If it is a symbol, then it is (case-sensitive) converted to string and used as described below.

If it is a string, then both type names derived from it:

The "*" string is appended to it, and the resulting string is used as C type name (for example, "GtkButton").

The corresponding scheme type name is created from C type name (without an asterisk) using the following translation:

-
The minus sign is inserted between the two adjacent letters of different case, both letters are downcased. For example, the GtkButton is converted to gtk-button, the theABCDcode becomes the-abcd-code.

-
All underscores are replaced by minuses, for example, gtk_window_new is converted to gtk-window-new.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.5.2 Defining names of an accessor

cgen allows you to automatically create a set of object accessors. The specification provides two names: a C type name and a C slot name. Then the names of each accessor are constructed using the following rules:

-
The object type name is converted as described above (for example, GtkButton is converted to gtk-button), producing a scheme object type name;

-
The slot type name is converted as described above (for example, GtkButton is converted to gtk-button), producing a scheme slot type name;

-
The slot name is converted as described above (for example, context_id is converted to context-id), producing a scheme slot name;

-
The scheme name of an accessor is a concatenation of scheme object type name with a scheme slot name suffix provided, delimited by a minus sign. For example, the procedure reading the integer slot named context_id of a structure named GtkStatusbarMsg will have a prototype:

 
(gtk-statusbar-msg-context-id::int o::gtk-statusbar-msg)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.6 Directives

Here are the cgen directives (in alphabetic order):

cgen directive: define-accessors type field-list
Add accessors to an existing type defined by define-object. The type argument is the scheme type name of the corresponding type. The field list format is that of field format of define-object directive.

cgen directive: define-boxed names #!rest directives
Currently same as define-object directive.

cgen directive: define-enum names . enum
cgen directive: define-enum-extended names . enum

Creates the new enumeration type. It takes the following arguments:

names
The first argument names defines the type name (See "Defining a type names" above").

enums

The remaining enums arguments must be two-element lists, each list representing the elements of the enumeration. The first element of each list (symbol, case-insensitive) is the scheme name of the enum, the second (string or case-sensitive symbol) is used as C name of enum element.

Each define-enum directive causes the following things to happen:

The new bigloo type is created with predicate and all the coercions necessary.

The addition conversion that coerces enum element symbolic name to enum element value

Examples:

define-enum-extended is the same as enum, but the corresponding integer enum values may be used instead of symbol to present the enum values.

cgen directive: define-flags

cgen directive: define-func namedef return-spec proto

Introduce a new interface to a C function.

Example:
 
(define-func gtk_window_get_title string((GtkWindow window)))

The namedef argument defines the C (gtk_window_get_title) and scheme (gtk-window-get-title) names of interfaced procedure. The return-spec defines C and scheme return types. The proto argument is a list of the function arguments descriptions.

The following directives all define interface to the same C procedures:

 
(define-func gtk_window_get_title string((GtkWindow window)))

;; same as above, but the Scheme name of the procedure is now explicitly
;; defined as `get-title' instead of automatically generated
;; `gtk-window-get-title'
(define-func (get-title gtk_window_get_title) string
  ((GtkWindow window)))

;; same as previous, but the C return type is `const char*' instead of
;; automatically generated `char *'
(define-func (get-title gtk_window_get_title)
  (string "const char*")
  ((GtkWindow window)))

;; same as previous, but the argument name is omitted
(define-func (get-title gtk_window_get_title)
  (string "const char*")
  ((GtkWindow)))

cgen directive: define-object

The syntax of the define-object declaration is:

<define-object> ==> ( define-object
        <names>
        ( <ancestor-list> )
        <directives>? )
<directives> ==> <free-directive> |
        <copy-directive> |
        <size-directive> |
        <conversion-directive> |
        <fields-directive> |
        <false-directive>

<fields-directive> ==> (fields  <field-decl>+ )
<false-directive> ==> (false  <value-list> ) | (false)
<free-directive> ==> (free ...)
<copy-directive> ==> (copy ...)
<size-directive> ==> (size ...)
<conversion-directive> ==> (conversion ...)

The define-object directive is used to introduce a new object type. Usually objects of that new type wrap pointers to corresponding C structures.

The false directives denotes that some values of embedded C pointer should be treated as scheme #f value. The <value-list> is the list of such values. If the <value-list> is an empty list, then a C NULL pointer will be treated as scheme #f.

The free, copy, size and conversion directives are for compatibility with guile-gtk and currently do nothing.

cgen directive: define-static name expr

The define-static directive is a convenient equivalent of Scheme define directive except that the defined name is explicitly declared as static in Bigloo module section.

cgen directive: import filename

The import directive processes the contents of file pointed by filename. The file imported may be any valid Bigloo scheme text. If the Bigloo module directive is encountered, then its contents is appended to output module section.

All other expressions are processed as if they were included literally into the file containing this import directive.

cgen directive: @if condition
cgen directive: @endif
cgen directive: @else

The @if is an equivalent of C preprocessor #if directive. All subsequent cgen directives untill matching @endif directive are processed only if the condition is met. The same directives are recognized by cgen within any list in any particular cgen directive.

For example, to compile the gtk_window_get_title function only if the version of GTK library is greater than 1.3:

 
@if (string>? gtk-version "1.3")
(define-func gtk_window_get_title
  string
  ((GtkWindow window)))
@endif

If an @else directive is encountered somewhere between @if and @endif, the condition is reversed, for example, to provide an alternate version of gtk-window-get-title for older versions of GTK:

 
@if (string>? gtk-version "1.3")

(define-func gtk_window_get_title
  string
  ((GtkWindow window)))

@else

(define(gtk-window-get-title window::gtk-window)
  (error "gtk-window-get-title"
         "function is not implemented in gtk-1.2"
          window))
@endif

It is an error if the @endif or @else directive is encountered without a matching @if directive within the list.

Also, it is an error if no @endif directive matches the @if directive within the list.

At the moment of writing, this feature is only used to conditionally compile stuff configured by autoconf.

For example, the gtk-version variable should be defined using the -e option of cgen:

 
cgen -e "(define gtk-version #t)" ...

cgen directive: module exprs

The contents of module directive is appended to module section of output cgen file. Note: this directive is optional, and it may appear in any part of input cgen file. More than one module directive is allowed.

cgen directive: register-predicate!

cgen directive: set-current-predicate!


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11.7 Usage examples

TBD


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.12 Advanced afile utility

This package includes the advanced version of afile utility (included into Bigloo bee). The list improvements made is:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13 Command-line applications support

This optional subpackage helps creating Bigloo applicatons that read input from the user a line at a time. It currently supports termios, readline (the GNU readline library API) and history (the GNU history library API).

It is compiled as an optional part of common library. To switch the compilation of this subpackage on, use --with-commandline option of configure script.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.1 Termios

These procedures control terminal attributes, terminal line, baud rate, and terminal foreground process group ID.

The description of termios parameters and function was taken mostly from that found in termios man page.

foreign type: termios

Objects of this type are pointers to to the C termios structure. They are created by make-termios procedure.

procedure: termios-iflag o::termios => iflag
procedure: set-termios-iflag! o::termios iflag

These procedures access the iflag field of the termios object, which controls the terminal input modes.

The values returned by termios-iflag or passed as iflag argument of set-termios-iflag! must be scheme lists of any of the following symbols:

ignbrk
ignore BREAK condition on input

brkint
If ignbrk is not set, generate SIGINT on BREAK condition, else read BREAK as character \0.

ignpar
ignore framing errors and parity errors.

parmrk
if ignpar is not set, prefix a character with a parity error or framing error with \377 \0. If neither ignpar nor parmrk is set, read a character with a parity error or framing error as \0.

inpck
enable input parity checking

istrip
strip off eighth bit

inlcr
translate NL to CR on input

igncr
ignore carriage return on input

icrnl
translate carriage return to newline on input (unless igncr is set)

iuclc
map uppercase characters to lowercase on input

ixon
enable XON/XOFF flow control on output

ixany
enable any character to restart output

ixoff
enable XON/XOFF flow control on input

imaxbel
ring bell when input queue is full

In this example we create a fresh termios instance, then read into it the attributes of the terminal attached to standard input, and print the value of iflag:

 
(define termios (make-termios 0))
(termios-iflag termios)
=>
(ixon icrnl)

procedure: termios-oflag o::termios => tc-oflag
procedure: set-termios-oflag! o::termios v::tc-oflag

These procedures access the oflag field of the termios object, which controls the terminal output modes.

The values returned by termios-oflag or passed as iflag argument to set-termios-oflag! must be scheme lists of any of the following symbols:

opost
enable implementation-defined output processing

olcuc
map lowercase characters to uppercase on output

onlcr
map NL to CR-NL on output

ocrnl
map CR to NL on output

onocr
don't output CR at column 0

onlret
don't output CR

ofill
send fill characters for a delay, rather than using a timed delay

ofdel
fill character is ASCII DEL. If unset, fill character is ASCII NUL

nldly
newline delay mask. Values are NL0 and NL1.

crdly
carriage return delay mask. Values are CR0, CR1, CR2, or CR3.

tabdly
horizontal tab delay mask. Values are TAB0, TAB1, TAB2, TAB3, or XTABS. A value of XTABS expands tabs to spaces (with tab stops every eight columns).

bsdly
backspace delay mask. Values are BS0 or BS1.

vtdly
vertical tab delay mask. Values are VT0 or VT1.

ffdly
form feed delay mask. Values are FF0 or FF1.

In this example we create a fresh termios instance, then read into it the attributes of the terminal attached to standard output, and print the value of the oflag field:

 
(define termios (make-termios 1))
(termios-oflag termios)
=>
(opost)

procedure: termios-cflag o::termios => tc-cflag
procedure: set-termios-cflag! o::termios v::tc-cflag

These procedures access the cflag (terminal control modes) field of the termios object.

The values returned by termios-cflag or passed as iflag argument to set-termios-cflag! must be scheme lists of any of the following symbols:

csize
character size mask. Values are CS5, CS6, CS7, or CS8.

cstopb
set two stop bits, rather than one.

cread
enable receiver.

parenb
enable parity generation on output and parity checking for input.

parodd
parity for input and output is odd.

hupcl
lower modem control lines after last process closes the device (hang up).

clocal
ignore modem control lines

cibaud
mask for input speeds (not used).

crtscts
flow control.

In this example we create a fresh termios instance, then read into it the attributes of the terminal attached to standard output, and print the value of the cflag field:

 
(define termios (make-termios 1))
(termios-cflag termios)
=> (cread csize)

procedure: termios-lflag o::termios => tc-lflag
procedure: set-termios-lflag! o::termios v::tc-lflag

These procedures access the lflag field of the termios object, which controls the terminal local modes.

The values returned by termios-lflag or passed as iflag argument to set-termios-lflag! must be scheme lists of any of the following symbols:

In this example we create a fresh termios instance, then read into it the attributes of the terminal attached to standard output, and print the value of the lflag field:

isig
when any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.

icanon
enable canonical mode. This enables the special characters EOF, EOL, EOL2, ERASE, KILL, REPRINT, STATUS, and WERASE, and buffers by lines.

xcase
if ICANON is also set, terminal is uppercase only. Input is converted to lowercase, except for characters preceded by \. On output, uppercase characters are preceded by \ and lowercase characters are converted to uppercase.

echo
echo input characters.

echoe
if ICANON is also set, the ERASE character erases the preceding input character, and WERASE erases the preceding word.

echok
if ICANON is also set, the KILL character erases the current line.

echonl
if ICANON is also set, echo the NL character even if ECHO is not set.

echoctl
if ECHO is also set, ASCII control signals other than TAB, NL, START, and STOP are echoed as ^X, where X is the character with ASCII code 0x40 greater than the control signal. For example, character 0x08 (BS) is echoed as ^H.

echoprt
if ICANON and IECHO are also set, characters are printed as they are being erased.

echoke
if ICANON is also set, KILL is echoed by erasing each character on the line, as specified by ECHOE and ECHOPRT.

flusho
output is being flushed. This flag is toggled by typing the DISCARD character.

noflsh
disable flushing the input and output queues when generating the SIGINT and SIGQUIT signals, and flushing the input queue when generating the SIGSUSP signal.

tostop
send the SIGTTOU signal to the process group of a background process which tries to write to its controlling terminal.

pendin
all characters in the input queue are reprinted when the next character is read. (bash handles typeahead this way.)

iexten
enable implementation-defined input processing.

In this example we create a fresh termios instance, then read into it the attributes of the terminal attached to standard output, and print the value of the lflag field:

 
(define termios (make-termios 1))
(termios-lflag termios)
=> (iexten echoke echoctl echok echoe icanon isig)

procedure: tcgetattr fd::int termios::termios => int

The procedure tcgetattr gets the parameters associated with the object referred by fd and stores them in the termios object. This procedure may be invoked from a background process; however, the terminal attributes may be subsequently changed by a foreground process.

For example:

 
;; Create a termios object
;; Read stdio terminal attributes
(define termios (make-termios 0))

;; Change the termios object with any of cfsetispeed, cfsetospeed,
;; tcsetpgrp or set-termios-XXX! procedures
...

;; Write it back to terminal
(tcsetattr 0 termios)

procedure: tcsetattr fd::int termios::termios #!optional (option 'now)

The procedure tcsetattr sets the parameters associated with the terminal (unless support is required from the underlying hardware that is not available) from the termios parameter. Optional option symbol specifies when the changes take effect:

now
the change occurs immediately. This is the default value.

drain
the change occurs after all output written to fd has been transmitted. This function should be used when changing parameters that affect output.

flush
the change occurs after all output written to the object referred by fd has been transmitted, and all input that has been received but not read will be discarded before the change is made.

See example in tcgetattr section.

procedure: tcsendbreak fd::int duration::int
fd duration

The procedure tcsendbreak transmits a continuous stream of zero-valued bits for a specific duration, if the terminal is using asynchronous serial data transmission. If duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds. If duration is not zero, it sends zero-valued bits for duration*N seconds, where N is at least 0.25, and not more than 0.5. If the terminal is not using asynchronous serial data transmission, tcsendbreak returns without taking any action.

procedure: tcdrain fd::int
fd

The procedure tcdrain waits until all output written to the object referred to by fd has been transmitted.

procedure: tcflush fd::int queue-selector::tcflush-selector

The procedure tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of queue-selector symbol:

input
flushes data received but not read.
output
flushes data written but not transmitted.
both
flushes both data received but not read, and written but not transmitted.

procedure: tcflow fd::int action::int
fd action

The procedure tcflow suspends transmission or reception of data on the object referred to by fd, depending on the value of action:

ooff
suspends output.

oon
restarts suspended output.

ioff
transmits a STOP character, which stops the terminal device from transmitting data to the system.

ion
transmits a START character, which starts the terminal device transmitting data to the system.

The default on open of a terminal file is that neither its input nor its output is suspended.

procedure: make-termios #!optional fd::int => termios

The procedure make-termios returns a new instance of termios. If the fd argument was given, the instance is initialized it with attributes of the terminal attached to that file descriptor.

procedure: cfmakeraw => termios

The convenience procedure cfmakeraw changes the attributes of the termios object as follows:

iflag

clear all the attributes except ignbrk, brkint, parmrk, istrip, inlcr, igncr, icrnl and ixon.

oflag
clear all the attributes except opost

lflag
clear all the attributes except echo, echonl, icanon, isig and iexten

cflag
clear all the attributes except csize and parenb. Set cs8 attribute.

procedure: cfgetospeed termios::termios => symbol
procedure: cfsetospeed termios::termios speed::symbol
procedure: cfgetispeed termios::termios => uint
procedure: cfsetispeed termios::termios speed::uint

These baud rate functions are provided for getting and setting the values of the input and output baud rates in the termios structure. The new values do not take effect until tcsetattr is successfully called.

The zero baud rate, b0, is used to terminate the connection. If b0 is specified, the modem control lines shall no longer be asserted. Normally, this will disconnect the line.

The procedure cfgetospeed returns the output baud rate stored in the termios object.

The procedure cfsetospeed sets the output baud rate stored in the termios to speed.

The procedure cfsetispeed sets the input baud rate stored in the termios object to speed. If the optional speed argument is omitted, the input baud rate will be equal to the output baud rate.

The speed must be one of these symbols: b0, b50, b75, b110, b134, b150, b200, b300, b600, b1200, b1800, b2400, b4800, b9600, b19200, b38400, b57600, b115200 or b230400

procedure: tcgetpgrp fd::int => uint
procedure: tcsetpgrp termios::termios pgrpid::uint

The procedure tcgetpgrp returns process group ID of foreground processing group.

The procedure tcsetpgrp sets process group ID to pgrpid. pgrpid must be the ID of a process group in the same session.

procedure: set-termios-cc! termios::termios what::symbol #!optional (value 0)

The procedure set-termios-cc! sets special control characters

Here are the what argument meanings and corresponding initial values:

intr
interrupt character: 0177, DEL, rubout
quit
quit character: 034, FS, Ctrl-\)
erase
erase character: 010, BS, Ctrl-H
kill
kill character: 025, NAK, Ctrl-U;
eof
end-of-file character: 004, EOT, Ctrl-D
time
min
swtc
switch character: 0, NUL
start
start character: 021, DC1, Ctrl-Q
stop
stop character: 023, DC3, Ctrl-S
susp
suspend character: 032, SUB, Ctrl-Z
eol
additional end-of-line character: 0, NUL
reprint
reprint unread characters: 022, DC2, Ctrl-R
discard
discard pending output: 017, SI, Ctrl-O
werase
word erase: 027, ETB, Ctrl-W
lnext
literal next: 026, SYN, Ctrl-V
eol2
yet another end-of-line character: 0, NUL

These symbolic subscript values are all different, except that time, min may have the same value as eol, eof, respectively. (In non-canonical mode the special character meaning is replaced by the timeout meaning. min represents the minimum number of characters that should be received to satisfy the read. time is a decisecond-valued timer. When both are set, a read will wait until at least one character has been received, and then return as soon as either min characters have been received or time time has passed since the last character was received. If only min is set, the read will not return before min characters have been received. If only time is set, the read will return as soon as either at least one character has been received, or the timer times out. If neither is set, the read will return immediately, only giving the currently already available characters.)

The value argument is coerced to an integer with the use of following rules:

If it is a character it is converted to an integer with char->integer

If it is a string, the first string character is taken, then it is converted to an integer with char->integer. The escape control sequences such as ^N (the ^ followed by uppercase letter) are also recognized.

Examples:

These equivalent expressions all attache the terminal STOP (originally attached to control-S character) operation to control-N character:

 
(set-termios-cc! termios 'stop 14)
(set-termios-cc! termios 'stop #\016)
(set-termios-cc! termios 'stop "^N")


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.2 The GNU readline library API

This section describes the interface between the GNU Readline Library and Bigloo scheme. It permits access to the features found in GNU Readline such as completionand line editing.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.3 Basic Behavior

procedure: readline #!optional prompt
prompt

The procedure readline prints a prompt prompt and then reads and returns a single line of text from the user. If prompt was omitted or the empty string, no prompt is displayed. The line returned has the final newline removed, so only the text remains. If readline encounters an EOF while reading the line, and the line is empty at that point, then #eof-object is returned. Otherwise, the line is ended just as if a newline had been typed.

For example:
 
(readline ">>> ")
-| >>> 


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.4 Custom Functions


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.5 Readline Variables

TBD


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.6 Readline Convenience Functions


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.6.1 Selecting a Keymap

Key bindings take place on a "keymap". The keymap is the association between the keys that the user types and the functions that get run. You can make your own keymaps, copy existing keymaps, and tell Readline which keymap to use.

procedure: rl-make-bare-keymap => keymap

The procedure rl-make-bare-keymap returns a new, empty keymap. The caller should free it by calling rl-discard-keymap when done.

procedure: rl-copy-keymap source::keymap => keymap

The procedure rl-copy-keymap returns a new keymap which is a copy of source.

procedure: rl-make-keymap => keymap

The procedure rl-make-keymap returns a new keymap with the printing characters bound to rl-insert, the lowercase Meta characters bound to run their equivalents, and the Meta digits bound to produce numeric arguments.

procedure: rl-discard-keymap keymap::keymap

The procedure rl-discard-keymap frees the storage associated with keymap


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.7 The GNU history library API

This section describes API to the GNU History library, a programming tool that provides a consistent user interface for recalling lines of previously typed input.

The programmer using the History library has available functions for remembering lines on a history list, associating arbitrary data with a line, removing lines from the list, searching through the list for a line containing an arbitrary text string, and referencing any line in the list directly. In addition, a history "expansion" function is available which provides for a consistent user interface across different programs.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8 Initializing History and State Management

This section describes functions used to initialize and manage the state of the History library when you want to use the history functions in your program.

procedure: using-history

Begin a session in which the history functions might be used. This initializes the interactive variables.

procedure: history-get-history-state => history-state
procedure: history-set-history-state state::history-state

Save and restore the current state of the input history.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.1 History List Management

These functions manage individual entries on the history list, or set parameters managing the list itself.

procedure: history-state entry::string

Place entry at the end of the history list.

For example:
 
(history-add "the first entry")
=>

procedure: history-remove which::int => string obj

Remove history entry at offset which from the history. Return two scheme values: the removed entry string and data object (or scheme #f the data was not set for that entry).

For example:
 
(history-clear)
(history-add "the first entry")
(history-add "the second entry")
(multiple-value-bind
      (string data)
   (history-remove 0)
   (print string)
   (print data))
-| the second entry
-| #f
(multiple-value-bind
      (string data)
   (history-remove 0)
   (print string)
   (print data))
-| "the first entry"
-| #f

procedure: history-replace
which::int line::string data::obj => string obj

Make the history entry at offset which have line and data. This returns the old entry's components. In the case of an invalid which, scheme #f value is returned.

In this example we add a new history entry replace it to another one, remove it, and try to remove a now non-existent entry:

 
(history-clear)
;; add a neww entry
(history-add "the first entry")

;; replace it by another one, set up the entry's data part
;; and print the string part of the replaced entry
(history-replace 0 "another entry" '(a b c))
=> "the first entry"

;; remove the replacement, print both the removed entry's
;; string and data parts
(multiple-value-bind
      (string data)
   (history-remove 0)
   (print string)
   (print data))
-| another entry
-| (a b c)

;; now the history is empty, so we get #f
(history-remove 0)
=> #f

procedure: history-clear

Clear the history list by deleting all the entries.

procedure: stifle-history max::int

Stifle the history list, remembering only max number of entries.

procedure: unstifle-history => int

Stop stifling the history. This returns the previous amount the history was stifled or scheme #f if the history wasn't stifled.

procedure: history-stifled? => bool

Return false if the history isn't stifled.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.2 Information About the History List

These functions return information about the entire history list or individual list entries.

procedure: history-list => pair-nil

Return the history contents as a list of pairs. Each pair consists of entry's string and data object.

For example:
 
(history-clear)
(history-add "")
(history-add "the first entry")
(history-replace 0 "the second entry" '(a b c))
=> "the first entry"
(history-list)
=> (("the second entry" a b c) ("" . #f))

procedure: history-where => int

Returns the position of the current history element (the last added entry's position, or the position explicitly set with history-set-pos!).

procedure: history-current => string obj

Return the history entry's string and data object at the current position (the last added entry position, or the position explicitly set with history-set-pos!). If there is no entry there (in a case of an empty history, for example), return #f.

For example:
 
(history-add "an entry")
(history-current)
=> "an entry"

(history-add "another one")
(history-current)
=> "another one"

(history-clear)
(history-current)
=> #f

procedure: history-get offset::int => string obj

Return the history entry at position offset, starting from the value returned by history-base. If there is no entry there, or if offset is greater than the history length, return scheme #f.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.3 Moving Around the History List

procedure: history-set-pos! pos::int => bool

Set the current history offset to pos, an absolute index into the list. Returns #f if pos is less than zero or greater than the number of history entries.

procedure: previous-history => hist-entry

Back up the current history offset to the previous history entry, and return that entry's string and data. If there is no previous entry, return #f.

procedure: next-history => hist-entry

Move the current history offset forward to the next history entry and return that entry's string and data. If there is no next entry, return #f.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.4 Searching the History List

These functions allow searching of the history list for entries containing a specific string. Searching may be performed both forward and backward from the current history position. The search may be "anchored", meaning that the string must match at the beginning of the history entry.

procedure: history-search string::string #!optional backward?

Search the history for string, starting at the current history offset. If backward? is true, then the search is through previous entries, otherwise through subsequent entries. If string is found, then the current history index is set to that history entry, and the value returned is the offset in the line of the entry where string was found. Otherwise, nothing is changed, and #f is returned.

procedure: history-search-prefix string::string #!optional backward?

Same as history-search, but lines that begin with string are searched for.

procedure: history-search-pos string::string #!optional backward? pos

Search for string in the history list, starting at pos, an absolute index into the list. If backward? is true, the search proceeds backward from pos, otherwise forward. Returns the absolute index of the history element where string was found, or #f otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.5 Managing the History File

The History library can read the history from and write it to a file. This section documents the functions for managing a history file.

procedure: history-read #!optional filename from to

Add a range of lines from filename to the history list, a line at a time. If filename is missing, then read from `~/.history'. Start reading at line from and end at to. If from argument is missing, then read from the beginning of the file. If to is missing, then read up to the end of the file.

procedure: history-write filename::string => int

Write the current history to filename, overwriting filename if necessary. If filename argument is missing, then write the history list to `~/.history'.

procedure: history-append nelements::int filename::string => int

Append the last nelements of the history list to filename. If filename argument is missing, then append to `~/.history'.

procedure: history-truncate-file filename::string lines::int => int

Truncate the history file filename, leaving only the last lines. If filename argument is missing, then `~/.history' is truncated.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.6 History Expansion

These functions implement history expansion. See the History documentation for the expansion details.

procedure: history-expand s::string

Expand string. Returns:

#f

If no expansions took place (or, if the only change in the text was the removal of escape characters preceding the history expansion character);

expanded string
If expansions did take place;

a list with the expanded string

If the returned line should be displayed, but not executed, as with the :p modifier.

An error is signaled, if an error ocurred in expansion.

For example:
 
(history-clear)
(history-add "the first entry")
(history-expand "!!")
=> "the first entry"

procedure: history-arg-extract string::string !#optional first last => pair-nil

Extract the args specified, starting at first, and ending at last. The args are taken from string. If either first or last is < 0, then make that arg count from the right (subtract from the number of tokens, so that first = -1 means the next to last token on the line). If last is omitted the last arg from string is used.

For example:
 
(history-arg-extract "one two three")
=> "one two three"

(history-arg-extract "one two three" 1)
=> "two three"

(history-arg-extract "one two three" 1 1)
=> "two"

(history-arg-extract "zero one two three")
=> "zero one two three"

(history-arg-extract "zero one two three" 2)
=> "two three"

(history-arg-extract "zero one two three" 2 3)
=> "two three"

procedure: history-get-event s::string delimiting-quote::char

The procedure history-get-event

For example:
 
=>

procedure: history-tokenize string::string => pair-nil

Return an array of tokens parsed out of string, much as the shell might. The tokens are split on the characters in the history-word-delimiters, and shell quoting conventions are obeyed.

For example:
 
(history-tokenize "zero one two three")
=> ("zero" "one" "two" "three")


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.7 History Variable wrappers

TODO


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.13.8.8 History Programming Example

The following is a tiny command line utility which reads user inputs, expand the lines and demonstrates some history-related commands: history-write, history-read, history-list and history-remove.

 
(module test
   (library common)
   )
     
(history-init)
(let loop ()
   (display "history$ ")
   (let((line(read-line)))
     (unless(eof-object? line)
	    (let((result(history-expand line)))
	      (when(string? result)
		   ;; line was expanded
		   (print result)
		   (set! line result))
	      (unless (pair? result)
		      (history-add line)
		      (read/rp (regular-grammar
			()
			("save"
			 (history-write "history-file"))
			("read"
			 (history-read "history-file"))
			("list"
			 (let loop((the-list(history-list))
				   (i (history-base)))
			   (when(pair? the-list)
				(print i ": "(caar the-list))
				(loop(cdr the-list)
				     (+fx i 1)))))
			((: "delete" (+ blank)(submatch (+ digit)))
			 (let((no(string->number (the-submatch 1))))
			   (unless(history-remove no)
				  (print "No such entry " no)))))
		       (open-input-string line))))
	    (loop))))
	 


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Vladimir Tsichevski on December, 26 2003 using texi2html