PageRenderTime 41ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/page.awk

https://bitbucket.org/jkiemes/survey
AWK | 562 lines | 539 code | 22 blank | 1 comment | 0 complexity | 3d50ecec516bbc6c073f96ceabd5b664 MD5 | raw file
  1. BEGIN {
  2. func_aff=""
  3. elem_aff=""
  4. page=-1
  5. elem=0
  6. required=""
  7. # required="required"
  8. print "#include <stdio.h>"
  9. print "#include <string.h>"
  10. print "#include <assert.h>"
  11. print "#include \"../page.h\""
  12. print "#include \"keystruct.h\""
  13. radio = " type=radio class=\\\"regular-radio\\\" "
  14. radio_checked = radio "checked=\\\"checked\\\" "
  15. checkbox = " type=checkbox class=\\\"regular-checkbox\\\" "
  16. checkbox_checked = checkbox "checked=\\\"checked\\\" "
  17. errstyle="\" style=\\\"background-color:red;\\\" \""
  18. butNext="Next"
  19. butPrev="Previous"
  20. }
  21. function map(n) {
  22. if (n < 26)
  23. return sprintf("%c",n+65)
  24. if (n < 52)
  25. return sprintf("%c",n+97-26)
  26. return sprintf("%c",n+48-52)
  27. }
  28. function next_elem(range ,s,r,bits,m) {
  29. r = int(elem/52)
  30. s = map(elem-r*52) map(r)
  31. el_range[s] = range
  32. m=2
  33. for (bits=1;m < range;bits++)
  34. m *= 2
  35. el_bits[s] = bits
  36. elem++
  37. return s
  38. }
  39. /^#/ {next}
  40. {
  41. gsub(/&/,"\\&amp;")
  42. gsub(/>/,"\\&gt;")
  43. gsub(/</,"\\&lt;")
  44. gsub(/"/,"\\&quot;")
  45. gsub(/&amp;&amp;/,"\\&\\&")
  46. }
  47. /^LANG:/ {
  48. gsub(/^LANG: */,"")
  49. lang = $0
  50. }
  51. /^[a-zA-Z][a-zA-Z]\-/ {
  52. if (substr($0,1,2) != lang)
  53. next
  54. gsub(/^[a-zA-Z][a-zA-Z]\-/,"")
  55. }
  56. /^NEXT:/ {
  57. gsub(/^NEXT: */,"")
  58. butNext = $0
  59. }
  60. /^PREV:/ {
  61. gsub(/^PREV: */,"")
  62. butPrev = $0
  63. }
  64. /^Title:/ {
  65. gsub(/^Title: */,"")
  66. print "void title(void) {"
  67. print " printf(\"%s\\n\",\"" $0 "\");"
  68. print "}"
  69. }
  70. /^Header:/ {
  71. gsub(/^Header: */,"")
  72. print "void header(void) {"
  73. print " printf(\"%s\\n\",\"" $0 "\");"
  74. print "}"
  75. }
  76. /^Page:/ {
  77. page++
  78. if (elem_aff != "") {
  79. print elem_aff
  80. elem_aff = ""
  81. }
  82. if (func_aff != "") {
  83. print func_aff
  84. func_aff = ""
  85. }
  86. print "static void page_"page"(int next,int prev) {"
  87. func_aff = func_aff " puts(\"<fieldset><div class=\\\"button-holder\\\">\");\n"
  88. #usepost = "formmethod=Post"
  89. func_aff = func_aff " if (prev) puts(\"<input type=\\\"submit\\\" " usepost " formaction=\\\"survey.prev\\\" onclick='this.form.action=\\\"survey.prev\\\";' value=\\\"" butPrev "\\\">\");\n"
  90. func_aff = func_aff " if (next) puts(\"<input type=\\\"submit\\\" formaction=\\\"survey\\\" onclick='this.form.action=\\\"survey\\\";' value=\\\"" butNext "\\\">\");\n"
  91. func_aff = func_aff " puts(\"</div></fieldset>\");\n"
  92. func_aff = func_aff "}\n"
  93. af = " autofocus=\\\"autofocus\\\" "
  94. if ($2 ~ /^\(.*\)$/)
  95. pagecond[page] = $2
  96. }
  97. /^Section:/ {
  98. }
  99. /^Q:/{
  100. if (elem_aff != "") {
  101. print elem_aff
  102. elem_aff = ""
  103. }
  104. if ($2 ~ /^\(.*\)$/) {
  105. elem_aff = " }"
  106. print " if " $2 " {"
  107. $2 = ""
  108. }
  109. gsub(/^Q: */,"")
  110. q = $0
  111. for (i in flagtag)
  112. delete flagtag[i]
  113. }
  114. /^TQ:/ {
  115. tq_aff = ""
  116. if ($2 ~ /^\(.*\)$/) {
  117. tq_aff = " }"
  118. print " if " $2 " {"
  119. $2 = ""
  120. }
  121. gsub(/^TQ: */,"")
  122. print " puts(\"<tr><td>" $0 "</td>\");"
  123. # 0 is for not selected, 1..n for the selection
  124. e = next_elem(n+1)
  125. eval[e] = "0-n"
  126. for (i = 1;i <= tn;i++) {
  127. if (tr[i] in flagtag)
  128. flagcond[flagtag[tr[i]]] = "(key."e" == " i ")"
  129. common="<td class=snug><input value=\\\""i"\\\" id=\\\"" e i"\\\" name=\\\""e"\\\"" af required
  130. print " if (key."e" == "i")"
  131. print " puts(\"" common radio_checked ">\");"
  132. print " else"
  133. print " puts(\"" common radio ">\");"
  134. print " puts(\"<label for=" e i ">" tr[i] "</label></td>\");"
  135. af = ""
  136. }
  137. print " puts(\"</tr>\");"
  138. for (i in flagtag)
  139. delete flagtag[i]
  140. if (tq_aff != "") {
  141. print tq_aff
  142. tq_aff = ""
  143. }
  144. }
  145. /^TR:/ {
  146. gsub(/^TR: */,"")
  147. tn = split($0,tr,"/")
  148. print " puts(\"<fieldset>\");"
  149. print " puts(\"<legend>" q "</legend>\");"
  150. print " puts(\"<table border=\\\"0\\\">\");"
  151. elem_aff = " puts(\"</table></fieldset>\");\n" elem_aff
  152. }
  153. /^F:/ {
  154. gsub(/^F: */,"")
  155. split($0,r,"=")
  156. flagtag[r[2]] = r[1]
  157. }
  158. /^R:/ {
  159. gsub(/^R: */,"")
  160. n = split($0,r,"/")
  161. print " puts(\"<fieldset>\");"
  162. print " puts(\"<legend>" q "</legend>\");"
  163. # 0 is for not selected, 1..n for the selection
  164. e = next_elem(n+1)
  165. print " puts(\"<div class=\\\"button-holder\\\">\");"
  166. eval[e] = "0-n"
  167. for (i = 1;i <= n;i++) {
  168. if (r[i] in flagtag)
  169. flagcond[flagtag[r[i]]] = "(key."e" == " i ")"
  170. common="<input value=\\\""i"\\\" id=\\\"" e i"\\\" name=\\\""e"\\\"" af required
  171. print " if (key."e" == "i")"
  172. print " puts(\"" common radio_checked ">\");"
  173. print " else"
  174. print " puts(\"" common radio ">\");"
  175. print " puts(\"<label for=" e i ">" r[i] "</label>\");"
  176. af = ""
  177. }
  178. print " puts(\"</div></fieldset>\");"
  179. }
  180. /^D:/ {
  181. gsub(/^D: */,"")
  182. n = split($0,r,"/")
  183. print " puts(\"<fieldset>\");"
  184. print " puts(\"<legend>" q "</legend>\");"
  185. # 0 is for not selected, 1..n for the selection
  186. e = next_elem(n+1)
  187. eval[e] = "0-n"
  188. print " puts(\"<select name=\\\""e"\\\" "af" "required">\");"
  189. af=""
  190. print " puts(\"<option value=\\\"0\\\">----</option>\");"
  191. for (i = 1;i <= n;i++) {
  192. if (r[i] in flagtag)
  193. flagcond[flagtag[r[i]]] = "(key."e" == " i ")"
  194. print " if (key."e" == "i")"
  195. print " puts(\"<option value=\\\""i"\\\" selected>"r[i]"</option>\");"
  196. print " else"
  197. print " puts(\"<option value=\\\""i"\\\">"r[i]"</option>\");"
  198. }
  199. print " puts(\"</select>\");"
  200. print " puts(\"</fieldset>\");"
  201. }
  202. /^C:/ {
  203. gsub(/^C: */,"")
  204. n = split($0,r,"/")
  205. print " puts(\"<fieldset>\");"
  206. print " puts(\"<legend>" q "</legend>\");"
  207. for (i = 1;i <= n;i++) {
  208. e = next_elem(2)
  209. if (r[i] in flagtag)
  210. flagcond[flagtag[r[i]]] = "(key."e" == 1)"
  211. checkboxes[page] = checkboxes[page] ":" e
  212. eval[e] = "0-n"
  213. common = "<input value=\\\""1"\\\" " af " id=\\\"" e "\\\" name=\\\""e"\\\" "
  214. print " if (key."e" == 1)"
  215. print " puts(\"" common checkbox_checked ">\");"
  216. print " else"
  217. print " puts(\"" common checkbox ">\");"
  218. print " puts(\"<label for=" e ">"r[i]"</label>\");"
  219. af = ""
  220. }
  221. print " puts(\"</fieldset>\");"
  222. }
  223. /^A:/ {
  224. gsub(/^A: */,"")
  225. print " puts(\"<fieldset>\");"
  226. print " puts(\"<legend>" q "</legend>\");"
  227. if ($0 == "Date") {
  228. e = next_elem(2013-15-1970+1+1)
  229. eval[e] = "0-n"
  230. print " printf(\"<select name=\\\""e"\\\" "af" %s "required">\\n\","
  231. print " parmerr."e"?"errstyle":\"\");"
  232. for(y = 1969;y <= 2013-15;y++) { # 1969 maps to ----
  233. lab = y
  234. if (y == 1969)
  235. lab = "----"
  236. print " if ("y-1969" == key."e")"
  237. print " puts(\"<option value=\\\""y-1969"\\\" selected>"lab"</option>\");"
  238. print " else"
  239. print " puts(\"<option value=\\\""y-1969"\\\">"lab"</option>\");"
  240. }
  241. print " puts(\"</select>\");"
  242. e = next_elem(13)
  243. eval[e] = "0-n"
  244. print " printf(\"<select name=\\\""e"\\\" "af" %s "required">\\n\","
  245. print " parmerr."e"?"errstyle":\"\");"
  246. print " puts(\"<option value=\\\"X\\\">--</option>\");"
  247. for(m = 0;m <= 12;m++) {
  248. lab = m
  249. if (m == 0)
  250. lab = "--"
  251. print " if ("m" == key."e")"
  252. print " puts(\"<option value=\\\""m"\\\" selected>"lab"</option>\");"
  253. print " else"
  254. print " puts(\"<option value=\\\""m"\\\">"lab"</option>\");"
  255. }
  256. print " puts(\"</select>\");"
  257. e = next_elem(32)
  258. eval[e] = "0-n"
  259. print " printf(\"<select name=\\\""e"\\\" "af" %s "required">\\n\","
  260. print " parmerr."e"?"errstyle":\"\");"
  261. for(d = 0;d <= 31;d++) {
  262. lab = d
  263. if (d == 0)
  264. lab = "--"
  265. print " if ("d" == key."e")"
  266. print " puts(\"<option value=\\\""d"\\\" selected>"lab"</option>\");"
  267. print " else"
  268. print " puts(\"<option value=\\\""d"\\\">"lab"</option>\");"
  269. }
  270. print " puts(\"</select>\");"
  271. }
  272. else if (/Number [0-9]*-[1-9][0-9]*/) {
  273. e = next_elem(256)
  274. eval[e] = "#"
  275. elen[e] = $2
  276. print " printf(\"<input type="$0" name=\\\""e"\\\" "af" %s value=\\\"%s\\\" "required">\","
  277. print " parmerr."e"?"errstyle":\"\",as_text_"e"());"
  278. }
  279. else if (/Text [0-9]*-[1-9][0-9]*/) {
  280. e = next_elem(256)
  281. eval[e] = "@"
  282. elen[e] = $2
  283. print " printf(\"<input type="$0" name=\\\""e"\\\" "af" %s value=\\\"%s\\\" "required">\","
  284. print " parmerr."e"?"errstyle":\"\",as_text_"e"());"
  285. }
  286. else
  287. print "Unknown TAG: "$0 >"/dev/stderr"
  288. af=""
  289. print " puts(\"</fieldset>\");"
  290. }
  291. function eval_number(e ,fld,n,var) {
  292. split(elen[e],fld,"-")
  293. n = fld[2]
  294. while (n >= 3) {
  295. var = "key." i "3_" int(n/3)
  296. print " "var" = 0;"
  297. print " if (*v) {"
  298. print " int n = strlen(v);"
  299. print " if (n >= 3) {"
  300. print " "var" = 1+(v[0]-'0')*100+(v[1]-'0')*10+(v[2]-'0');"
  301. print " v += 3;"
  302. print " }"
  303. print " else if (n >= 1)"
  304. print " "var" = 1001+ (*v++)-'0';"
  305. print " }"
  306. n-=3
  307. }
  308. if ((n == 1) || (fld[2] == 3)) {
  309. var = "key." i "1"
  310. print " "var" = 0;"
  311. print " if (*v) {"
  312. print " if (strlen(v) == 1)"
  313. print " "var" = 1+(*v++)-'0';"
  314. print " }"
  315. }
  316. if (n == 2) {
  317. var = "key." i "2"
  318. print " "var" = 0;"
  319. print " if (*v) {"
  320. print " int n = strlen(v);"
  321. print " if (n == 2) {"
  322. print " "var" = 1+(v[0]-'0')*10+(v[1]-'0');"
  323. print " v += 2;"
  324. print " }"
  325. print " else if (n == 1)"
  326. print " "var" = 101+ (*v++)-'0';"
  327. print " }"
  328. }
  329. print " return (*v == 0);"
  330. }
  331. function eval_text(e ,fld) {
  332. split(elen[e],fld,"-")
  333. print " for (i = 0;i < " fld[2]";i++) {"
  334. print " key."e"[i] = *v;"
  335. print " if (*v)"
  336. print " v++;"
  337. print " }"
  338. print " return 1;"
  339. }
  340. function in_buf_number(e ,fld) {
  341. split(elen[e],fld,"-")
  342. n = fld[2]
  343. while (n >= 3) {
  344. var = "key." i "3_" int(n/3)
  345. print " if ("var" != 0) {"
  346. print " if ("var" <= 1000) {"
  347. print " char tmp[5];"
  348. print " sprintf(tmp,\"%d\","var"+1000-1);"
  349. print " strncpy(buf,tmp+1,3);"
  350. print " buf += 3;"
  351. print " }"
  352. print " else"
  353. print " *buf++ = '0' + ("var"-1001);"
  354. print " }"
  355. n-=3
  356. }
  357. if ((n == 1) || (fld[2] == 3)) {
  358. var = "key." i "1"
  359. print " if (("var" != 0) && ("var" <= 10))"
  360. print " *buf++ = '0' + "var"-1;"
  361. }
  362. if (n == 2) {
  363. print " if ("var" != 0) {"
  364. print " if ("var" <= 100) {"
  365. print " char tmp[4];"
  366. print " sprintf(tmp,\"%d\","var"+100-1);"
  367. print " strncpy(buf,tmp+1,2);"
  368. print " buf += 2;"
  369. print " }"
  370. print " else"
  371. print " *buf++ = '0' + ("var"-101);"
  372. print " }"
  373. }
  374. print " *buf = 0;"
  375. }
  376. function in_buf_text(e ,fld) {
  377. split(elen[e],fld,"-")
  378. print " strncpy(buf,key."e","fld[2]");"
  379. print " buf["fld[2]"] = 0;"
  380. }
  381. END {
  382. if (elem_aff != "") {
  383. print elem_aff
  384. elem_aff = ""
  385. }
  386. if (func_aff != "") {
  387. print func_aff
  388. func_aff = ""
  389. }
  390. print "void questions(unsigned int page) {"
  391. for (i = 0;i <= page;i++) {
  392. print " if (page == " i ") page_" i "("(i!=page)","(i != 0)");"
  393. }
  394. print "}"
  395. print "static int get_val(const char *v) {"
  396. print " int p=-1;"
  397. print " while (*v) {"
  398. print " if ((*v >= '0') && (*v <= '9')) {"
  399. print " if (p < 0) p = 0;"
  400. print " p = p*10 + (*v++) - '0';"
  401. print " }"
  402. print " else"
  403. print " return -1;"
  404. print " }"
  405. print " return p;"
  406. print "}"
  407. for (i in el_range) {
  408. print "static int eval_"i"(const char *v) {"
  409. if (eval[i] == "0-n") {
  410. print " int p = get_val(v);"
  411. print " if (p < 0) { parmerr."i" = 1; return 0; }"
  412. print " if (p >= "el_range[i]") { parmerr."i" = 1; return 0; }"
  413. print " key."i" = p;"
  414. print " return 1;"
  415. }
  416. else if (eval[i] ~ /[#@]/) {
  417. print " int i;"
  418. split(elen[i],fld,"-")
  419. if (eval[i] == "#") {
  420. print " for (i = 0;v[i];i++)"
  421. print " if ((v[i] < '0') || (v[i] > '9')) {"
  422. print " parmerr."i" = 1;"
  423. print " return 0;"
  424. print " }"
  425. }
  426. if (fld[0] > 0)
  427. print " if (strlen(v) < "fld[1]") {parmerr."i" = 1;return 0;}"
  428. print " if (strlen(v) > "fld[2]") {parmerr."i" = 1;return 0;}"
  429. if (eval[i] == "#")
  430. eval_number(i)
  431. else
  432. eval_text(i)
  433. }
  434. else
  435. print " return 0;"
  436. print "}"
  437. }
  438. print "int eval_parm(char *k,char *v) {"
  439. print " if (strcmp(k,\"key\") == 0) return 1;"
  440. for (i in el_range)
  441. print " if (strcmp(k,\"" i "\") == 0) return eval_"i"(v);"
  442. print " return 0;"
  443. print "}"
  444. print "char shared_buffer[1024];"
  445. for (i in el_range) {
  446. if (eval[i] ~ /[#@]/) {
  447. print "char *as_text_"i"(void) {"
  448. print " char *buf = shared_buffer;"
  449. if (eval[i] == "#")
  450. in_buf_number(i)
  451. else
  452. in_buf_text(i)
  453. print " return shared_buffer;"
  454. print "}"
  455. }
  456. }
  457. print "void empty_checkboxes(unsigned int page) {"
  458. suffix=""
  459. for (i in checkboxes) {
  460. print " if (page == "i") {"
  461. n = split(checkboxes[i],r,":")
  462. for (j = 2;j <= n;j++)
  463. print " key." r[j] " = 0;"
  464. print " }"
  465. }
  466. print "}"
  467. print "int present_page(unsigned int page) {"
  468. suffix=""
  469. for (i = 0;i <= page;i++) {
  470. print " if (page == "i")"
  471. if (i in pagecond)
  472. print " return " pagecond[i] ";"
  473. else
  474. print " return 1;"
  475. }
  476. print " return 0;"
  477. print "}"
  478. f="auto/keystruct.h"
  479. print "#define KEY_LEN sizeof(struct key_s)" >f
  480. for (i in el_range)
  481. if (eval[i] ~ /[#@]/)
  482. print "char *as_text_"i"(void);" >f
  483. print "struct key_s {" >f
  484. split("@:#:0-n",evals,":")
  485. for (k = 1;k <= 3;k++) {
  486. ev = evals[k]
  487. for (i in el_range)
  488. if (eval[i] == ev) {
  489. if (ev == "0-n")
  490. print " unsigned int " i ":" el_bits[i] "; // " el_range[i] >f
  491. if (ev == "@") {
  492. split(elen[i],fld,"-")
  493. print " char " i "[" fld[2] "]; // text" >f
  494. }
  495. if (ev == "#") {
  496. split(elen[i],fld,"-")
  497. n = fld[2]
  498. while (n >= 3) {
  499. print " unsigned int " i "3_" int(n/3) ":10; // 0=0|1=1001..1010|3=1..1000 digits" >f
  500. n-=3
  501. }
  502. if ((n == 1) || (fld[2] == 3))
  503. print " unsigned int " i "1:4; // 0=0|1=1..10 digits" >f
  504. if (n == 2)
  505. print " unsigned int " i "2:7; // 0=0|1=101..110|2=1..100 digits" >f
  506. }
  507. }
  508. }
  509. m=2
  510. for (bits=1;m < page;bits++)
  511. m *= 2
  512. print " unsigned int page:" bits ";" >f
  513. print "} key;" >f
  514. print "struct parmerr_s {" >f
  515. for (i in el_range) {
  516. print " int " i ":1;" >f
  517. }
  518. print "} parmerr;" >f
  519. for (i in flagcond)
  520. print "#define "i" " flagcond[i] >f
  521. }