%{ /*************************** pn.l (lex+C file) ************************ This is the main code for a CGI script (called from http://www.phmartin.infowf/pnml.html) that converts the PNML output of PIPE to EPNML (the PNML accepted by Woflan, see http://www.petriweb.org/specs/). Created by "pm .@. phmartin dot info" on the 16/07/2004 Compilation outline: flex -Ppn -i pn.l g++ -o pn.o -c lex.pn.c g++ -o pn.cgi pn.o ldynStr.o (ldynStr.cc is my implementation of dynamic strings) ***********************************************************/ #include <stdio.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <ctype.h> #include "ldynStr.h" #define pr printf #define ERR_HDR "CONTENT-TYPE: text/html\n\n<html><head><title>Error</title></head><body>\n" static int R; static char *Boundary, Attr[110], FileName[110]; static dynStr Val(110); static int FD; static FILE *FP; int prErrDoc (const char *format, ...); static int prErr (const char *format, ...); static int scpto (/*initP*/ char *s, const char *name); static void rplSpaces (); %} ANY (.|\n) QSTR1 '([^'\\]|(\\{ANY}))*' QSTR2 \"([^"\\]|(\\{ANY}))*\" QSTR ({QSTR1}|{QSTR2}) DUMMY (a|b) S ([ \n\t\r])+ s ([ \n\t\r])* IDENT1 ("#"?[A-Za-z0-9_-]) IDENTn ([A-Za-z0-9_/-\-.#@: ]|"\\".) IDENT {IDENT1}{IDENTn}* ID ([A-Za-z0-9_\- ]+) NUM ([0-9A-Za-z]+) BOUND ("--""-"*{NUM}{S}"Content-Disposition: form-data; name="\") END_BOUND ("--""-"*{NUM}"--") BOUNDofFILE ({BOUND}file\""; filename="\") %x BOUND_NUM BOUND_SEP FILEN FILEC ATTR VAL SKARC SKIM0 %% "Content-Type: multipart/form-data; " ; {BOUNDofFILE} {if (strstr(pntext,Boundary)) BEGIN(FILEN);} <FILEN>{IDENT}\"{s} {*(strrchr(pntext,'"'))='\0'; if(!(R=scpto(FileName,"File name")))return R; BEGIN(FILEC);} <FILEC>{BOUND} {yyless(0); BEGIN(0);} <FILEC>"value>" {fputs("text>",stdout);} <FILEC>"</place>" {fputs("<type><text>channel</text></type> </place>",stdout);} <FILEC>"<graphics/>" ; <FILEC>"<initialMarking>"{s}"<value>0</value>" BEGIN(SKIM0); <SKIM0>"</initialMarking>" BEGIN(FILEC); <SKIM0>. ; <FILEC>"<orientation>" {fputs("<!-- <orientation>",stdout);} <FILEC>"</orientation>" {fputs("</orientation> -->",stdout);} <FILEC>"<rate>" {fputs("<!-- <rate>",stdout);} <FILEC>"</rate>" {fputs("</rate> -->",stdout);} <FILEC>"<timed>" {fputs("<!-- <timed>",stdout);} <FILEC>"</timed>" {fputs("</timed> -->",stdout);} <FILEC>"<arcpath id" BEGIN(SKARC); <SKARC>"/>" BEGIN(FILEC); <SKARC>. ; <FILEC>" id="\"{ID} {rplSpaces(); fputs(pntext,stdout); /*"*/ } <FILEC>"Content-Type: text/xml"{s} ; <FILEC>\r\n {fputc(pntext[0],stdout);} <FILEC>\n {fputc(pntext[0],stdout);} <FILEC>. {fputc(pntext[0],stdout);} {BOUND} {if (strstr(pntext,Boundary)) BEGIN(ATTR);} <ATTR>{IDENT}\"{s} {*(strrchr(pntext,'"'))='\0'; Val.clear(); if(!(R=scpto(Attr,"Attribute")))return R; BEGIN(VAL);} <ATTR>. {BEGIN(0); return prErr("Not an identifier: %s");} <VAL>{BOUND} {yyless(0); BEGIN(0);} <VAL>. {Val.append(pntext[0]);} <*>{END_BOUND} {/*pr("\n</body></html>\n");/} {ANY} {/*pr(",%c",pntext[0]);*/} %% int prErrDoc (const char *format, ...) { va_list pArgs; va_start(pArgs,format); pr(ERR_HDR "Error. "); vfprintf(stdout,format,pArgs); pr("\n</body></html>\n"); va_end(pArgs); fflush(stdout); yyterminate();//return 0; } int prErr (const char *format, ...) { va_list pArgs; va_start(pArgs,format); vfprintf(stdout,format,pArgs); pr("\n"); va_end(pArgs); fflush(stdout); yyterminate();//return 0; } static int scpto (/*initP*/ char *s, const char *name) { if (pnleng<100) { strcpy(s,pntext); return 1; } pr("%s too long: %s\n",name, s); yyterminate();//return 0; } static void rplSpaces () { for (int i=1; i<pnleng; i++) if (isspace(pntext[i])) pntext[i]='_'; } void pn_yyunput (int i, char *s) /*to suppress the "not used" messages*/ { yyunput(i,s); } int pnwrap () { return 1;/*no other file to parse*/ } int pnerror (const char *s) { pr("At \"%s\": %s",pntext,s); return 1; } int main (int argc, char *argv[], char *envp[]) { const char *e= getenv("REQUEST_METHOD"); if (!e) return 0; if (strcmp(e,"POST")) { pr(ERR_HDR "Unexpected CGI call: %s. Instead, \"REQUEST_METHOD='POST'\" was" " expected\n</body></html>\n",e); return 0; } if (strncmp(e=getenv("CONTENT_TYPE"),"multipart/form-data; ",21)) { pr(ERR_HDR "Unexpected form encoding: \"multipart/form-data'\" " "expected</body></html>\n"); return 0; } if (!(Boundary= strrchr(e,'='))) { pr(ERR_HDR "No Boundary specified.\n</body></html>\n"); return 0; } ++Boundary; pr("CONTENT-TYPE: text/xml\n\n"); pnin= stdin; errno=0; //I::LineNum=1; pnlex(); //only once since no return in the rules of the grammar return 0; }