home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-09-21 | 9.5 KB | 289 lines | [TEXT/ALFA] |
- \
- \
- \ PF Forms Handler Shell -- version 1.1
- \
- \
- \ (c) Ronald T. Kneusel, 1995
- \ (rkneusel@post.its.mcw.edu)
- \
- \ This code may be used and distributed freely provided the copyright
- \ notice remains intact and my name is mentioned in the documentation.
- \
- \ Last mod: 21-Sep-95
- \ =========================================================================
- \
- \ Provides a shell for writing CGI applications for use with WebSTAR. The
- \ shell will handle all communication between WebSTAR and the CGI. It also
- \ provides a vocabulary for extracting the information presented by WebSTAR.
- \
- \
- \ @Field ( addr1 addr2 new|append -- )
- \
- \ Get the post data string for the field whose address is
- \ on the stack. Place the data into the string at addr2. @Field
- \ will convert characters as necessary.
- \
- \ @Addr ( addr new|append -- )
- \
- \ Put the client's IP address in the string at addr
- \
- \ @Direct ( addr new|append -- )
- \
- \ Put the direct argument in the string at addr
- \
- \ @Browser ( addr new|append -- )
- \
- \ Put the browser type in the string at addr
- \
- \ REPLY ( addr -- )
- \
- \ Send the string back to WebSTAR. Use only within ae: ... ;ae
- \
-
-
- ( *************************** String Functions **************************** )
-
- : MESSAGE[ \ compiling: ( -- ) enclose subsequent ']'ed string
- CREATE 93 word here c@ 1+ dup 2 mod + allot 0 [compile] ,
- DOES> count drop ; \ runtime action: ( -- addr )
-
- : STRING>> \ compiling: ( n -- ) number of bytes in the string
- CREATE allot ;
-
- : <> = 0= ; macro
-
- : newstr ( addr -- ) \ zero a string
- 0 swap c! ;
-
- : length ( addr -- count ) \ length of the string at addr
- dup >r BEGIN dup c@ 0 <> WHILE 1+ REPEAT r> - ;
-
- : strcpy ( str1 str2 -- ) \ copy string 1 to string 2
- dup length + >r \ automatically append
- BEGIN dup c@ 0 <> WHILE
- dup c@ r c! r> 1+ >r 1+
- REPEAT 0 r> c! ;
-
- : strncpy ( str1 str2 -- ) \ copy as above, clear str2 first
- dup newstr strcpy ;
-
- : 0type ( addr -- ) \ type null terminated string
- dup length dup 0 <> IF type ELSE 2drop THEN ;
-
- : >null ( addr -- ) \ convert a counted string into a null terminated string
- dup c@ 2dup + >r swap dup 1+ swap rot cmove 0 r> c! ;
-
- : >count ( addr -- ) \ convert a null terminated string into a counted string
- dup length >r dup dup 1+ r cmove r> swap c! ;
-
- : accept ( addr len -- ) \ like expect but no blank at end of line
- swap dup >r swap expect 0 r r> length 1- c! ;
-
-
- ( **************** Apple Event and reply string handler ******************* )
-
- \ This code courtesy of C. Heilman
-
- 2variable DDATA 4 allot
-
- MESSAGE[ SERROR Empty stack!]
-
- ( get AEDesc handle from an Apple Event )
- : ?DESC ( d.key d.type -- desc.handle desc.type -1 or 0 )
- 0 >r ( room for error )
- 202 +md 2@ 2>r ( the AppleEvent handle )
- 2swap 2>r 2>r ( keyword and type )
- here a>r ( receiving address )
- ,$ 303C ,$ 812 ,$ A816 ( AEGetParamDesc: move #$812,d0 _Pack8 )
- r> 0= IF ( if there is no error )
- here 4 + 2@ here 2@ -1 ( get data & leave true )
- ELSE 0 THEN ; ( or else leave false )
-
- : -DESC ( addr.where.desc.is.stored -- error ) ( remove desc rec. )
- 0 >r a>r ( push room and descriptor )
- ,$ 303C ,$ 0204 ,$ A816 ( AEDisposeDesc: move #$0204,d0 _Pack8 )
- r> ;
-
- 2variable DSIZE \ this double variable holds the size of a string in dbuff
- variable DBUFF 2046 allot \ this block is filled with a text string
-
- ( get AE data from an Apple Event )
- : ?DATA ( d.key -- addr length -1 or 0 )
- 0 >r \ make room on stack for error
- 202 +md 2@ 2>r \ push theAppleEvent address
- 2>r ,s TEXT 2>r \ push keyword (from pstack) and desired type (TEXT)
- here a>r \ push an address to hold the actual type
- dbuff a>r \ push the data receiving address
- 2048 s>d 2>r \ max number of bytes to read
- dsize a>r \ push a variable to hold the actual size
- ,$ 303C ,$ 0E11 ,$ A816 \ AEGetParamPtr: move #$812,d0 _Pack8
- r> 0= IF \ if there is no error
- dbuff dsize 2@ drop -1 \ put address, count and true on pstack
- ELSE 0 THEN ; \ else false
-
- \ Reply to an Apple Event with a string
- : REPLY ( addr -- ) \ **** USE INSIDE OF A HANDLER ONLY ****
- dup length \ how long is it?
- 0 >r \ put room for error on rstack
- 198 +md 2@ 2>r \ put the ReplyEvent handle on rstack
- ,s ---- 2>r ,s TEXT 2>r \ put keyword and type on rstack
- swap a>r 0 2>r \ put addr & count on rs from pstack
- ,$ 303C ,$ 0A0F ,$ A816 \ AEPutParamPtr: move #$A0F,d0 _Pack8
- r> drop ; \ ignore any error
-
-
- ( ******************* Words to get field data *********************** )
-
- 0 constant NEW \ start a new string
- -1 constant APPEND \ append at end of existing string
-
- variable theAddr \ holds the address of the string
-
- : zeroStr ( -- ) \ zero the string in theAddr
- 0 theAddr @ c! ;
-
- : >append ( c -- ) \ put a character on the end of theAddr
- theAddr @ length theAddr @ + dup >r c! \ character
- 0 r> 1+ c! ; \ null
-
- : count>str ( addr len -- ) \ copy characters into the string
- >r dup r> + swap DO
- r c@ >append
- LOOP ;
-
- : h>d ( c -- d ) \ hex digit to decimal, no error checking
- dup 64 > IF 55 - ELSE 48 - THEN ;
-
- : hex>char ( addr -- addr+2 ) \ convert a %xx sequence into a character
- 1+ dup c@ swap 1+ dup c@ swap >r ( save addr )
- h>d swap h>d 16 * +
- dup 32 < IF
- 13 = IF 13 >append THEN \ return character
- ELSE
- >append \ anything >= space
- THEN
- r> ; ( pull address )
-
- variable <end> \ where to stop
- : count>str+ ( addr len -- ) \ copy characters into the string (filtered)
- swap dup rot + <end> !
- BEGIN
- dup <end> @ < \ not at the end of the string
- WHILE
- dup c@
- dup 43 = IF drop 32 >append ELSE \ pluses to spaces
- dup 37 = IF drop ( a) hex>char ELSE \ non-alphanumeric character
- >append THEN THEN \ alphanumeric character
- 1+ \ move to next character
- REPEAT ;
-
- message[ s1 <html>]
- message[ s2 </html>]
-
- : startString ( addr -- ) ( load the header text into string )
- s1 swap strcpy ;
- : endString ( -- ) s2 swap strcpy ; ( ending text )
-
- ( *************************** Number <--> String ************************* )
-
- : f>str ( f addr -- ) \ convert a float to a string in addr
- depth 4 > IF \ original CH, modified by RTK
- theAddr ! zeroStr \ dest address
- @pen 2>r 10 +md @ >r 30000 10 +md ! \ move pen offscreen
- 3000 3000 !pen f. \ print float: string is at here
- r> 10 +md ! 2r> !pen \ return pen to origonal position
- here count count>str \ put it addr
- ELSE serror THEN ;
-
- : str>f ( addr -- f ) \ convert a string into a float
- 1- >abs fnumber ;
-
- ( ********************** User level words ************************* )
-
- : @Direct ( addr new|append -- ) \ get the direct argument
- swap theAddr ! \ store the string address
- NEW = IF zeroStr THEN \ clear the string
- ,s ---- ?data IF count>str THEN \ get the argument
- ;
-
- : @Addr ( addr new|append -- ) \ get the IP address
- swap theAddr ! \ store the string address
- NEW = IF zeroStr THEN \ clear the string
- ,s addr ?data IF count>str THEN \ get it
- ;
-
- : @Browser ( addr new|append -- ) \ get the browser type
- swap theAddr ! \ store string address
- NEW = IF zeroStr THEN
- ,s Agnt ?data IF count>str THEN \ get it
- ;
-
- \
- \ Fetch Field Data
- \
-
- variable fname \ holds field name address
- variable postend \ holds end of post data address
-
- : [@] ( a offset -- v ) + c@ ;
-
- variable sflg
- : same? ( str1 str2 -- t|f ) \ true if str1==str2, length from str2
- -1 sflg !
- dup length 0 DO 2dup
- r [@] swap r [@]
- <> IF 0 sflg ! leave THEN
- LOOP 2drop
- sflg @ ;
-
- : nextField ( indx -- indx' eos? ) \ move pointer to the next field name
- \ i.e. advance to 1 beyond next '&' character
- BEGIN
- dup dup c@ 38 <>
- swap postend @ <> and \ while not '&' and not at end of string
- WHILE 1+
- REPEAT
- dup c@ 0= IF -1 ELSE 1+ 0 THEN
- ;
-
- : fData ( addr -- addr' ) \ return pointer to beginning of field data
- BEGIN
- dup dup c@ 61 <> \ while not an '='
- swap postend @ <> and \ and not end-of-data
- WHILE 1+ \ move to next char
- REPEAT
- 1+ \ really want to end up pointing just beyond the '='
- ;
-
- : fLen ( addr -- len ) \ return length of field data
- dup BEGIN
- dup dup c@ 38 <> \ while not an '&'
- swap postend @ <> and \ and not end-of-data
- WHILE 1+ \ move to next char
- REPEAT
- swap - \ return the length
- ;
-
- : @Field ( addr1 addr2 new|append -- ) \ get the data for a field
- rot theAddr !
- NEW = IF zeroStr THEN
- fname ! \ address of field name string
- ,s post ?data IF \ there is post data
- postend ! \ store the length
- dup postend +! \ and find end of post data address
- ( a ) 0 \ start of string, eos? flag
- BEGIN 0=
- WHILE
- dup fname @ same? \ right field?
- IF
- fData dup fLen \ yes, move to field data and get length
- count>str+ \ then copy to the output string
- -1 \ flag end of loop
- ELSE
- nextField \ no, move to next
- THEN
- REPEAT
- drop \ remove addr
- THEN
- ;
-