11. WORD GLOSSARY

The word glossary is the core of Forth documentation. No program is complete without it. Until is no exception. This chapter has a complete word glossary and several smaller, specialized glossaries on specific subject areas, such as files. The main word glossary contains the word descriptions and the specific glossaries contains complete code examples.


Notational Conventions

Each glossary entry first line contains the word name and the stack comment. Short examples are included in many cases. Word pronunciation is enclosed in double quotes at the start of the description. A stack comment is enclosed in parens:

      ( input --- result )

The "---" represents the action of the word. Input and result can be:

      ( 'string --- )

is pronounced address of string.

S-Engine Words

This section identifies the words that are specific to the S-Engine SGML document interpreter. It is not included in this manual.


append_this
( 'string --- )
"append-this". Append the string whose address is on the top of the stack to the current SGML buffer.
   " this is a test" append_this

clear_read
( --- )
"clear-read". Resets the current SGML input buffer, this_field, to a small scratch buffer. It cannot be simply set to zero just in case more data is collected.
read_into
( 'string --- )
"read-into". Set SGML input buffer pointer to the string whose address is on the top of the stack. SGML input will be collected into this buffer until changed. It is very important that the allocate length of 'string be long enough to hold the text being collected into it.
   500 string trash
   ...
   trash read_into

sengine
( --- )
"s-engine". Interpret the SGML document opened by a previous call to sengine-init. Each SGML tag is extracted then executed.
sengine_init
( 'SGML-file --- )
"s-engine-init". Open the SGML file whose name is specified by the string whose address in on the parameter stack. The SGML filename can be passed as a string:
   " anyfile.sgm" sengine_init

this_field
( --- 'string )
"this-field". The current SGML input buffer is this_field. It is normally set by read_into. All text up to the next SGML tag is collected in the buffer pointed to by this_field.

S-ENGINE EXAMPLE

The previous section describes the processing mechanisms of S-Engine. This section describes a simple, but complete S-Engine application. The file, ADDRESS.DTD, is an SGML Document Type Definition (DTD) that describes an address book document. It describes the structure of and markup (elements) that appear in the SGML instance (document) for an address document type.

The file ADDRESS.SGM is a document instance. It is a valid SGML file that can be validated using an SGML parser and ADDRESS.DTD. That level of SGML processing is beyond the scope of this manual. Here we are only interested in processing ADDRESS.SGM with S-Engine.

The example S-Engine program, ADDRESS.APP, converts the SGML file, ADDRESS.SGM, to HTML suitable for viewing on a Web Server with Mosaic or NetScape. ADDRESS.HTM is also a valid SGML file that is described by a DTD and can be validated or processed with any SGML tool.

The overall strategy of the program is to collect text for a complete address record, then process the text when and end of record tag (</entry>) executes.

The file structure is straight forward. The entire file is wrapped up by the address tags, <address> and </address>. Each address record is wrapped by the entry tags, <entry> and </entry>. This SGML design allows the wrapper tags to be used as "triggers" to initiate processing at defined points in the file.

The ADDRESS.APP code contains comments with Section numbers that correspond to the descriptions that follow.

One of the beauties of SGML is the structure defined by the element tags can be used to key processing from.

Here is the code for ADDRESS.APP:

\ Address book - S-Engine Demo
\ ====================================================================
\				SECTION 1
\ ====================================================================

variable fd.out

10   constant <nl>

4096 string out.buf

\ ====================================================================
\				SECTION 2
\ ====================================================================
80 string name
32 string bphone
32 string aphone
32 string hphone
32 string fax
80 string title
80 string category
80 string company
80 string addr1
80 string addr2
80 string city
80 string st
16 string zip
4096 string note
\ ====================================================================
\				SECTION 3
\ ====================================================================
: clear		( address --- )
   0 swap c!
   ;
: -newline		( 'string --- )
   dup strlen + 1- 		\ Calc address
   dup c@ <nl> =		\ Compare last char to newline
   if
     0 swap c!			\ yes, trash it
   else
     drop
   endif
   ;
: output.line		( ?? 'string --- )
   fd.out @ fprintf 
   ;
: msg 		 ( 'string --- )
   dup strlen type
   ;
\ ====================================================================
\				SECTION 4
\ ====================================================================
: clear.fields		( --- )
   name clear      bphone clear 
   aphone clear    hphone clear 
   fax clear       title clear 
   category clear  company clear 
   addr1 clear     addr2 clear 
   city clear      st clear 
   zip clear       note clear 
   ;
: setup.HTML
   " <HTML>\n"   output.line
   " <HEAD><TITLE>SGML Address Book</TITLE></HEAD>\n" 
output.line
   " </HEAD>\n"  output.line
   " <BODY>\n"   output.line
   ;
: process.name
   " <HR>\n" output.line
   name strlen 0>
   if    ( There is a name field )
      out.buf name strcpy
   else  ( use the company name  )
      out.buf company strcpy
      company clear
   endif 
   out.buf output.line
   ;
: process.phones
   " <DL>\n" output.line
   bphone strlen 0>
   if    bphone " <DT>Bus.: <DD>%s\n" output.line  endif
   hphone strlen 0>
   if    hphone " <DT>Home: <DD>%s\n" output.line  endif
   fax strlen 0>
   if    fax    " <DT>Fax : <DD>%s\n" output.line  endif
   aphone strlen 0>
   if    aphone " <DT>Alt : <DD>%s\n" output.line  endif
   " </DL>\n" output.line
   ;
: process.the.rest
   " <P>\n"   output.line
   title   strlen 0>   if title   " %s<BR>\n" output.line endif
   company strlen 0>   if company " %s<BR>\n" output.line endif
   addr1   strlen 0>   if addr1   " %s<BR>\n" output.line endif
   addr2   strlen 0>   if addr2   " %s<BR>\n" output.line endif
   city    strlen 0>
   if 
     city st zip " %s, %s  %s<BR>\n" output.line
   endif
   note    strlen 0>   if note    " <P>\n%s<BR>\n" output.line
endif
   clear.fields
   ;
\ ====================================================================
\				SECTION 5
\ ==================================================================== 
: <ADDRESS>
   cr ." The SGML-based Address Book" cr cr
   " address.htm"  WRITE fopen
   fd.out !
   setup.HTML
   clear.fields
   ;
: </ADDRESS> 
   " </BODY>\n"  output.line
   " </HTML>\n"  output.line
   fd.out @ fclose
   ;

: <ENTRY> ;
: </ENTRY>
   process.name
   process.phones
   process.the.rest
   ;

\ ====================================================================
\				SECTION 6
\ ====================================================================
: <NAME>	name read_into    ;
: </NAME>	name -newline   
name msg cr ;

: <BPHONE>	bphone read_into  ;
: </BPHONE>	bphone -newline ;

: <APHONE>	aphone read_into  ;
: </APHONE>	aphone -newline ;

: <HPHONE>	hphone read_into  ;
: </HPHONE>	hphone -newline ;

: <FAX> 	fax read_into     ;
: </FAX>	fax -newline    ;

: <TITLE>	title read_into   ;
: </TITLE>	title -newline  ;

: <CATEGORY>	category read_into  ;
: </CATEGORY>	category -newline ;

: <COMPANY>	company read_into   ;
: </COMPANY>	company -newline  ;

: <ADDR1>	addr1 read_into     ;
: </ADDR1>	addr1 -newline    ;

: <ADDR2>	addr2 read_into     ;
: </ADDR2>	addr2 -newline    ;

: <CITY>	city read_into      ;
: </CITY>	city -newline     ;

: <ST>		st read_into        ;
: </ST>		st -newline       ;

: <ZIP>		zip read_into       ;
: </ZIP>	zip -newline      ;

: <NOTE>	note read_into      ;
: </NOTE>	note -newline     ;
\ ====================================================================
\				SECTION 7
\ ====================================================================
: &		" &" ;
: <		" <" ;
: >		" >" ;

" address.sgm" sengine_init
sengine


File I/O Words

The set of file words implemented in Until follows C conventions. In fact, most of the words use the same names as the equivalent C functions. If there are questions about calling sequences, refer to a C function reference manual. The code for the words documented here is found in FILE.C. The way each of these words operates is to collect the arguments from the stack, then call the corresponding C function. The Until word, errno returns the value of the C global variable errno. Any questions about word behavior can be answered by looking up the equivalent C function in the C compiler documentation. A file descriptor is the result of a call to fopen. The file descriptor is indicated by fd. The file related words are:


fclose
( fd --- )
"f-close". Close the file whose file descriptor is fd.
      " test.fil" READ fopen  descriptor !
        ...
      descriptor @ fclose

fcr
( fd --- status )
"f-c-r". Write a carriage return (well actually a newline) to the output file specified by fd.
      descriptor @ fcr

feof
( fd --- 0|eof )
"f-e-o-f". Test the specified stream, fd, for end of file. A zero return means not at EOF. Eof is returned if the last file operation encountered end of file.
  descriptor @ feof
        if   ." Got eof"
        else ." Not eof" then

ferror
( fd --- tf )
"f-error". This word tests the file stream for read or write error. FALSE means no error and TRUE indicates an error has occurred.
        descriptor @ ferror
        if   ." File error"
        else ." No error" endif

fflush
( fd --- )
"f-flush". This word flushes the system output buffer for the file specified by fd. The file must have been opened previously by a call to fopen.
        descriptor @ fflush

fgetc
( fd --- c )
"f-get-c". Read the next character from the file specified by the file descriptor fd. The value is true (-1) on End of File.
        descriptor @ fgetc

fgets
( addr size fd --- count )
"f-get-s". Read the next string of a max length of size into the buffer at addr from file fd. The count is the number of bytes actually read or 0 for End of File. A "string" is logically a line in the file. The trailing newline character is included in the result string. fgets reads up to the new line character.
        buffer size descriptor @ fgets
        0= if ." EOF" then
Note that buffer is a counted string. The trailing <newline> is included in the buffer and a trailing NULL is included so buffer may be treated as either a NULL terminated or counted string. The string size is meaningless when the buffer is greater than 255 bytes.
fnsplit
( 'filename --- 'drive 'dir 'file 'ext )
"f-n-split". Break the filename contained in the string whose address is on the top of the stack into its component parts.
        " c:\until\outer.c" fnsplit
        .( Extension> ) dup strlen type cr
        .( File     > ) dup strlen type cr
        .( Dir      > ) dup strlen type cr
        .( Drive    > ) dup strlen type cr

fopen
( 'filename 'fmode --- fd )
"f-open". Open the file whose name is stored in 'filename and has a fmode of BINARY, READ, WRITE, or APPEND. The file descriptor, fd, should be saved and is used by most of the other file words to refer to the file.
      " name" READ fopen

The predefined modes are:


fprintf
( a1 a2 ... an 'format fd --- )
"f-print-f". This is the C fprintf() function. The top of the stack contains a file descriptor, fd, followed by the format string, 'format. 'format is a C fprintf() format string such as:
   " A string: %s  or a decimal number: %d"
The arguments to fprintf are in the order used. For example:
   " string" 65 " A string: %s  or a decimal number: %d\n" fd @ fprintf
will write:
   A string: string  or a decimal number: 65
with a trailing newline character to the file descriptor fd. The first argument goes with the first format specifier (" string" and the %s) and the second argument goes with the second format specifier (65 and %d) in this case.

Note that floating point values cannot be used with fprintf. Use fprintf_f to output floating point values.


fprintf_f
( a1 a2 ... an 'format fd --- )
"f-print-f-underscore-f". This is the C fprintf() function. fprintf_f can only be used to out floating point values. The top of the stack contains a file descriptor, fd, followed by the format string, 'format. 'format is a C fprintf() format string such as:
   " A floating point number: %e"
The arguments to fprintf_f are in the order used. For example:
   f# 123.456 " A floating point number: %e\n" fd @ fprintf_f
will write:
   A floating point number: 123.4560
with a trailing newline character to the file descriptor fd. The first argument goes with the first format specifier (123.456 and the %e).

Note that only floating point values can be used with fprintf_f. Use fprintf to output other values.


fputc
( ch fd --- status)
"f-put-c". Write the character, ch, to the file whose descriptor is fd. The status of the write is returned. The status is either the character on a successful write or EOF on error.
fputline
( 'string fd --- status )
"f-put-line". Write the string whose address is next to the top of the parameter stack to the file whose file descriptor, fd, is on the top of the stack. A <newline> is appended to the string before being written. status is EOF when an error occurs. (See fcr).
fputs
( 'buffer fd --- status )
"f-put-s". Write the string whose address is specified by buffer to the file descriptor, fd. status is the last character written on success or EOF on error.
fread
( addr len fd --- status )
"f-read". Read a block of data from a disk file. This word eventually calls fread(). It reads len bytes into the buffer that starts at addr. The status is the number of bytes read on success or zero for end of file.
fseek
( whence offset fd --- status)
"f-seek". This word positions the file, fd, to the offset specified by offset. The offset is not necessarily the relative number of bytes from the beginning of the file. whence can be:
  0 Beginning of the file (SEEK_SET)
  1 From the current file position (SEEK_CUR)
  2 End of the file (SEEK_END)
The status is zero on success and non-zero on error. DOS only returns an error when attempting to position a file that has not been opened. Other operating systems may return additional errors.
ftell
( fd --- offset)
"f-tell". Return the file offset for the file specified by fd. An offset of -1 indicates an error. Most C compilers return the number of bytes from the beginning of the file, but this is not guaranteed!
fwrite
( addr len fd --- status )
"f-write". Calls the C function fwrite(). It writes the buffer at addr for a length of len bytes to the file specified by fd. Status is the number of bytes written or zero for an error. fwrite writes from the current position in the file.
printf
( a1 a2 ... an 'format fd --- )
"print-f". This is the C printf() function. The top of the stack contains a format string, 'format. 'format is a C printf() format string such as:
   " A string: %s  or a decimal number: %d"

The arguments to printf are in the order used. For example:

   " string" 65 " A string: %s  or a decimal number: %d\n" printf

will write:

   A string: string  or a decimal number: 65

with a trailing newline character to STDOUT. The first argument goes with the first format specifier (" string" and the %s) and the second argument goes with the second format specifier (65 and %d) in this case.

Note that floating point values cannot be used with printf. Use printf_f to output floating point values.


printf_f
( f1 f2 ... an 'format --- )
"print-f-underscore-f". This is the C printf() function. printf_f can only be used to out floating point values. The top of the stack contains a format string, 'format. 'format is a C printf() format string such as:
   " A floating point number: %e"
The arguments to printf_f are in the order used. For example:
   f# 123.456 " A floating point number: %e\n" printf_f
will write:
   A floating point number: 123.4560
with a trailing newline character to STDOUT. The first argument goes with the first format specifier (123.456 and the %e).

Note that only floating point values can be used with printf_f. Use printf to output other values.


SEEK_CUR
( --- 1 )
"seek-cur". Sets seek mode relative to the current file position. Use with fseek.
SEEK_END
( --- 2 )
"seek-end". Sets seek mode relative to end of file. Use with fseek.
SEEK_SET
( --- 0 )
"seek-set". Sets seek mode to beginning of the file. Used with fseek.

Table of Contents
Next Section