[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
The procedures described here, are intended for end-user applications. They are compatible to those provided by MzScheme.
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") => () |
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
:
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.
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 |
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.
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] | [ ? ] |
Procedures described here are direct interfaces to corresponding C runtime calls. You woudn't want to use them in end-user applications.
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) :
regex(7)
for details.
regexec
searches using this
pattern buffer will be case insensitive (2).
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
.
Given the error code, returned by regcomp
or regexec
,
return the error description.
(regerror 'erange (regexp " ")) => "invalid endpoint in range" |
Free the memory allocated to the rexp by the regcomp
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
The procedure gdbm-open
opens or creates gdbm
database file filename.
The parameters are:
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.
block-size
is used.
chmod(2)
and open(2)
man pages) if the file
is created).
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)) |
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] | [ ? ] |
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" => |
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 |
Look up the data associated with the key. Return the data string
found or #f
if the key wasn't found in a database.
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] | [ ? ] |
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] | [ ? ] |
Try to shrink the database after multiple deletions were done. See GDBM documentation for details.
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
.
The procedure gdbm-setopt
sets certain options on an already open
database. The valid options are:
gdbm
descriptor, and is set automatically to 100
upon the first access to the database.
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.
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) |
The procedure gdbm-fdesc
returns the file descriptor of the database.
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] | [ ? ] |
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"))) |
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 |
Means nothing in bigloo-lib
.
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.
Aliases Bigloo directory?
procedure
Create the new directory path with access mask mask. The default value of mask is #o0777.
Get or set the application process current directory.
(current-directory) => /usr/local/bin (current-directory "/home/wowa") => #unspecified (current-directory) => /home/wowa |
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] | [ ? ] |
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] | [ ? ] |
An open shared object handle as returned by dlopen
A symbol object as returned by dlsym
.
A set of possible values for the mode argument of dlopen
procedure.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
TBD
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
TBD
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Bigloo-lib
provides a limited support for string-lib
, the
SRFI-13 string library. The limitations are as follows:
string-compare
,
string-compare-ci
(really I did not understand the specification).
The rest of this chapter is based mostly on original SRFI document, copyrighted by Olin Shivers.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the following procedure specifications:
s
parameter is a string.
char
parameter is a character.
start
and end
parameters are half-open string indices
specifying a substring within a string parameter; when optional, they
default to 0 and the length of the string, respectively. When specified,
it must be the case that 0 <= start
<= end
<=
(string-length S), for the corresponding parameter s
. They
typically restrict a procedure's action to the indicated substring.
pred
parameter is a unary character predicate procedure, returning a
true/false value when applied to a character.
char/char-set/pred
parameter is a value used to select/search for a
character in a string. If it is a character, it is used in an equality
test; if it is a character set, it is used as a membership test; if it
is a procedure, it is applied to the characters as a test predicate.
i
parameter is an exact non-negative integers specifying an index
into a string.
len
and nchars
parameters are exact non-negative integers specifying a
length of a string or some number of characters.
Passing values to procedures with these parameters that do not satisfy these types is an error.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Is s
the empty string?
(string-null? "") => #t |
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
.
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] | [ ? ] |
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] | [ ? ] |
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) |
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.)
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.
'infix
means an infix or separator grammar: insert the delimiter
between list elements. An empty list will produce an empty string --
note, however, that parsing an empty string with an infix or separator
grammar is ambiguous. Is it an empty list, or a list of one element,
the empty string?
'strict-infix
means the same as 'infix
, but will raise an error if given an
empty list.
'suffix
means a suffix or terminator grammar: insert the delimiter after every list element. This grammar has no ambiguities.
'prefix
means a prefix grammar: insert the delimiter before every list element. This grammar has no ambiguities.
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] | [ ? ] |
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" |
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:
end
parameter is optional, not required.
substring/shared
may return a value that shares memory with s
or
is eq?
to s
.
Example:
(let((s "Beta substitution")) (eq?(substring/shared s 0)s)) => #t |
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" |
string-take
returns the first nchars
of 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--> |
string-drop
returns all but the first nchars
of 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--> |
string-take-right
returns the last nchars
of 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" |
(string-take-right "foo" 37) error--> |
string-drop-right
returns all but the last nchars
of 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 " |
(string-drop-right "foo" 37) error--> |
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" |
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" |
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
are
trimmed;
pred
, it is a test predicate that is applied
to the characters in s; a character causing it to return true is
skipped.
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" |
See description of string-trim
.
Example:
(string-trim-right #" The outlook wasn't brilliant, \n\r") => #" The outlook wasn't brilliant," |
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] | [ ? ] |
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] | [ ? ] |
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))
Test strings for equality. See notes at the beginning of this section.
Test strings for inequality. See notes at the beginning of this section.
Test if s1
string is less than s2
string. See notes at the
beginning of this section.
Test if s1
string is greater than s2
string. See notes at the
beginning of this section.
Test if s1
string is less than or equal to s2
string. See
notes at the beginning of this section.
Test if s1
string is greater than or equal to s2
string. See
notes at the beginning of this section.
Test strings for equality case-insensitive. See notes at the beginning of this section.
Test strings for inequality case-insensitive. See notes at the beginning of this section.
Test if s1
string is less than s2
string
case-insensitive. See notes at the beginning of this section.
Test if s1
string is greater than s2
string
case-insensitive. See notes at the beginning of this section.
Test if s1
string is less than or equal to s2
string
case-insensitive. See notes at the beginning of this section.
Test if s1
string is greater than or equal to s2
string
case-insensitive. See notes at the beginning of this section.
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)) |
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] | [ ? ] |
Return the length of the longest common prefix of the two strings.
This is equivalent to the "mismatch index" for the strings (modulo
the start
i 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 |
Return the length of the longest common suffix of the two strings.
This is equivalent to the "mismatch index" for the strings (modulo
the start
i 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 |
Case-insensitive variant of string-prefix-length
.
Case-insensitive variant of string-suffix-length
.
Is s1
a prefix of s2
?
Example:
(string-prefix? "qwerty" "qwertyasdf" => #t |
Is s1
a suffix of s2
?
Example:
(string-prefix? "qwerty" "asdfqwerty" => #t |
Case-insensitive variant of string-prefix?
.
Case-insensitive variant of string-suffix?
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
string-index
searches through the string from the left, returning
the index of the first occurrence of a character which
char/char-set/pred
(if it is a character);
char/char-set/pred
(if it is a character set);
char/char-set/pred
(if it is a procedure).
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.
string-index-right
searches through the string from the right,
returning the index of the first occurrence of a character which
char/char-set/pred
(if it is a character);
char/char-set/pred
(if it is a character set);
char/char-set/pred
(if it is a procedure).
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
.
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. ...))) |
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.
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
The setenv
procedure makes the value of the environment variable
name equal to value by altering an existing variable or
creating a new one.
The unsetenv
procedure function deletes the variable name from the
environment.
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 |
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
mmap
result is returned in
form of Bigloo bstring
, the length really passed to libc
mmap()
includes the bstring
object overhead too.
#!key fd
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
exec
read
write
none
#!key flags
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
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 |
Release memory mapped by mmap
.
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
stat-uid
stat-gid
stat-size
stat-atime::double
stat-mtime::double
stat-ctime::double
The meaning of abovementioned stat-mode flag list is as follows:
fsock
=> file is a socketflnk
=> file is a symbolic linkfreg
=> file is a regular filefblk
=> file is a block devicefdir
=> file is a directoryfchr
=> file is a character devicefifo
=> file is a fifosuid
=> file has the UID bit setsgid
=> file has the GID bit setsvtx
=> file has the sticky bit setrusr
=> file owner has read permissionwusr
=> file owner has write permissionxusr
=> file owner has execute permissionrgrp
=> file group has read permissionwgrp
=> file group has write permissionxgrp
=> file group has execute permissionroth
=> file others have read permissionwoth
=> file others have write permissonxoth
=> 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 |
Test for a terminal device. Argument what should be open file descriptor. Example:
(isatty(open "/dev/tty")) => #t (isatty(open "/etc/passwd")) => #f |
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 |
Close a file descriptor, so that it no longer refers to any file and may be reused.
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.
Try to write the str to specified file descriptor. Return the number of bytes really wrote.
getppid
returns the process ID of the parent of the current
process.
getpid
returns the process ID of the current process. (This is
often used by routines that generate unique temporary file names.)
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$ |
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:
string
)
integer
)
integer
)
string
)
string
)
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" |
cuserid
procedure generates a character-string representation
of the login name under which the owner of the current process is logged
in.
(cuserid) => wowa |
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" |
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" |
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" |
char->hex
prints character c to hexadecimal string, for
example:
(char->hex #\newline) => "0a" |
string->hex
prints string str using char->hex
conversion, for example:
(string->hex "Hello") => "48656c6c6f" |
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" |
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" ... ) |
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] | [ ? ] |
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
.
The structure holding the information about the source and target character sets and current state of conversion.
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> |
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
.
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) |
Release the cd object and all related resources.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
A wrapper for C library struct tm
structure, broken-down time
representation.
The following read accessors are defined:
See also strftime
procedure description to print these objects in
human-readable form.
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.
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 |
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
.
Return number of seconds west of UTC. For example, here in Moscow:
(timezone) => -10800 (/ (timezone) 3600) => -3 |
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 |
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.
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" |
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 |
Defined as:
(define(current-milliseconds::double) (* (current-seconds) 1000.0)) |
Interface for ctime_r
C runtime procedure. Return 26-character
string with fixed-format time representation, for example:
Constructor for objects of tm
type. The arguments are:
Example:
(strftime(mktime 1960 12 27)) => "12/27/60 00:00:00" |
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" |
The times
procedure measures various time-accounting information.
Depending on value of argument which? of symbol
type it
returns the following values:
utime
stime
cutime
cstime
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 |
Print time argument in UTC time format.
(tm->utctime(localtime(current-seconds))) => 20000531123949Z |
(strftime(utctime->tm "20000531123949Z")) => 05/31/00 12:39:49 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section describes cgen
-- the utility for creating bigloo
interfaces to C libraries.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
In course of evaluation of the foreign interface, I found it not always suitable for the following reasons :
inline
, their body is
copied into every module that uses it.
cgen
is, on the
other hand, quite simple and open-ended. It is not hard to change it
without risk to broke the whole compiler.
cgen
is readable scheme text. When something goes
not as expected, you can easily check that's going on. Bigloo, in its
turn, does similar thing while compiling the foreign
and
extern
module clauses, i.e. it creates and compiles the low-level
scheme type expressions, but it never reveals the intermediate code to
the programmer.
cgen
was developed in hope to achieve the following goals:
cgen
creates write accessor for C structure
slots only if you specify that directly.
cgen
lets bit fields be presented
in scheme in form of lists of symbols.
#f
value.
GTK+
interface 8. GTK+ interface compatible with guile-gtk
(http://www.gtk.org). Using the interface specifications from
guile-gtk
saved me much work. The main idea and specification
file format came from guile-gtk
also.
cgen
are exported automatically, they may form bigloo library,
and may be visible in interpreter.
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] | [ ? ] |
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] | [ ? ] |
Typically cgen
is used in this form:
cgen -o <outfile> file1 [file2] ... |
The other options are:
-o <filename>
cgen
uses current-error-port
if this option is not used.
-I <path>
cgen
looks for input files. This
option may occur more than once.
-e <expr>
@if
cgen directive to conditionally
process code.
-v <number>
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] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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:
GtkButton
is
converted to gtk-button
, the theABCDcode
becomes
the-abcd-code
.
gtk_window_new
is converted to gtk-window-new
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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:
GtkButton
is converted to gtk-button
), producing a scheme
object type name;
GtkButton
is converted to gtk-button
), producing a scheme
slot type name;
context_id
is converted to context-id
), producing a scheme
slot name;
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] | [ ? ] |
Here are the cgen
directives (in alphabetic order):
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.
define-object
directive.
Creates the new enumeration type. It takes the following arguments:
names
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:
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.
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))) |
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.
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.
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.
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)" ... |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
TBD
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This package includes the advanced version of afile
utility
(included into Bigloo bee
). The list improvements made is:
-I
added. The arguments of each -I
option form file search path. So output of
afile -I ../compat -I ../node compat.scm node.scm |
now looks like
;; /jet/tmp/bigloo-lib-0.11/common ;; Wed Apr 12 14:08:55 2000 ((compat #"../compat/compat.scm") (node #"../node/node.scm")) |
Note that the current directory is automatically added to search path
only if no any -I
option is given. Also note the required space
between the -I
and filename.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
The description of termios
parameters and function was taken
mostly from that found in termios
man page.
Objects of this type are pointers to to the C termios
structure. They are created by make-termios
procedure.
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
brkint
ignbrk
is not set, generate SIGINT on BREAK condition, else
read BREAK as character \0.
ignpar
parmrk
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
istrip
inlcr
igncr
icrnl
igncr
is
set)
iuclc
ixon
ixany
ixoff
imaxbel
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) |
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
olcuc
onlcr
ocrnl
onocr
onlret
ofill
ofdel
nldly
crdly
tabdly
bsdly
vtdly
ffdly
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) |
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
cstopb
cread
parenb
parodd
hupcl
clocal
cibaud
crtscts
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) |
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
icanon
xcase
echo
echoe
echok
echonl
echoctl
echoprt
echoke
flusho
noflsh
tostop
pendin
iexten
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) |
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) |
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
drain
flush
See example in tcgetattr
section.
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.
The procedure tcdrain
waits until all output written to the
object referred to by fd has been transmitted.
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
output
both
The procedure tcflow
suspends transmission or reception of data on the
object referred to by fd, depending on the value of action:
ooff
oon
ioff
ion
The default on open of a terminal file is that neither its input nor its output is suspended.
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.
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
opost
lflag
echo
, echonl
,
icanon
, isig
and iexten
cflag
csize
and parenb
. Set
cs8
attribute.
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
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.
The procedure set-termios-cc!
sets special control characters
Here are the what argument meanings and corresponding initial values:
intr
quit
erase
kill
eof
time
min
swtc
start
stop
susp
eol
reprint
discard
werase
lnext
eol2
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] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
The procedure rl-make-bare-keymap
returns a new, empty
keymap. The caller should free it by calling rl-discard-keymap
when done.
The procedure rl-copy-keymap
returns a new keymap
which is
a copy of source.
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.
The procedure rl-discard-keymap
frees the storage associated with
keymap
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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.
Begin a session in which the history functions might be used. This initializes the interactive variables.
Save and restore the current state of the input history.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions manage individual entries on the history list, or set parameters managing the list itself.
Place entry at the end of the history list.
For example:
(history-add "the first entry") => |
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 |
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 |
Clear the history list by deleting all the entries.
Stifle the history list, remembering only max number of entries.
Stop stifling the history. This returns the previous amount the history
was stifled or scheme #f
if the history wasn't stifled.
Return false if the history isn't stifled.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions return information about the entire history list or individual list entries.
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)) |
Returns the position of the current history element (the last added
entry's position, or the position explicitly set with
history-set-pos!
).
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 |
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] | [ ? ] |
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.
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
.
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] | [ ? ] |
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.
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.
Same as history-search
, but lines that begin with string
are searched for.
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] | [ ? ] |
The History library can read the history from and write it to a file. This section documents the functions for managing a history file.
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.
Write the current history to filename, overwriting filename
if necessary. If filename
argument is missing, then write the
history list to `~/.history'.
Append the last nelements of the history list to filename.
If filename
argument is missing, then append to `~/.history'.
Truncate the history file filename, leaving only the last lines. If filename
argument is missing, then `~/.history' is truncated.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions implement history expansion. See the History
documentation for the expansion details.
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);
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" |
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" |
The procedure history-get-event
For example:
=> |
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] | [ ? ] |
TODO
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |