#include #include #include typedef enum { st_ok, st_in_string, st_in_string_bsl, st_tag_open, st_sst_tag_open, st_in_expression, st_in_expression_percent, st_in_schemelet, st_in_schemelet_percent } parse_state; int ssp_compile(const char *infile, const char *outfile) { struct stat stat1, stat2; FILE *inf, *outf; int c; parse_state pst; parse_state saved_pst; int count; if(stat(infile,&stat1)!=0) { return 0; } if(stat(outfile,&stat2)==0) { if(difftime(stat1.st_mtime,stat2.st_mtime)<0) { return 1; /* No recompilation needed */ } } inf=fopen(infile,"r"); outf=fopen(outfile,"w"); if(inf==0 || outf==0) { if(inf!=0) { fclose(inf); } if(outf!=0) { fclose(outf); } return 0; } pst=st_ok; count=0; while((c=fgetc(inf))!=EOF) { switch(pst) { case st_ok: if(count==0) { fputs("(display \"",outf); } else if(count==256) { fputs("\")\n(display \"",outf); count=0; } if(c=='<') { pst=st_tag_open; } else if(c=='\n') { fputs("\n",outf); count++; } else { if(c=='"') { saved_pst=pst; pst=st_in_string; fputc('\\',outf); } fputc(c,outf); count++; } break; case st_in_schemelet: if(c=='%') { pst=st_in_schemelet_percent; } else { if(c=='"') { saved_pst=pst; pst=st_in_string; } fputc(c,outf); } break; case st_in_schemelet_percent: if(c=='>') { pst=st_ok; count=0; } else { fputc('%',outf); fputc(c,outf); pst=st_in_schemelet; } break; case st_tag_open: if(c=='%') { fputs("\")\n",outf); pst=st_sst_tag_open; } else { pst=st_ok; fputc('<',outf); fputc(c,outf); count+=2; } break; case st_sst_tag_open: if(c=='=') { pst=st_in_expression; fputs("(display ",outf); } else { pst=st_in_schemelet; } break; case st_in_expression: if(c=='%') { pst=st_in_expression_percent; } else { if(c=='"') { saved_pst=pst; pst=st_in_string; } fputc(c,outf); } break; case st_in_expression_percent: if(c=='>') { fputs(")\n",outf); pst=st_ok; count=0; } else { fputc('%',outf); fputc(c,outf); pst=st_in_expression; } break; case st_in_string: if(c=='\\') { pst=st_in_string_bsl; } else if(c=='"') { pst=saved_pst; if(pst==st_ok) { fputc('\\',outf); count++; } fputc(c,outf); } else { fputc(c,outf); } break; case st_in_string_bsl: fputc('\\',outf); pst=st_in_string; fputc(c,outf); break; } } if(pst==st_ok && count!=0) { fputs("\")\n",outf); } else { /* ??? */ } fclose(inf); fclose(outf); return 1; } #ifdef SSP_COMPILER_MAIN int main(int argc, char **argv) { char outfile[1024]; if(argc<2 || access(argv[1],R_OK)!=0) { printf("Usage: ssp_compiler []\n"); return 1; } if(argv[2]==0) { strcpy(outfile,argv[1]); argv[2]=outfile; } ssp_compile(argv[1],argv[2]); } #endif