From 0e7e33e7917126521c2e05e621a0c600b011d69b Mon Sep 17 00:00:00 2001 From: Igor Khomyakov Date: Thu, 8 Mar 2012 18:38:20 -0500 Subject: [PATCH] version 0.1. requires improvements: 1) use proper temporary file 2) encode text to make sure it doesnt have a conflict with [====[... 3) print help / usage 4) add third arg : output file name 5) chmod/chown?/chcon? out file to input file 6) traverse dir recoursively, search for *.template and process them --- miconf/README | 6 +- miconf/miconf.c | 155 +++++++++++++++++++++++++++++++++++++++++++------ miconf/sample.config | 12 ++++ miconf/sample.template | 11 ++++ 4 files changed, 164 insertions(+), 20 deletions(-) create mode 100644 miconf/sample.config create mode 100644 miconf/sample.template diff --git a/miconf/README b/miconf/README index 2fd8483..520954c 100644 --- a/miconf/README +++ b/miconf/README @@ -1,4 +1,4 @@ -$ cat config.lua +$ cat sample.config a = 5 b = 200 c = "Hello, world!" @@ -23,9 +23,9 @@ text5,<<>>,text6,<<>>,text7 === end text8 -$ miconf config.lua file +$ miconf sample.config sample.template >sample -$ cat file +$ cat sample text0 text1,Hello, world!,text2 text3 diff --git a/miconf/miconf.c b/miconf/miconf.c index d9ee0cd..6ad1ee3 100644 --- a/miconf/miconf.c +++ b/miconf/miconf.c @@ -31,45 +31,166 @@ #include "lauxlib.h" #include "lualib.h" +#define TMPFNAME "tmp.lua" + #define WRITE_BATCH 50 #define WRITE_BEG "[=====[" #define WRITE_END "]=====]" +#define EQ '=' +#define LA '<' +#define RA '>' +#define NL '\n' + +#define begText() fprintf(fo,"io.write(%s",WRITE_BEG) +#define doText(c) fputc(c,fo) +#define endText() fprintf(fo,"%s) -- %d\n",WRITE_END,lineno) + +#define begStat() fputc(NL,fo) +#define doStat(c) fputc(c,fo) +#define endStat() fprintf(fo," -- %d\n",lineno) + +#define begExpr() fprintf(fo,"io.write(tostring(") +#define doExpr(c) fputc(c,fo) +#define endExpr() fprintf(fo,")) -- %d\n", lineno) + +// if (lineno % WRITE_BATCH == 0) { + void convert(FILE* fi, FILE* fo) { int lineno = 1; int c; - fprintf(fo,"io.write(%s",WRITE_BEG); + int s = 1; //state do { - c = getc(fi); - if (c == EOF) { - if (ferror(fi)) { - fprintf(stderr,"stdin error: %d\n", errno); - exit(1); + c=getc(fi); + switch (s) { + case 1: + switch (c) { + case EQ: s=2; break; + case LA: s=6; break; + case EOF: s=1; break; + default: s=5; begText(); doText(c); break; + } + break; + case 2: + switch (c) { + case EQ: s=3; break; + case EOF: s=5; doText(EQ); endText(); break; + default: s=5; doText(EQ); doText(c); break; + } + break; + case 3: + switch (c) { + case EQ: s=4; begStat(); break; + case EOF: s=5; doText(EQ); doText(EQ); endText(); break; + default: s=5; doText(EQ); doText(EQ); doText(c); break; } - } else if (c == '\n') { - fputc(c,fo); - if (lineno % WRITE_BATCH == 0) { - fprintf(fo,"%s)\nio.write(%s",WRITE_END,WRITE_BEG); + break; + case 4: + switch (c) { + case NL: s=1; endStat(); break; + case EOF: s=1; endStat(); break; + default: s=4; doStat(c); break; } + break; + case 5: + switch (c) { + case LA: s=6; break; + case NL: s=1; doText(c); endText(); break; + case EOF: s=5; endText(); break; + default: s=5; doText(c); break; + } + break; + case 6: + switch (c) { + case LA: s=7; break; + case EOF: s=5; doText(LA); endText(); break; + default: s=5; doText(LA); doText(c); break; + } + break; + case 7: + switch (c) { + case LA: s=8; endText(); begExpr(); break; + case EOF: s=5; doText(LA); doText(LA); endText(); break; + default: s=5; doText(LA); doText(LA); doText(c); break; + } + break; + case 8: + switch (c) { + case RA: s=9; break; + case EOF: s=8; endExpr(); break; + default: s=8; doExpr(c); break; + } + break; + case 9: + switch (c) { + case RA: s=10; break; + case EOF: s=8; doExpr(RA); endExpr(); break; + default: s=8; doExpr(RA); doExpr(c); break; + } + break; + case 10: + switch (c) { + case RA: s=5; endExpr(); begText(); break; + case EOF: s=8; doExpr(RA); doExpr(RA); endExpr(); break; + default: s=8; doExpr(RA); doExpr(RA); doExpr(c); break; + } + break; + } + if (c==NL) { lineno++; - } else { - fputc(c,fo); } - } while (c != EOF); - fprintf(fo,"%s)\n",WRITE_END); + + } while (c!=EOF); + + if (ferror(fi)) { + fprintf(stderr,"file read error (errno=%d)\n", errno); + exit(1); + } } int main(int argc, char* argv[]) { + const char* cname = argc>1 ? argv[1] : "config.lua"; + const char* tname = argc>2 ? argv[2] : "-"; + FILE* fi; + FILE* fo; lua_State *L = luaL_newstate(); luaL_openlibs(L); - if (luaL_dofile(L,"config.lua")!=0) { - fprintf(stderr,"%s\n",lua_tostring(L,-1)); + if (luaL_dofile(L,cname)!=0) { + fprintf(stderr,"%s (file=%s)\n",lua_tostring(L,-1),cname); lua_pop(L,1); exit(1); } - convert(stdin,stdout); + if (strcmp(tname,"-")!=0) { + fi = fopen(tname,"r"); + if (fi==NULL) { + fprintf(stderr,"can't open input file (file=%s, errno=%d)\n", tname, errno); + exit(1); + } + } else { + fi = stdin; + } + + fo = fopen(TMPFNAME,"w"); + if (fo==NULL) { + fprintf(stderr,"can't open temporary file (file=%s, errno=%d)\n", TMPFNAME, errno); + exit(1); + } + convert(fi,fo); + fclose(fo); + + if (strcmp(tname,"-")!=0) { + fclose(fi); + } + + if (luaL_dofile(L,TMPFNAME)!=0) { + fprintf(stderr,"%s (file=%s)\n",lua_tostring(L,-1),TMPFNAME); + lua_pop(L,1); + exit(1); + } + lua_close(L); + return(0); } diff --git a/miconf/sample.config b/miconf/sample.config new file mode 100644 index 0000000..35ac5de --- /dev/null +++ b/miconf/sample.config @@ -0,0 +1,12 @@ +a = 5 +b = 200 +c = "Hello, world!" +if a < 100 then + d = {x=a, "boo"} +else + d = {x=10, "foo"} +end +function square(x) + return x*x +end + diff --git a/miconf/sample.template b/miconf/sample.template new file mode 100644 index 0000000..204f4eb --- /dev/null +++ b/miconf/sample.template @@ -0,0 +1,11 @@ +text0 +text1,<<>>,text2 +=== if b > 100 then +text3 +=== end +text4 +=== for i = 1, a do +text5,<<>>,text6,<<>>,text7 +=== end +text8 + -- 2.11.4.GIT