\ $Id: cgi.f,v 1.18 2009/08/29 12:52:05 ygreks Exp $
\
\ Simple CGI
\ See it in action at http://ygrek.org.ua/p/spf/words?q=swap
: wordsfile S" words.txt" ;
REQUIRE FINE-TAIL ~pinka/samples/2005/lib/split-white.f
REQUIRE $Revision ~ygrek/lib/fun/kkv.f
REQUIRE { lib/ext/locals.f
REQUIRE DumpParams ~ac/lib/string/get_params.f
REQUIRE BOUNDS ~ygrek/lib/string.f
REQUIRE CEQUAL ~pinka/spf/string-equal.f
REQUIRE TYPE>STR ~ygrek/lib/typestr.f
REQUIRE OSNAME-STR ~ygrek/lib/sys/osname.f
\ REQUIRE INTER ~ygrek/lib/debug/inter.f
REQUIRE list-all ~ygrek/lib/list/all.f
REQUIRE words-load ~ygrek/prog/web/help.cgi/load.f
REQUIRE XHTML-EXTRA ~ygrek/lib/xhtml/extra.f
: revision $Revision: 1.18 $ SLITERAL ;
: spf-version VERSION 1000 / 100 /MOD " {n}.{n}" ;
: text/html S" Content-type: text/html" TYPE CR ;
: content-length ( n -- ) " Content-Length: {n}" STYPE CR ;
: get-params S" QUERY_STRING" ENVIRONMENT? 0= IF S" " THEN GetParamsFromString ;
: EMPTY? NIP 0= ;
: STARTS-WITH? { a1 u1 a2 u2 -- ? }
u1 u2 < IF FALSE EXIT THEN
a1 u2 a2 u2 CEQUAL ;
ALSO XHTML
ALSO XMLSAFE
: start-page ( -- )
<<
tag: h2
." Search SP-Forth words (src,lib,devel) :"
>>
S" " form
<<
tag: div
%[
`q `name $$
`q GetParam `value $$
`text `type $$
`30 `size $$
]%
/atag: input
%[
`exact `name $$
`1 `value $$
`exact GetParam EMPTY? NOT IF `checked 2DUP $$ THEN
`exact `id $$
`checkbox `type $$
]%
/atag: input
<< %[ `exact `for $$ ]% `label atag S" whole word" TYPE >>
%[ `submit `type $$ `Search `value $$ ]% `input /atag
>>
`div tag
`small tag
." Usual shell wildcards should work : ? (any symbol) and * (any number of any symbols)" CR
S" All words" wordsfile link-text
;
\ link to source
: source-from-spf ( a u -- )
\ " http://spf.cvs.sourceforge.net/*checkout*/spf/"
" http://forth.org.ru/"
>R
2DUP S" ~" STARTS-WITH? IF S" devel/" R@ STR+ THEN
2DUP R@ STR+
R@ " \" " /" replace-str- \ "
( a u ) R@ STR@ link-text
R> STRFREE ;
: spf-logo ." Powered by " `SP-Forth `http://spf.sf.net link-text SPACE spf-version STYPE ;
: show-word ( s1 s2 s3 -- )
<< `word :span STR@ TYPE >>
SPACE
<< `stack :span STR@ TYPE >>
<< `source :span ." \ " STR@ source-from-spf >>
CR ;
: block ( l a u -- )
hrule
<< tag: h3 TYPE >>
tag: div
DUP << words-each-> show-word >>
list::free ;
: content
get-params
start-page
`q GetParam EMPTY? IF EXIT THEN
{ | l s }
wordsfile words-load -> l
`q GetParam `exact GetParam EMPTY? IF " *{s}*" ELSE >STR THEN -> s
s STR@ l words-find ( l1 l2 )
S" Exact matches : " block
S" Case-insensitive matches : " block
l words-free
s STRFREE
;
: footer
hrule
tag: div
<<
%[ S" float:left;margin-right:1%" `style $$ ]%
atag: div
tag: small
OSNAME-STR { os }
`help.cgi `http://forth.org.ru/~ygrek/prog/web/help.cgi/cgi.f link-text
os STR@ FINE-TAIL " r{revision} ({s})" STYPE CR
os STRFREE
spf-logo
>>
icon-valid
;
: output
xml-declaration
doctype-strict
xhtml
<<
tag: head
%[ `content-type `http-equiv $$ `text/html;charset=utf-8 `content $$ ]% /atag: meta
`some.css link-stylesheet
tag: title S" SP-Forth words search" TYPE
>>
tag: body
content
footer ;
PREVIOUS
PREVIOUS
\ buffer all output so that we can set Content-Length and server won't use
\ chunked transfer-encoding (thx to ~pinka for pointing this out)
: output-s LAMBDA{ output CR } TYPE>STR ;
: main text/html output-s DUP STRLEN content-length CR STYPE ;
: save
LAMBDA{ main BYE } MAINX !
`help.cgi SAVE BYE ;