/* Copyright (C) 2001 ITK Autor : Rust (rust@itk.ru) Licence : (GPL) http://www.itk.ru/clipper/licence.html */ #define CR CHR(13) #define LF CHR(10) #define CHUNKSIZE 1024 memvar vars, recurse, stopparsing memvar html, ifdeep, ifyes, ifanyyes memvar whiledeep, whilestack, whileyes, conn memvar rdbms, host, login, passwd, rs PROCEDURE Main() LOCAL srcfile LOCAL conn PRIVATE vars := GETENV() PUBLIC recurse := -1 PUBLIC stopparsing := .F. set translate off ErrorBlock({|e| BREAK(e)}) vars:WWW_CLIP_VERSION := "0.0.1" ?? "Content-type: text/html" ? "Generator: WWW-Clip Version "+vars:WWW_CLIP_VERSION ? srcfile := vars:PATH_TRANSLATED ? ParseFile(srcfile) RETURN FUNCTION ParseFile(srcfile) LOCAL fd LOCAL src := "" LOCAL chunk := SPACE(CHUNKSIZE) LOCAL read LOCAL len LOCAL I LOCAL istag := .F. LOCAL tagbegin := 0 LOCAL tagend := 0 LOCAL term LOCAL isquote := .F. LOCAL ret := "" LOCAL done := .F. LOCAL brk := .F. LOCAL nxt := .F. LOCAL pars := "" LOCAL ch PRIVATE html := ARRAY(0) PRIVATE ifdeep := 0 PRIVATE ifyes := ARRAY(100) PRIVATE ifanyyes := ARRAY(100) PRIVATE whiledeep := 0 PRIVATE whilestack := ARRAY(100) PRIVATE whileyes := ARRAY(100) PRIVATE conn := NIL PRIVATE rdbms PRIVATE host PRIVATE login PRIVATE passwd PRIVATE rs := map() recurse++ IF recurse >= 10 recurse-- RETURN ret ENDIF AFILL(whilestack,0) IF vars:REQUEST_METHOD == "GET" pars := vars:QUERY_STRING ELSE fd := FOPEN("-|",0) DO WHILE (read := FREAD(fd,@chunk,CHUNKSIZE)) == CHUNKSIZE pars += chunk chunk := SPACE(CHUNKSIZE) ENDDO pars += LEFT(chunk,read) FCLOSE(fd) ENDIF ParseParameters(pars) fd := FOPEN(srcfile,0) IF fd == -1 recurse-- RETURN "File not found" ENDIF DO WHILE (read := FREAD(fd,@chunk,CHUNKSIZE)) == CHUNKSIZE src += chunk chunk := SPACE(CHUNKSIZE) ENDDO src += LEFT(chunk,read) FCLOSE(fd) len := LEN(src) FOR I:=1 TO len ch := SUBSTR(src,I,1) IF !isquote IF !istag IF ch == "<" istag := .T. tagbegin := I term := SUBSTR(src,tagend+1,tagbegin-tagend-1) IF LEN(term) > 0 AADD(html,term) ENDIF ENDIF ELSE IF ch == ">" istag := .F. tagend := I term := SUBSTR(src,tagbegin,tagend-tagbegin+1) AADD(html,term) ENDIF ENDIF ENDIF IF ch == '"' .AND. SUBSTR(src,MAX(I-1,1),1) != "\" isquote := !isquote ENDIF NEXT AADD(html,SUBSTR(src,MAX(tagbegin,tagend+1))) FOR I:=1 TO LEN(html) IF stopparsing EXIT ENDIF IF LEFT(html[I],2) == "connect: too few arguments
"+LF ENDIF rdbms := terms[1] host := IF(LEN(terms)>1,terms[2],NIL) login := IF(LEN(terms)>2,terms[3],NIL) passwd := IF(LEN(terms)>3,terms[4],NIL) host := IF(host=="NIL" .OR. host=="",NIL,host) login := IF(login=="NIL" .OR. login=="",NIL,login) passwd := IF(passwd=="NIL" .OR. passwd=="",NIL,passwd) IF UPPER(rdbms) == "OR" .OR. UPPER(rdbms) == "MS" conn := ConnectNew(rdbms,NIL,NIL,login,passwd) ENDIF CASE cmd == "CLIP" CASE cmd == "CLOSE" conn:Destroy() CASE cmd == "CONTINUE" nxt := .T. CASE cmd == "CONVERT" terms := ParseArgs(args) IF LEN(terms) < 1 RETURN "convert: too few arguments
"+LF ENDIF vars[HASHSTR(UPPER(terms[1]))] :=; XTOC(vars[HASHSTR(UPPER(terms[1]))]) CASE cmd == "DATABASE" terms := ParseArgs(args) IF LEN(terms) == 0 RETURN "database: too few arguments
"+LF ENDIF IF rdbms == "PG" conn := ConnectNew(rdbms,host,NIL,login,passwd,terms[1]) ELSEIF rdbms == "MS" conn:Command("use "+terms[1]) ENDIF CASE cmd == "EVAL" IF LEN(args)==0 RETURN "eval: too few arguments
"+LF ENDIF ret := DoEval(ParseExpr(args)) CASE cmd == "EXEC" IF LEN(args)==0 RETURN "exec: too few arguments
"+LF ENDIF tmp := "" err := "" SYSCMD(args,"",@tmp,@err) ret := tmp CASE cmd == "FETCH" RETURN ret CASE cmd == "FTIME" terms := ParseArgs(args) IF LEN(terms) < 1 RETURN "ftime: too few arguments
"+LF ENDIF tmp := 0 IF LEN(terms) > 1 tmp := VAL(terms[2]) ENDIF ret += STRFTIME(terms[1],tmp) CASE cmd == "FREE" terms := ParseArgs(args) IF LEN(terms) == 0 RETURN "free: too few arguments
"+LF ENDIF r := rs[HASHSTR(UPPER(terms[1]))] r:Destroy() CASE cmd == "IF" IF LEN(args)==0 RETURN "if: too few arguments
"+LF ENDIF tmp := DoEval(ParseExpr(args)) IF tmp != "0" .AND. tmp != "1" RETURN tmp ENDIF ifdeep++ IF ifdeep == 1 .OR. ifyes[ifdeep-1] ifanyyes[ifdeep] := ifyes[ifdeep] := (tmp != "0") ELSE ifyes[ifdeep] := .F. ENDIF CASE cmd == "ELSEIF" IF LEN(args)==0 RETURN "elseif: too few arguments
"+LF ENDIF IF ifdeep == 1 .OR. ifyes[ifdeep-1] IF !ifyes[ifdeep] tmp := DoEval(ParseExpr(args)) IF tmp != "0" .AND. tmp != "1" ret += tmp ENDIF ifanyyes[ifdeep] := ifyes[ifdeep] := (tmp != "0") ELSE ifyes[ifdeep] := .F. ENDIF ELSE ifyes[ifdeep] := .F. ENDIF CASE cmd == "ELSE" IF ifdeep == 1 .OR. ifyes[ifdeep-1] ifyes[ifdeep] := !ifanyyes[ifdeep] ELSE ifyes[ifdeep] := .F. ENDIF CASE cmd == "ENDIF" ifdeep-- CASE cmd == "INCLUDE" terms := ParseArgs(args) IF LEN(terms)<1 RETURN "include: too few arguments
"+LF ENDIF ret := ParseFile(terms[1]) CASE cmd == "PRINT" terms := ParseArgs(args) IF LEN(terms) < 0 RETURN "print: too few arguments
"+LF ENDIF args := STRTRAN(terms[1],'\"','"') args := STRTRAN(args,"\n",LF) args := STRTRAN(args,"\t",CHR(9)) args := STRTRAN(args,"\?","?") ret := ParseFields(args,.F.) CASE cmd == "PRINT_LOOP" terms := ParseArgs(args) IF LEN(terms)<1 RETURN "print_loop: too few arguments
"+LF ENDIF r := rs[HASHSTR(UPPER(terms[1]))] IF whiledeep == 0 .OR. whilestack[whiledeep] != I whiledeep++ whilestack[whiledeep] := I ELSE r:Skip() ENDIF whileyes[whiledeep] := !r:Eof() CASE cmd == "PRINT_ROWS" terms := ParseArgs(args) IF LEN(terms)<2 RETURN "print_rows: too few arguments
"+LF ENDIF r := rs[HASHSTR(UPPER(terms[1]))] terms[2] := STRTRAN(terms[2],'\"','"') terms[2] := STRTRAN(terms[2],"\n",LF) terms[2] := STRTRAN(terms[2],"\t",CHR(9)) DO WHILE !r:Eof() ret += ParseFields(terms[2],.F.) r:Skip() ENDDO CASE cmd == "QUERY" terms := ParseArgs(args) IF LEN(terms)<1 RETURN "query: too few arguments
"+LF ENDIF query := ParseQuery(terms[1]) IF LEN(terms) == 1 vars:AFFECTED_ROWS := conn:Command(query) ELSE r := rs[HASHSTR(UPPER(terms[2]))] :=; conn:CreateRowset(query) vars:NUM_FIELDS := r:NFields() vars:NUM_ROWS := r:Lastrec() ENDIF CASE cmd == "QTABLE" terms := ParseArgs(args) IF LEN(terms)<1 RETURN "qtable: too few arguments
"+LF ENDIF borders := .F. IF LEN(terms)>1 .AND. UPPER(terms[2]) == "BORDERS" borders := .T. ENDIF r := rs[HASHSTR(UPPER(terms[1]))] ret := "| " ret += r:FieldName(J) ret += " | " NEXT ret += "
|---|
| " tmp := data[HASHSTR(UPPER(r:FieldName(J)))] ret += XTOC(tmp) ret += " | " NEXT ret += "
qlongform: too few arguments
"+LF ENDIF r := rs[HASHSTR(UPPER(terms[1]))] rec := r:Recno() r:GoTop() DO WHILE !r:Eof() data := r:Read() FOR J:=1 TO r:NFields() ret += ""+r:FieldName(J)+": " tmp := data[HASHSTR(UPPER(r:FieldName(J)))] ret += XTOC(tmp) ret += ""+LF r:Skip() ENDDO r:Goto(rec) CASE cmd == "QSELECT" terms := ParseArgs(args) IF LEN(terms)<2 RETURN "
qselect: too few arguments
"+LF ENDIF ret += '"+LF CASE cmd == "SEEK" terms := ParseArgs(args) IF LEN(terms)<2 RETURN "seek: too few arguments
"+LF ENDIF r := rs[HASHSTR(UPPER(terms[1]))] pos := VAL(terms[2]) r:Goto(pos) CASE cmd == "SET" .OR. cmd == "SETEXPR" terms := ParseArgs(args) IF LEN(terms)<2 RETURN "set: too few arguments
"+LF ENDIF pos := AT(" ",args) tmp := "vars:"+STUFF(args,pos,1,":=") DoEval(ParseExpr(tmp)) CASE cmd == "SETDEFAULT" terms := ParseArgs(args) IF LEN(terms)<2 RETURN "setdefault: too few arguments
"+LF ENDIF pos := AT(" ",args) tmp := HASHSTR(UPPER(SUBSTR(args,1,pos-1))) mkeys := MAPKEYS(vars) FOR J:=1 TO LEN(mkeys) IF mkeys[J] == tmp RETURN ret ENDIF NEXT pos := AT(" ",args) tmp := "vars:"+STUFF(args,pos,1,":=") DoEval(tmp) CASE cmd == "WHILE" IF LEN(args)==0 RETURN "while: too few arguments
"+LF ENDIF tmp := DoEval(ParseExpr(args)) IF whiledeep == 0 .OR. whilestack[whiledeep]!=I whiledeep++ whilestack[whiledeep] := I ENDIF whileyes[whiledeep] := (tmp != "0") CASE cmd == "DONE" done := .T. OTHERWISE ret := "Unknown command: "+tag+"
"+LF ENDCASE ENDIF RECOVER USING e ret := "