PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Hsml/SubLang.c

https://bitbucket.org/radare/screws
C | 535 lines | 446 code | 70 blank | 19 comment | 86 complexity | 400c1897c437f07f4526c982341b99fb MD5 | raw file
Possible License(s): GPL-2.0
  1. #include <time.h>
  2. #if !SCREWS_MODULE
  3. #include "main.h"
  4. extern char *b;
  5. #endif
  6. #include "Cache.h"
  7. #include "SubLang.h"
  8. sublang_t *sublang;
  9. int nlangs;
  10. long int filelen=0;
  11. int donotexec=0;
  12. char *dip=DIP;
  13. char *buf=0;
  14. char *p=0;
  15. void *resolve_sym(void *handle, const char *symbol)
  16. {
  17. void *sym;
  18. if(!(sym = dlsym(handle, symbol)))
  19. printf("%s\n", dlerror());
  20. return sym;
  21. }
  22. void hsml_init()
  23. {
  24. int i,j;
  25. char *mod_path = getenv("HSML_LANG_MOD");
  26. char def_mod_path[] = ".";
  27. char path[1023];
  28. char *langs[]={"c","perl","python","brainfuck","clisp",0};//,"clisp","ml","ruby","lua","java","csharp",0};
  29. int bytes;
  30. char *cwd;
  31. void **ptr;
  32. if(!mod_path) mod_path = def_mod_path;
  33. sublang = (sublang_t *)calloc(sizeof(langs)/sizeof(char**),sizeof(sublang_t));
  34. for(i=0, j=0; langs[i]; i++)
  35. {
  36. if(mod_path[0] != '/')
  37. {
  38. bytes = snprintf(path, 1023, "%s/%s/lang_%s.so", cwd = getcwd(NULL, 0), mod_path, langs[i]);
  39. free(cwd);
  40. }
  41. else bytes = snprintf(path, 1023, "%s/lang_%s.so", mod_path, langs[i]);
  42. if(bytes >= 1023){
  43. continue;
  44. }
  45. if(!(sublang[j].module = dlopen(path, RTLD_NOW)))
  46. {printf("%s\n", dlerror()); continue;}
  47. if(!(sublang[j].lang = resolve_sym(sublang[j].module, "lang"))) continue;
  48. if(!(sublang[j].file = resolve_sym(sublang[j].module, "file"))) continue;
  49. if(!(sublang[j].init = resolve_sym(sublang[j].module, "init"))) continue;
  50. if(!(sublang[j].get_path_from_env = resolve_sym(sublang[j].module, "get_path_from_env"))) continue;
  51. if(!(sublang[j].show_config = resolve_sym(sublang[j].module, "show_config"))) continue;
  52. if(!(sublang[j].print_begin = resolve_sym(sublang[j].module, "print_begin"))) continue;
  53. if(!(sublang[j].print_end = resolve_sym(sublang[j].module, "print_end"))) continue;
  54. if(!(sublang[j].print_end_nl = resolve_sym(sublang[j].module, "print_end_nl"))) continue;
  55. if(!(sublang[j].code_begin = resolve_sym(sublang[j].module, "code_begin"))) continue;
  56. if(!(sublang[j].code_end = resolve_sym(sublang[j].module, "code_end"))) continue;
  57. if(!(sublang[j].codevar = resolve_sym(sublang[j].module, "codevar"))) continue;
  58. if(!(sublang[j].exec = resolve_sym(sublang[j].module, "exec"))) continue;
  59. if(!(sublang[j].cache_exec = resolve_sym(sublang[j].module, "cache_exec"))) continue;
  60. if(!(ptr = resolve_sym(sublang[j].module, "cache"))) continue;
  61. *(char *)ptr = cache;
  62. if(!(ptr = resolve_sym(sublang[j].module, "cacherule"))) continue;
  63. *(char *)ptr = cacherule;
  64. if(!(ptr = resolve_sym(sublang[j].module, "pwd"))) continue;
  65. *(char **)ptr = pwd;
  66. if(!(ptr = resolve_sym(sublang[j].module, "tmp"))) continue;
  67. *(char **)ptr = tmp;
  68. if(!(ptr = resolve_sym(sublang[j].module, "cache_output_add"))) continue;
  69. *ptr = (void *)&cache_output_add;
  70. if(!(ptr = resolve_sym(sublang[j].module, "cache_print"))) continue;
  71. *ptr = (void *)&cache_print;
  72. if(!(ptr = resolve_sym(sublang[j].module, "cache_exec_add"))) continue;
  73. *ptr = (void *)&cache_exec_add;
  74. sublang[j].init();
  75. j++;
  76. }
  77. nlangs = j;
  78. for(i = 0; i < j; i++)
  79. {
  80. sublang[i].show_config();
  81. }
  82. }
  83. void show_lang_config()
  84. {
  85. int i;
  86. for(i=0; sublang[i], i<=nlangs; i++)
  87. sublang[i].show_config();
  88. }
  89. bool
  90. isOk(file1,file2)
  91. char *file1; /* Source File */
  92. char *file2; /* Binary File */
  93. {
  94. struct stat f1,f2;
  95. if (
  96. stat(file1,&f1) |
  97. stat(file2,&f2)
  98. ) return false; /* ErrOccRrd */
  99. if (f1.st_mtime>f2.st_mtime)
  100. return false;
  101. return true;
  102. }
  103. void
  104. subLang_doExec(file,lang)
  105. char *file;
  106. int lang;
  107. {
  108. // call lang module exec func
  109. sublang[lang].exec(file, buf, tmp);
  110. /* XXX type another message ;) */
  111. fprintf(stderr,"Error executing script. Check language environs with '-l\n");
  112. sublang[lang].show_config();
  113. perror("PERROR MSG: ");
  114. }
  115. /* TODO : tokenizeBUffer doesn't cleans all params */
  116. char *
  117. tokenizeBuffer(buf)
  118. char *buf;
  119. {
  120. // XXX must strdup, etc. tokenizeBuffer, return malloqed buffer
  121. char *p=buf;
  122. /* Clear $, etc.. */
  123. while(1)
  124. {
  125. p=strchr(p,'\"');
  126. if (!p) break;
  127. p[0]='\'';
  128. }
  129. return buf;
  130. }
  131. int
  132. SubLang_include(files,lang)
  133. char *files;
  134. int lang;
  135. {
  136. FILE *fd;
  137. char *next, *tmpbuf, *end = p+3, *old_b;
  138. int b_dif;
  139. long flen;
  140. int i=0;
  141. if(files[0] == ' ') files++;
  142. while(next = strchr(files,' '))
  143. {
  144. next[0] = '\0';
  145. next++;
  146. while(sublang[i].file)
  147. {
  148. if (strstr(files,sublang[i].file))
  149. break;
  150. i++;
  151. }
  152. if (sublang[i].file)
  153. {
  154. if (i!=lang)
  155. {
  156. sublang[i].print_begin(buf);
  157. strcat(buf,
  158. "<font color='red'>"
  159. "WARNING: Cannot include files written in other language"
  160. "</font>\n");
  161. sublang[i].print_end(buf);
  162. continue;
  163. }
  164. }
  165. fd=fopen(files,"r");
  166. if(fd) {
  167. fseek(fd,0,SEEK_END);
  168. flen = ftell(fd);
  169. fseek(fd,0,SEEK_SET);
  170. filelen += flen;
  171. old_b = b;
  172. b = (char *)realloc(b,filelen+1);
  173. b_dif = b-old_b;
  174. p += b_dif;
  175. next += b_dif;
  176. end += b_dif;
  177. tmpbuf = strdup(end);
  178. fread(end,flen,1,fd);
  179. end = end+flen;
  180. strcpy(end,tmpbuf);
  181. free(tmpbuf);
  182. fclose(fd);
  183. } else {
  184. sublang[i].print_begin(buf);
  185. strcat(buf,"Cannot include file '");
  186. strcat(buf,files);
  187. strcat(buf,"'");
  188. sublang[i].print_end(buf);
  189. }
  190. files = next;
  191. }
  192. return 1;
  193. }
  194. void
  195. execSubLang(file,fd,lang,len)
  196. char *file;
  197. FILE *fd;
  198. int lang;
  199. long int len;
  200. {
  201. int i=0;
  202. int code=0;
  203. int codevar=0;
  204. FILE *fdi;
  205. long flen;
  206. bool newline=false;
  207. char *e,*e2,*c,*p2;
  208. char *include;
  209. char *tmpbuf;
  210. char *exe;
  211. filelen=len;
  212. /* Allocate */
  213. buf=(char *)malloc(filelen*2+10+len);
  214. buf[0]='\0';
  215. /* Concat include file */
  216. include=malloc(strlen(dip)+20);
  217. sprintf(include,"%s/include%s",dip,sublang[lang]);
  218. fdi=fopen(include,"r");
  219. if (fdi)
  220. {
  221. fseek(fd,0,SEEK_END);
  222. flen=ftell(fd);
  223. fseek(fd,0,SEEK_SET);
  224. /* Realocate */
  225. buf=(char *)realloc(buf,filelen+10+flen);
  226. fread(buf,len,1,fdi);
  227. buf[flen]=0;
  228. fclose(fdi);
  229. }
  230. /** BEGIN OF DOCUMENT */
  231. sublang[lang].code_begin(buf);
  232. /** PARSE THE TAGS */
  233. filelen=len;
  234. p=b;
  235. while(p<b+filelen)
  236. {
  237. e=strchr(p,'\n');
  238. if (e) {
  239. newline=true;
  240. e[0]='\0'; /* EOS */
  241. } else {
  242. e=strchr(p,'\0');
  243. }
  244. if (!code)
  245. {
  246. c=strstr(p,"<?");
  247. codevar=0;
  248. } else {
  249. c=strstr(p,"?>");
  250. if (c) /* tag found in this line. continue and disable code */
  251. {
  252. c[0]=0;
  253. strcat(buf,p);
  254. p=c+2;
  255. code=0;
  256. continue;
  257. }
  258. }
  259. if (c)
  260. {
  261. c[0]='\0';
  262. /** Tags */
  263. switch(c[2])
  264. {
  265. case '-': // comment
  266. p=strstr(c+2,"-?>");
  267. if (!p)
  268. {
  269. sublang[lang].print_begin(buf);
  270. strcat(buf,"comment tag not closed");
  271. sublang[lang].print_end(buf);
  272. goto END_EXEC_SUBLANG;
  273. }
  274. p=p+2;
  275. continue;
  276. case '^': // header
  277. p=strstr(c+2,"?>");
  278. if (!p)
  279. {
  280. sublang[lang].print_begin(buf);
  281. strcat(buf,"tag not closed");
  282. sublang[lang].print_end(buf);
  283. goto END_EXEC_SUBLANG;
  284. }
  285. p[0]=0;
  286. p+=2;
  287. addHeader(c+3);
  288. continue;
  289. case '=': // printvar
  290. codevar=1;
  291. newline=false;
  292. break;
  293. case '%': // directives
  294. p=strstr(c+2,"?>");
  295. if (!p)
  296. {
  297. sublang[lang].print_begin(buf);
  298. strcat(buf,"tag not closed");
  299. sublang[lang].print_end(buf);
  300. goto END_EXEC_SUBLANG;
  301. }
  302. p[0]=0;
  303. p+=2;
  304. if(e = strstr(c+3, "cacherule="))
  305. {
  306. if(!strncmp(e+10, "never", 5)) cacherule = CACHERULE_NEVER;
  307. else if(!strncmp(e+10, "noinput", 7) && cacherule) cacherule = CACHERULE_NOINPUT;
  308. else if(!strncmp(e+10, "time", 4) && cacherule) cacherule = CACHERULE_TIME;
  309. }
  310. /* TODO parse hsml directives */
  311. //printf("HSML directives(%s)\n",c+3);
  312. continue;
  313. case '&': // include
  314. p=strstr(c+2,"?>");
  315. if (!p)
  316. {
  317. sublang[lang].print_begin(buf);
  318. strcat(buf,"tag not closed");
  319. sublang[lang].print_end(buf);
  320. goto END_EXEC_SUBLANG;
  321. }
  322. p[0]='\0';
  323. SubLang_include(c+3,lang);
  324. p+=2;
  325. continue;
  326. case '@': // include at top
  327. p=strstr(c+2,"?>");
  328. if (!p)
  329. {
  330. sublang[lang].print_begin(buf);
  331. strcat(buf,"tag not closed");
  332. sublang[lang].print_end(buf);
  333. goto END_EXEC_SUBLANG;
  334. }
  335. p[0]=0;
  336. tmpbuf=strdup(buf);
  337. buf=(char *)realloc(buf,filelen+strlen(c+3));
  338. strcpy(buf,c+3);
  339. strcat(buf,tmpbuf);
  340. free(tmpbuf);
  341. p=p+3;
  342. continue;
  343. default:
  344. if (code)
  345. strcat(buf,p);
  346. break;
  347. }
  348. }
  349. if (!code||!newline)
  350. {
  351. p2=tokenizeBuffer(p);
  352. if (strlen(p2))
  353. {
  354. sublang[lang].print_begin(buf);
  355. strcat(buf,p2);
  356. if (newline) sublang[lang].print_end(buf);
  357. else sublang[lang].print_end_nl(buf);
  358. }
  359. }
  360. if (c)
  361. {
  362. code = !code;
  363. p=c+2;
  364. c=strstr(p,"?>");
  365. if (c) { c[0]='\0'; c++;}
  366. }
  367. if (code)
  368. {
  369. if (codevar)
  370. {
  371. sublang[lang].codevar(buf, p);
  372. } else {
  373. strcat(buf,p);
  374. strcat(buf,"\n");
  375. }
  376. if (c)
  377. {
  378. code=0;
  379. e=c;
  380. }
  381. }
  382. if (e) p=e+1;
  383. else p=c+1;
  384. }
  385. END_EXEC_SUBLANG:
  386. if(cache_should_output(file))
  387. {
  388. printHeaders();
  389. cache_print(file);
  390. return;
  391. }
  392. if(cache_should_exec(file))
  393. {
  394. printHeaders();
  395. cache_exec(file, lang);
  396. return;
  397. }
  398. if (p) strcat(buf,p);
  399. /** ENDOF DOCUMENT */
  400. sublang[lang].code_end(buf);
  401. /* Headers */
  402. printHeaders();
  403. /* Body */
  404. if (donotexec)
  405. printf("%s",buf);
  406. else
  407. subLang_doExec(file,lang);
  408. //free(buf);
  409. }
  410. bool
  411. subLang(file,len)
  412. char *file;
  413. long int len;
  414. {
  415. int lang=0;
  416. char buf[1024];
  417. char *token;
  418. FILE *fd;
  419. fd = fopen(file,"r");
  420. if ( fd == NULL )
  421. {
  422. fprintf(stderr,"subLang(%s,%d): cannot open file\n",file,len);
  423. return false;
  424. }
  425. if (strstr(file,".hsml"))
  426. {
  427. fgets(buf,1000,fd);
  428. if (!strncmp(buf,"#!",2))
  429. {
  430. buf[strlen(buf)-1]=0;
  431. while(sublang[lang].lang &&
  432. strcmp(sublang[lang].lang,buf+2))
  433. { lang++; }
  434. /* language not found */
  435. if (!sublang[lang].lang)
  436. {
  437. printf("Language hashbang '%s' not found!\n",buf+2);
  438. fclose(fd);
  439. return true;
  440. }
  441. b=b+strlen(buf)+1;
  442. len-=strlen(buf)+1;
  443. } else {
  444. fclose(fd);
  445. return false;
  446. }
  447. } else {
  448. while(sublang[lang].file)
  449. {
  450. if (strstr(file,sublang[lang].file))
  451. break;
  452. lang++;
  453. }
  454. }
  455. if (sublang[lang].file)
  456. {
  457. while(token=strchr(file,'/')) // Strip path access
  458. file = token+1;
  459. //getPathFromEnv();
  460. execSubLang(file,fd,lang,len);
  461. fclose(fd);
  462. return true; // Found
  463. }
  464. return false;
  465. }