You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1503 lines
37 KiB

  1. #include <sys/time.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <errno.h>
  7. #include <sys/stat.h>
  8. #include "smem.h"
  9. char *Sfile_fgets();
  10. int Sregex_string();
  11. int Sregex_trimline();
  12. #include "ctyp.h"
  13. #include "cgen.h"
  14. /* ----------------------------- CgeN ------------------------- */
  15. int Cgen_new(cgen,flag)
  16. struct CgeN **cgen;
  17. int flag;
  18. {
  19. int ret;
  20. struct CgeN *c;
  21. *cgen= c= TSOB_FELD(struct CgeN,1);
  22. if(c==NULL) {
  23. fprintf(stderr,"+++ Cannot create cgen object : %s\n",strerror(errno));
  24. return(-1);
  25. }
  26. c->classname= NULL;
  27. c->structname= NULL;
  28. c->functname= NULL;
  29. c->is_managed_list= 0;
  30. c->is_bossless_list= 0;
  31. c->gen_for_stic= 1;
  32. c->make_ansi= 0;
  33. c->make_lowercase= 0;
  34. c->global_include_file[0]= 0;
  35. c->global_include_fp= NULL;
  36. c->elements= NULL;
  37. c->last_element= NULL;
  38. c->may_overwrite= 0;
  39. c->fp= NULL;
  40. c->filename[0]= 0;
  41. c->ptt_fp= NULL;
  42. c->ptt_filename[0]= 0;
  43. c->msg[0]= 0;
  44. return(1);
  45. }
  46. int Cgen_destroy(cgen,flag)
  47. struct CgeN **cgen;
  48. int flag;
  49. {
  50. struct CgeN *c;
  51. struct CtyP *ct,*next_ct;
  52. c= *cgen;
  53. if(c==NULL)
  54. return(0);
  55. if(c->fp!=NULL)
  56. fclose(c->fp);
  57. if(c->ptt_fp!=NULL)
  58. fclose(c->ptt_fp);
  59. Sregex_string(&(c->classname),NULL,0);
  60. Sregex_string(&(c->structname),NULL,0);
  61. Sregex_string(&(c->functname),NULL,0);
  62. for(ct= c->elements; ct!=NULL; ct= next_ct) {
  63. next_ct= ct->next;
  64. Ctyp_destroy(&ct,0);
  65. }
  66. free((char *) c);
  67. *cgen= NULL;
  68. return(1);
  69. }
  70. int Cgen_make_names(cgen,flag)
  71. struct CgeN *cgen;
  72. int flag;
  73. {
  74. int l;
  75. if(Sregex_string(&(cgen->structname),cgen->classname,0)<=0)
  76. return(-1);
  77. if(Sregex_string(&(cgen->functname),cgen->classname,0)<=0)
  78. return(-1);
  79. if(!cgen->make_lowercase) {
  80. cgen->structname[0]= toupper(cgen->structname[0]);
  81. l= strlen(cgen->structname);
  82. cgen->structname[l-1]= toupper(cgen->structname[l-1]);
  83. cgen->functname[0]= toupper(cgen->functname[0]);
  84. }
  85. return(1);
  86. }
  87. int Cgen_read_fp(cgen,fp,flag)
  88. struct CgeN *cgen;
  89. FILE *fp;
  90. int flag;
  91. /*
  92. bit0= return 0 if eof at classname
  93. */
  94. {
  95. char line[4096],*cpt,*bpt;
  96. int ret;
  97. line[0]= 0;
  98. while(1) {
  99. printf("[-list] classname ?\n");
  100. if(Sfile_fgets(line,sizeof(line)-1,fp)==NULL) {
  101. if(!(flag&1))
  102. return(2);
  103. no_name:;
  104. sprintf(cgen->msg,"No classname given.");
  105. return(0);
  106. }
  107. printf("%s\n",line);
  108. if(strcmp(line,"@@@")==0)
  109. return(2);
  110. if(line[0]==0 || line[0]=='#') {
  111. /* >>> record class comments */;
  112. } else
  113. break;
  114. }
  115. cpt= line;
  116. while(cpt[0]=='-') {
  117. /* look for management specifiers:
  118. -l* listable by prev-next chain
  119. */
  120. if(cpt[1]=='l' || cpt[1]=='L') {
  121. cgen->is_managed_list= 1;
  122. } else if(cpt[1]=='b' || cpt[1]=='B') {
  123. cgen->is_bossless_list= 1;
  124. }
  125. while(*cpt!=0 && !isspace(*cpt)) cpt++;
  126. while(*cpt!=0 && isspace(*cpt)) cpt++;
  127. if(*cpt==0)
  128. goto no_name;
  129. }
  130. if(Sregex_string(&(cgen->classname),cpt,0)<=0)
  131. return(-1);
  132. ret= Cgen_make_names(cgen,0);
  133. if(ret<=0)
  134. return(ret);
  135. while(1) {
  136. ret= Ctyp_read_fp(&(cgen->last_element),fp,cgen->msg,
  137. !!cgen->make_lowercase);
  138. if(ret<=0)
  139. return(ret);
  140. if(ret==2)
  141. break;
  142. if(cgen->elements==NULL)
  143. cgen->elements= cgen->last_element;
  144. }
  145. if(cgen->is_managed_list) {
  146. sprintf(line,"-c struct %s *prev",cgen->structname);
  147. ret= Ctyp_new_from_line(&(cgen->last_element),cgen->last_element,
  148. line,cgen->msg,0);
  149. if(ret<=0)
  150. return(ret);
  151. if(cgen->elements==NULL)
  152. cgen->elements= cgen->last_element;
  153. sprintf(line,"-c struct %s *next",cgen->structname);
  154. ret= Ctyp_new_from_line(&(cgen->last_element),cgen->last_element,
  155. line,cgen->msg,0);
  156. if(ret<=0)
  157. return(ret);
  158. }
  159. return(1);
  160. }
  161. int Cgen_open_wfile(cgen,flag)
  162. struct CgeN *cgen;
  163. int flag;
  164. /*
  165. bit0-3: modes
  166. 0= open cgen->fp
  167. 1= open cgen->ptt_fp
  168. 2= open cgen->global_include_fp
  169. */
  170. {
  171. struct stat stbuf;
  172. int ret, mode;
  173. char *name, fmode[4];
  174. FILE *fp;
  175. mode= flag&15;
  176. strcpy(fmode,"w");
  177. if(mode==0) {
  178. name= cgen->filename;
  179. fp= cgen->fp;
  180. cgen->fp= NULL;
  181. } else if(mode==1) {
  182. name= cgen->ptt_filename;
  183. fp= cgen->ptt_fp;
  184. cgen->ptt_fp= NULL;
  185. } else if(mode==2) {
  186. strcpy(fmode,"a");
  187. name= cgen->global_include_file;
  188. fp= cgen->global_include_fp;
  189. cgen->global_include_fp= NULL;
  190. } else {
  191. fprintf(stderr,"+++ Cgen_open_wfile : program error : unknown mode %d\n",
  192. mode);
  193. ret= -1; goto ex;
  194. }
  195. if(fmode[0]=='w' && stat(name,&stbuf)!=-1 && !cgen->may_overwrite) {
  196. sprintf(cgen->msg,"File '%s' already existing.",name);
  197. ret= 0; goto ex;
  198. }
  199. if(fp!=NULL)
  200. {fclose(fp); fp= NULL;}
  201. fp= fopen(name,fmode);
  202. if(fp==NULL) {
  203. sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
  204. name,fmode,strerror(errno));
  205. ret= 0; goto ex;
  206. }
  207. ret= 1;
  208. ex:;
  209. if(mode==0)
  210. cgen->fp= fp;
  211. else if(mode==1)
  212. cgen->ptt_fp= fp;
  213. else if(mode==2)
  214. cgen->global_include_fp= fp;
  215. return(ret);
  216. }
  217. int Cgen_write_datestr(cgen,flag)
  218. struct CgeN *cgen;
  219. int flag;
  220. /*
  221. bit0= operate on ptt (= ANSI prototype) file rather than on internal header
  222. */
  223. {
  224. time_t t0;
  225. char timetext[81];
  226. FILE *fp;
  227. if(flag&1)
  228. fp= cgen->ptt_fp;
  229. else
  230. fp= cgen->fp;
  231. t0= time(0);
  232. strftime(timetext,sizeof(timetext),"%a, %d %b %Y %H:%M:%S GMT",
  233. gmtime(&t0));
  234. fprintf(fp,"/* ( derived from stub generated by CgeN on %s ) */\n",
  235. timetext);
  236. return(1);
  237. }
  238. int Cgen_write_h(cgen,flag)
  239. struct CgeN *cgen;
  240. int flag;
  241. {
  242. int ret,i,pointer_level;
  243. FILE *fp= NULL;
  244. struct CtyP *ct;
  245. char pvt[16],macro_name[4096],*cpt;
  246. if(cgen->make_ansi) {
  247. sprintf(cgen->filename,"%s_private.h",cgen->classname);
  248. strcpy(pvt,"_private");
  249. } else {
  250. sprintf(cgen->filename,"%s.h",cgen->classname);
  251. strcpy(pvt,"");
  252. }
  253. ret= Cgen_open_wfile(cgen,0);
  254. if(ret<=0)
  255. goto ex;
  256. sprintf(macro_name,"%s%s_includeD",cgen->functname,pvt);
  257. macro_name[0]= toupper(macro_name[0]);
  258. fp= cgen->fp;
  259. /* >>> print class comments */;
  260. fprintf(fp,"\n");
  261. fprintf(fp,"#ifndef %s\n",macro_name);
  262. fprintf(fp,"#define %s\n",macro_name);
  263. fprintf(fp,"\n");
  264. if(strlen(cgen->global_include_file)!=0) {
  265. fprintf(fp,"#include \"%s\"\n",cgen->global_include_file);
  266. fprintf(fp,"\n\n");
  267. }
  268. if(cgen->make_ansi)
  269. fprintf(fp,"/* For function prototypes see file %s.h */\n",cgen->classname);
  270. fprintf(fp,"\n\n");
  271. fprintf(fp,"struct %s {\n",cgen->structname);
  272. fprintf(fp,"\n");
  273. ct= cgen->elements;
  274. for(ct= cgen->elements;ct!=NULL;ct= ct->next) {
  275. if(ct->is_comment) {
  276. if(ct->name[0]==0) {
  277. fprintf(fp,"\n");
  278. continue;
  279. }
  280. fprintf(fp," /* ");
  281. for(cpt= ct->name; *cpt!=0; cpt++) {
  282. fprintf(fp,"%c",*cpt);
  283. if(cpt[0]=='*' && cpt[1]=='/')
  284. fprintf(fp," ");
  285. }
  286. fprintf(fp," */\n");
  287. continue;
  288. }
  289. if(ct->is_volatile)
  290. fprintf(fp," volatile");
  291. if(Ctyp_is_struct(ct,0))
  292. fprintf(fp," struct");
  293. else if(ct->is_unsigned)
  294. fprintf(fp," unsigned");
  295. fprintf(fp," %s ",ct->dtype);
  296. pointer_level= Ctyp_get_pointer_level(ct,0);
  297. for(i=0;i<pointer_level;i++)
  298. fprintf(fp,"*");
  299. fprintf(fp,"%s",ct->name);
  300. if(ct->array_size>0)
  301. fprintf(fp,"[%lu]",ct->array_size);
  302. fprintf(fp,";\n");
  303. }
  304. fprintf(fp,"\n");
  305. fprintf(fp,"};\n");
  306. fprintf(fp,"\n");
  307. fprintf(fp,"\n");
  308. fprintf(fp,"#endif /* %s */\n",macro_name);
  309. fprintf(fp,"\n");
  310. Cgen_write_datestr(cgen,0);
  311. /* Eventually write start of ANSI prototype include file */
  312. if(!cgen->make_ansi)
  313. goto after_ansi_h;
  314. sprintf(cgen->ptt_filename,"%s.h",cgen->classname);
  315. ret= Cgen_open_wfile(cgen,1);
  316. if(ret<=0)
  317. goto ex;
  318. sprintf(macro_name,"%s_includeD",cgen->functname);
  319. macro_name[0]= toupper(macro_name[0]);
  320. fp= cgen->ptt_fp;
  321. /* >>> print class comments */;
  322. fprintf(fp,"\n");
  323. fprintf(fp,"#ifndef %s\n",macro_name);
  324. fprintf(fp,"#define %s\n",macro_name);
  325. fprintf(fp,"\n\n");
  326. if(strlen(cgen->global_include_file)!=0) {
  327. fprintf(fp,"#include \"%s\"\n",cgen->global_include_file);
  328. } else {
  329. fprintf(fp,"struct %s;\n",cgen->structname);
  330. }
  331. fprintf(fp,"\n\n");
  332. fprintf(fp,"/* For inner details see file %s_private.h */\n",cgen->classname);
  333. fprintf(fp,"\n\n");
  334. after_ansi_h:;
  335. if(strlen(cgen->global_include_file)==0)
  336. goto after_global_include;
  337. ret= Cgen_open_wfile(cgen,2);
  338. if(ret<=0)
  339. goto ex;
  340. fprintf(cgen->global_include_fp,"struct %s;\n",cgen->structname);
  341. after_global_include:;
  342. ret= 1;
  343. ex:;
  344. if(cgen->fp!=NULL)
  345. {fclose(cgen->fp); cgen->fp= NULL;}
  346. /* ( note: cgen->ptt_fp stays open ) */
  347. if(cgen->global_include_fp!=NULL)
  348. {fclose(cgen->global_include_fp); cgen->global_include_fp= NULL;}
  349. return(ret);
  350. }
  351. int Cgen_write_to_ptt(cgen,ptt,flag)
  352. struct CgeN *cgen;
  353. char *ptt;
  354. int flag;
  355. {
  356. if(cgen->ptt_fp==NULL)
  357. return(-1);
  358. fprintf(cgen->ptt_fp,"%s;\n",ptt);
  359. return(1);
  360. }
  361. int Cgen_finish_public_h(cgen,flag)
  362. struct CgeN *cgen;
  363. int flag;
  364. {
  365. char macro_name[4096];
  366. if(cgen->ptt_fp==NULL)
  367. return(-1);
  368. fprintf(cgen->ptt_fp,"\n");
  369. fprintf(cgen->ptt_fp,"\n");
  370. sprintf(macro_name,"%s_includeD",cgen->functname);
  371. macro_name[0]= toupper(macro_name[0]);
  372. fprintf(cgen->ptt_fp,"#endif /* %s */\n",macro_name);
  373. fprintf(cgen->ptt_fp,"\n");
  374. Cgen_write_datestr(cgen,1);
  375. if(cgen->ptt_fp!=NULL)
  376. {fclose(cgen->ptt_fp); cgen->ptt_fp= NULL;}
  377. return(1);
  378. }
  379. int Cgen_write_c_head(cgen,flag)
  380. struct CgeN *cgen;
  381. int flag;
  382. {
  383. int ret,is_pointer,is_struct,array_size;
  384. FILE *fp= NULL;
  385. struct CtyP *ct,*hct;
  386. char *dtype= NULL,*name= NULL;
  387. fp= cgen->fp;
  388. fprintf(fp,"\n");
  389. fprintf(fp,"/*\n");
  390. fprintf(fp," cc -g -c %s.c\n",cgen->classname);
  391. fprintf(fp,"*/\n");
  392. Cgen_write_datestr(cgen,0);
  393. fprintf(fp,"\n");
  394. fprintf(fp,"#include <sys/types.h>\n");
  395. fprintf(fp,"#include <stdlib.h>\n");
  396. fprintf(fp,"#include <stdio.h>\n");
  397. fprintf(fp,"#include <string.h>\n");
  398. fprintf(fp,"#include <errno.h>\n");
  399. fprintf(fp,"\n");
  400. fprintf(fp,"#include \"%s.h\"\n",cgen->classname);
  401. if(cgen->make_ansi) {
  402. fprintf(fp,"#include \"%s_private.h\"\n",cgen->classname);
  403. }
  404. fprintf(fp,"\n");
  405. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  406. if(ct->is_comment)
  407. continue;
  408. Ctyp_get_dtype(ct,&dtype,0);
  409. Ctyp_get_type_mod(ct,&is_pointer,&is_struct,&array_size,0);
  410. /*
  411. fprintf(stderr,"DEBUG: %s %s\n",(is_struct?"struct ":""),dtype);
  412. */
  413. /* already included ? */
  414. if(strcmp(dtype,cgen->structname)==0)
  415. continue;
  416. for(hct= cgen->elements; hct!=NULL && hct!=ct; hct= hct->next) {
  417. if(hct->is_comment)
  418. continue;
  419. if(hct->dtype!=NULL)
  420. if(strcmp(hct->dtype,dtype)==0)
  421. break;
  422. }
  423. if(hct!=ct && hct!=NULL)
  424. continue;
  425. if(is_struct && (isupper(dtype[0]) && isupper(dtype[strlen(dtype)-1]))) {
  426. dtype[0]= tolower(dtype[0]);
  427. dtype[strlen(dtype)-1]= tolower(dtype[strlen(dtype)-1]);
  428. fprintf(fp,"#include \"%s.h\"\n",dtype);
  429. }
  430. }
  431. fprintf(fp,"\n");
  432. if(cgen->gen_for_stic==1) {
  433. fprintf(fp,"#include \"../s_tools/smem.h\"\n");
  434. fprintf(fp,"#include \"../s_tools/sfile.h\"\n");
  435. fprintf(fp,"#include \"../s_tools/sregex.h\"\n");
  436. fprintf(fp,"\n");
  437. } else if(cgen->gen_for_stic==2) {
  438. fprintf(fp,"#include \"smem.h\"\n");
  439. fprintf(fp,"\n");
  440. }
  441. fprintf(fp,"\n");
  442. fprintf(fp,"/* -------------------------- %s ----------------------- */\n",
  443. cgen->structname);
  444. fprintf(fp,"\n");
  445. if(dtype!=NULL)
  446. Sregex_string(&dtype,NULL,0);
  447. if(name!=NULL)
  448. Sregex_string(&name,NULL,0);
  449. return(1);
  450. }
  451. int Cgen_write_c_new(cgen,flag)
  452. struct CgeN *cgen;
  453. int flag;
  454. {
  455. int ret,pointer_level,management,boss_parm= 0;
  456. unsigned long array_size;
  457. FILE *fp= NULL;
  458. struct CtyP *ct;
  459. char ptt[4096];
  460. fp= cgen->fp;
  461. if(!cgen->is_bossless_list) {
  462. if(cgen->elements!=NULL)
  463. if(strcmp(cgen->elements->name,"boss")==0 && cgen->elements->is_struct &&
  464. cgen->elements->is_pointer==1 && cgen->elements->no_initializer==0)
  465. boss_parm= 1;
  466. if(cgen->is_managed_list && boss_parm==0)
  467. fprintf(stderr,
  468. "+++ Warning: -l %s without -v struct ... *boss as first attribute\n",
  469. cgen->classname);
  470. }
  471. fprintf(fp,"\n");
  472. if(cgen->make_ansi) {
  473. sprintf(ptt,"int %s_new(struct %s **objpt, ",
  474. cgen->functname,cgen->structname);
  475. if(boss_parm)
  476. sprintf(ptt+strlen(ptt),"struct %s *boss, ",cgen->elements->dtype);
  477. sprintf(ptt+strlen(ptt),"int flag)");
  478. fprintf(fp,"%s\n",ptt);
  479. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  480. if(ret<=0)
  481. return(ret);
  482. } else {
  483. fprintf(fp,"int %s_new(objpt,\n",cgen->functname);
  484. if(boss_parm)
  485. fprintf(fp,"boss,");
  486. fprintf(fp,"flag)\n");
  487. fprintf(fp,"struct %s **objpt;\n",cgen->structname);
  488. if(boss_parm)
  489. fprintf(fp,"struct %s *boss;",cgen->elements->dtype);
  490. fprintf(fp,"int flag;\n");
  491. }
  492. fprintf(fp,"{\n");
  493. fprintf(fp," struct %s *o;\n",cgen->structname);
  494. /* Is an array index i needed ? */
  495. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  496. if(ct->is_comment || ct->no_initializer)
  497. continue;
  498. if(ct->array_size>0)
  499. if(strcmp(ct->dtype,"char")!=0) {
  500. fprintf(fp," int i;\n");
  501. break;
  502. }
  503. }
  504. fprintf(fp,"\n");
  505. if(cgen->gen_for_stic)
  506. fprintf(fp," *objpt= o= TSOB_FELD(struct %s,1);\n",cgen->structname);
  507. else
  508. fprintf(fp," *objpt= o= (struct %s *) malloc(sizeof(struct %s));\n",
  509. cgen->structname, cgen->structname);
  510. fprintf(fp," if(o==NULL)\n");
  511. fprintf(fp," return(-1);\n");
  512. fprintf(fp,"\n");
  513. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  514. if(ct->is_comment || ct->no_initializer)
  515. continue;
  516. array_size= Ctyp_get_array_size(ct,0);
  517. pointer_level= Ctyp_get_pointer_level(ct,0);
  518. if(ct==cgen->elements && boss_parm) {
  519. fprintf(fp," o->boss= boss;\n");
  520. } else if(array_size>0) {
  521. if(strcmp(ct->dtype,"char")==0) {
  522. fprintf(fp," o->%s[0]= 0;\n;",ct->name);
  523. } else if(pointer_level>0) {
  524. fprintf(fp," for(i=0;i<%lu;i++)\n",array_size);
  525. fprintf(fp," o->%s[i]= NULL;\n",ct->name);
  526. } else {
  527. fprintf(fp," for(i=0;i<%lu;i++)\n",array_size);
  528. fprintf(fp," o->%s[i]= 0;\n",ct->name);
  529. }
  530. } else if(pointer_level>0) {
  531. fprintf(fp," o->%s= NULL;\n",ct->name);
  532. } else
  533. fprintf(fp," o->%s= 0;\n",ct->name);
  534. }
  535. fprintf(fp,"\n");
  536. fprintf(fp," return(1);\n");
  537. fprintf(fp,"/*\n");
  538. fprintf(fp,"failed:;\n");
  539. fprintf(fp," %s_destroy(objpt,0);\n",cgen->functname);
  540. fprintf(fp," return(-1);\n");
  541. fprintf(fp,"*/\n");
  542. fprintf(fp,"}\n");
  543. fprintf(fp,"\n");
  544. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  545. if(ct->is_comment)
  546. continue;
  547. management= Ctyp_get_management(ct,0);
  548. if(management==4) {
  549. if(ct->next==NULL) {
  550. no_last_pt:;
  551. sprintf(cgen->msg,
  552. "Lonely -l found. A -v of same type must follow.\nName is : %s",
  553. ct->name);
  554. return(0);
  555. }
  556. if(strcmp(ct->next->dtype,ct->dtype)!=0
  557. || ct->next->is_pointer!=ct->is_pointer)
  558. goto no_last_pt;
  559. ct->next->with_getter= ct->next->with_setter= 0;
  560. ret= Cgen_write_c_new_type(cgen,ct,ct->next,0);
  561. if(ret<=0)
  562. return(ret);
  563. }
  564. }
  565. return(1);
  566. }
  567. int Cgen_write_c_new_type(cgen,ct_first,ct_last,flag)
  568. struct CgeN *cgen;
  569. struct CtyP *ct_first,*ct_last;
  570. int flag;
  571. {
  572. int ret,l,management,pointer_level,i;
  573. FILE *fp= NULL;
  574. char funct[4096],classname[4096],*npt,ptt[4096];
  575. strcpy(funct,ct_first->dtype);
  576. strcpy(classname,funct);
  577. l= strlen(funct);
  578. if(l>0) {
  579. if(cgen->make_lowercase)
  580. funct[0]= tolower(funct[0]);
  581. else
  582. funct[0]= toupper(funct[0]);
  583. funct[l-1]= tolower(funct[l-1]);
  584. classname[0]= tolower(funct[0]);
  585. classname[l-1]= funct[l-1];
  586. }
  587. fp= cgen->fp;
  588. fprintf(fp,"\n");
  589. if(cgen->make_ansi) {
  590. sprintf(ptt, "int %s_new_%s(struct %s *o, int flag)",
  591. cgen->functname,ct_first->name,cgen->structname);
  592. fprintf(fp,"%s\n",ptt);
  593. if(ct_first->with_setter) {
  594. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  595. if(ret<=0)
  596. return(ret);
  597. }
  598. } else {
  599. fprintf(fp,"int %s_new_%s(o,flag)\n",cgen->functname,ct_first->name);
  600. fprintf(fp,"struct %s *o;\n",cgen->structname);
  601. fprintf(fp,"int flag;\n");
  602. }
  603. fprintf(fp,"{\n");
  604. fprintf(fp," int ret;\n");
  605. fprintf(fp," struct %s *c= NULL;\n",ct_first->dtype);
  606. fprintf(fp,"\n");
  607. if(ct_first->bossless_list)
  608. fprintf(fp," ret= %s_new(&c,0);\n",funct);
  609. else
  610. fprintf(fp," ret= %s_new(&c,o,0);\n",funct);
  611. fprintf(fp," if(ret<=0)\n");
  612. fprintf(fp," return(ret);\n");
  613. fprintf(fp," %s_link(c,o->%s,0);\n",funct,ct_last->name);
  614. fprintf(fp," o->%s= c;\n",ct_last->name);
  615. fprintf(fp," if(o->%s==NULL)\n",ct_first->name);
  616. fprintf(fp," o->%s= c;\n",ct_first->name);
  617. fprintf(fp," return(1);\n");
  618. fprintf(fp,"}\n");
  619. fprintf(fp,"\n");
  620. ret= 1;
  621. ex:;
  622. return(ret);
  623. }
  624. int Cgen_write_c_destroy(cgen,flag)
  625. struct CgeN *cgen;
  626. int flag;
  627. {
  628. int ret,l,management,pointer_level,i;
  629. FILE *fp= NULL;
  630. struct CtyP *ct,*next;
  631. char funct[4096],*npt,ptt[4096];
  632. fp= cgen->fp;
  633. fprintf(fp,"\n");
  634. if(cgen->make_ansi) {
  635. sprintf(ptt, "int %s_destroy(struct %s **objpt, int flag)",
  636. cgen->functname,cgen->structname);
  637. fprintf(fp,"%s\n",ptt);
  638. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  639. if(ret<=0)
  640. return(ret);
  641. } else {
  642. fprintf(fp,"int %s_destroy(objpt,flag)\n",cgen->functname);
  643. fprintf(fp,"struct %s **objpt;\n",cgen->structname);
  644. fprintf(fp,"int flag;\n");
  645. }
  646. fprintf(fp,"{\n");
  647. fprintf(fp," struct %s *o;\n",cgen->structname);
  648. fprintf(fp,"\n");
  649. fprintf(fp," o= *objpt;\n");
  650. fprintf(fp," if(o==NULL)\n");
  651. fprintf(fp," return(0);\n");
  652. fprintf(fp,"\n");
  653. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  654. if(ct->is_comment)
  655. continue;
  656. management= Ctyp_get_management(ct,0);
  657. if(management==1 || management==4) {
  658. strcpy(funct,ct->dtype);
  659. l= strlen(funct);
  660. if(l>0) {
  661. if(cgen->make_lowercase)
  662. funct[0]= tolower(funct[0]);
  663. else
  664. funct[0]= toupper(funct[0]);
  665. funct[l-1]= tolower(funct[l-1]);
  666. }
  667. if(strcmp(ct->dtype,"char")==0) {
  668. if(cgen->gen_for_stic==1)
  669. fprintf(fp," Sregex_string(");
  670. else if(cgen->gen_for_stic==2)
  671. fprintf(fp," Smem_freE((char *) ");
  672. else
  673. fprintf(fp," free(");
  674. } else if(strcmp(ct->dtype,"LstrinG")==0 || management==4)
  675. fprintf(fp," %s_destroy_all(",funct);
  676. else
  677. fprintf(fp," %s_destroy(",funct);
  678. pointer_level= Ctyp_get_pointer_level(ct,0)-2;
  679. for(i=0; i>pointer_level; i--)
  680. fprintf(fp,"&");
  681. for(i=0; i<pointer_level; i++)
  682. fprintf(fp,"*");
  683. fprintf(fp,"(o->%s)",ct->name);
  684. if(strcmp(ct->dtype,"char")==0) {
  685. if(cgen->gen_for_stic==1)
  686. fprintf(fp,",NULL,0);\n");
  687. else
  688. fprintf(fp,");\n");
  689. } else
  690. fprintf(fp,",0);\n");
  691. } else if(management==2) {
  692. next= ct->next;
  693. if(next==NULL) {
  694. broken_chain:;
  695. sprintf(cgen->msg,
  696. "Lonely -c found. They have to appear in pairs.\nName is : %s",
  697. ct->name);
  698. ret= 0; goto ex;
  699. }
  700. if(next->management!=3)
  701. goto broken_chain;
  702. fprintf(fp," if(o->%s!=NULL)\n",ct->name);
  703. fprintf(fp," o->%s->%s= o->%s;\n",ct->name,next->name,next->name);
  704. fprintf(fp," if(o->%s!=NULL)\n",next->name);
  705. fprintf(fp," o->%s->%s= o->%s;\n",next->name,ct->name,ct->name);
  706. ct= next;
  707. }
  708. }
  709. fprintf(fp,"\n");
  710. if(cgen->gen_for_stic)
  711. fprintf(fp," Smem_freE((char *) o);\n");
  712. else
  713. fprintf(fp," free((char *) o);\n");
  714. fprintf(fp," *objpt= NULL;\n");
  715. fprintf(fp," return(1);\n");
  716. fprintf(fp,"}\n");
  717. fprintf(fp,"\n");
  718. if(cgen->is_managed_list){
  719. ret= Cgen_write_c_destroy_all(cgen,0);
  720. if(ret<=0)
  721. goto ex;
  722. }
  723. ret= 1;
  724. ex:;
  725. return(ret);
  726. }
  727. int Cgen_write_c_destroy_all(cgen,flag)
  728. struct CgeN *cgen;
  729. int flag;
  730. {
  731. int ret,l,management,pointer_level,i;
  732. FILE *fp= NULL;
  733. struct CtyP *ct;
  734. char ptt[4096];
  735. fp= cgen->fp;
  736. fprintf(fp,"\n");
  737. if(cgen->make_ansi) {
  738. sprintf(ptt, "int %s_destroy_all(struct %s **objpt, int flag)",
  739. cgen->functname, cgen->structname);
  740. fprintf(fp,"%s\n",ptt);
  741. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  742. if(ret<=0)
  743. return(ret);
  744. } else {
  745. fprintf(fp,"int %s_destroy_all(objpt,flag)\n",cgen->functname);
  746. fprintf(fp,"struct %s **objpt;\n",cgen->structname);
  747. fprintf(fp,"int flag;\n");
  748. }
  749. fprintf(fp,"{\n");
  750. fprintf(fp," struct %s *o,*n;\n",cgen->structname);
  751. fprintf(fp,"\n");
  752. fprintf(fp," o= *objpt;\n");
  753. fprintf(fp," if(o==NULL)\n");
  754. fprintf(fp," return(0);\n");
  755. fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
  756. fprintf(fp," for(;o!=NULL;o= n) {\n");
  757. fprintf(fp," n= o->next;\n");
  758. fprintf(fp," %s_destroy(&o,0);\n",cgen->functname);
  759. fprintf(fp," }\n");
  760. fprintf(fp," *objpt= NULL;\n");
  761. fprintf(fp," return(1);\n");
  762. fprintf(fp,"}\n");
  763. fprintf(fp,"\n");
  764. ret= 1;
  765. ex:;
  766. return(ret);
  767. }
  768. int Cgen_write_c_access(cgen,flag)
  769. struct CgeN *cgen;
  770. int flag;
  771. {
  772. int ret,l,mgt,pointer_level,i;
  773. FILE *fp= NULL;
  774. struct CtyP *ct;
  775. char funct[4096],*npt,ptt[4096];
  776. fp= cgen->fp;
  777. for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
  778. if(ct->is_comment)
  779. continue;
  780. pointer_level= Ctyp_get_pointer_level(ct,0);
  781. if(Ctyp_get_with_getter(ct,0)<=0)
  782. goto after_getter;
  783. fprintf(fp,"\n");
  784. if(cgen->make_ansi) {
  785. sprintf(ptt, "int %s_get_%s(struct %s *o, ",
  786. cgen->functname,ct->name,cgen->structname);
  787. if(Ctyp_is_struct(ct,0))
  788. strcat(ptt,"struct ");
  789. strcat(ptt,ct->dtype);
  790. strcat(ptt," ");
  791. for(i=0; i<pointer_level+1; i++)
  792. strcat(ptt,"*");
  793. if(Ctyp_get_array_size(ct,0)>0)
  794. strcat(ptt,"*");
  795. strcat(ptt,"pt");
  796. if(ct->management==4)
  797. strcat(ptt,", int idx");
  798. strcat(ptt,", int flag)");
  799. fprintf(fp,"%s\n",ptt);
  800. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  801. if(ret<=0)
  802. return(ret);
  803. } else {
  804. fprintf(fp,"int %s_get_%s(o,pt",cgen->functname,ct->name);
  805. if(ct->management==4)
  806. fprintf(fp,",idx");
  807. fprintf(fp,",flag)\n");
  808. fprintf(fp,"struct %s *o;\n",cgen->structname);
  809. if(Ctyp_is_struct(ct,0))
  810. fprintf(fp,"struct ");
  811. fprintf(fp,"%s ",ct->dtype);
  812. for(i=0; i<pointer_level+1; i++)
  813. fprintf(fp,"*");
  814. if(Ctyp_get_array_size(ct,0)>0)
  815. fprintf(fp,"*");
  816. fprintf(fp,"pt;\n");
  817. if(ct->management==4)
  818. fprintf(fp,"int idx;\n");
  819. fprintf(fp,"int flag;\n");
  820. }
  821. if(ct->management==4)
  822. fprintf(fp,"/* Note: idx==-1 fetches the last item of the list */\n");
  823. fprintf(fp,"{\n");
  824. if(ct->management==4) {
  825. strcpy(funct,ct->dtype);
  826. l= strlen(funct);
  827. if(cgen->make_lowercase)
  828. funct[0]= tolower(funct[0]);
  829. if(l>1)
  830. funct[l-1]= tolower(funct[l-1]);
  831. fprintf(fp," if(idx==-1) {\n");
  832. fprintf(fp," *pt= o->%s;\n",ct->next->name);
  833. fprintf(fp," return(*pt!=NULL);\n");
  834. fprintf(fp," }\n");
  835. fprintf(fp," return(%s_by_idx(o->%s,(flag&1?1:idx),pt,flag&1));\n",
  836. funct,ct->name);
  837. } else {
  838. fprintf(fp," *pt= o->%s;\n",ct->name);
  839. fprintf(fp," return(1);\n");
  840. }
  841. fprintf(fp,"}\n");
  842. fprintf(fp,"\n");
  843. after_getter:;
  844. if(Ctyp_get_with_setter(ct,0)<=0)
  845. goto after_setter;
  846. /* <<< provisory : develop a setter for arrays */
  847. if(Ctyp_get_array_size(ct,0)>0)
  848. goto after_setter;
  849. mgt= Ctyp_get_management(ct,0);
  850. if(mgt==0 ||
  851. (mgt==1 && pointer_level==1)) {
  852. /* -value or -managed pointers */
  853. /* was: -value or -managed char * */
  854. /* (mgt==1 && strcmp(ct->dtype,"char")==0 && pointer_level==1)) { */
  855. fprintf(fp,"\n");
  856. if(cgen->make_ansi) {
  857. sprintf(ptt, "int %s_set_%s(struct %s *o, ",
  858. cgen->functname,ct->name,cgen->structname);
  859. if(Ctyp_is_struct(ct,0))
  860. strcat(ptt,"struct ");
  861. strcat(ptt,ct->dtype);
  862. strcat(ptt," ");
  863. for(i=0; i<pointer_level; i++)
  864. strcat(ptt,"*");
  865. strcat(ptt,"value, int flag)");
  866. fprintf(fp,"%s\n",ptt);
  867. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  868. if(ret<=0)
  869. return(ret);
  870. } else {
  871. fprintf(fp,"int %s_set_%s(o,value,flag)\n",cgen->functname,ct->name);
  872. fprintf(fp,"struct %s *o;\n",cgen->structname);
  873. if(Ctyp_is_struct(ct,0))
  874. fprintf(fp,"struct ");
  875. fprintf(fp,"%s ",ct->dtype);
  876. for(i=0; i<pointer_level; i++)
  877. fprintf(fp,"*");
  878. fprintf(fp,"value;\n");
  879. fprintf(fp,"int flag;\n");
  880. }
  881. fprintf(fp,"{\n");
  882. if(mgt==1 && strcmp(ct->dtype,"char")==0) {
  883. if(cgen->gen_for_stic==1) {
  884. fprintf(fp," if(Sregex_string(&(o->%s),value,0)<=0)\n",ct->name);
  885. fprintf(fp," return(-1);\n");
  886. } else if(cgen->gen_for_stic==2) {
  887. fprintf(fp," if(Smem_clone_string(&(o->%s),value)<=0)\n",ct->name);
  888. fprintf(fp," return(-1);\n");
  889. } else {
  890. fprintf(fp," char *cpt;\n");
  891. fprintf(fp,"\n");
  892. fprintf(fp," cpt= malloc(strlen(value)+1);\n");
  893. fprintf(fp," if(cpt==NULL)\n");
  894. fprintf(fp," return(-1);\n");
  895. fprintf(fp," o->%s= cpt;\n",ct->name);
  896. fprintf(fp," \n");
  897. }
  898. } else {
  899. fprintf(fp," o->%s= value;\n",ct->name);
  900. }
  901. fprintf(fp," return(1);\n");
  902. fprintf(fp,"}\n");
  903. fprintf(fp,"\n");
  904. }
  905. after_setter:;
  906. }
  907. if(cgen->is_managed_list) {
  908. fprintf(fp,"\n");
  909. if(cgen->make_ansi) {
  910. sprintf(ptt,"int %s_link(struct %s *o, struct %s *link, int flag)",
  911. cgen->functname,cgen->structname,cgen->structname);
  912. fprintf(fp,"%s\n",ptt);
  913. /* if(cgen->readonly) */
  914. {
  915. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  916. if(ret<=0)
  917. return(ret);
  918. }
  919. } else {
  920. fprintf(fp,"int %s_link(o,link,flag)\n",cgen->functname);
  921. fprintf(fp,"struct %s *o;\n",cgen->structname);
  922. fprintf(fp,"struct %s *link;\n",cgen->structname);
  923. fprintf(fp,"int flag;\n");
  924. }
  925. fprintf(fp,"/*\n");
  926. fprintf(fp," bit0= insert as link->prev rather than as link->next\n");
  927. fprintf(fp,"*/\n");
  928. fprintf(fp,"{\n");
  929. fprintf(fp," if(o->prev!=NULL)\n");
  930. fprintf(fp," o->prev->next= o->next;\n");
  931. fprintf(fp," if(o->next!=NULL)\n");
  932. fprintf(fp," o->next->prev= o->prev;\n");
  933. fprintf(fp," o->prev= o->next= NULL;\n");
  934. fprintf(fp," if(link==NULL)\n");
  935. fprintf(fp," return(1);\n");
  936. fprintf(fp," if(flag&1) {\n");
  937. fprintf(fp," o->next= link;\n");
  938. fprintf(fp," o->prev= link->prev;\n");
  939. fprintf(fp," if(o->prev!=NULL)\n");
  940. fprintf(fp," o->prev->next= o;\n");
  941. fprintf(fp," link->prev= o;\n");
  942. fprintf(fp," } else {\n");
  943. fprintf(fp," o->prev= link;\n");
  944. fprintf(fp," o->next= link->next;\n");
  945. fprintf(fp," if(o->next!=NULL)\n");
  946. fprintf(fp," o->next->prev= o;\n");
  947. fprintf(fp," link->next= o;\n");
  948. fprintf(fp," }\n");
  949. fprintf(fp," return(1);\n");
  950. fprintf(fp,"}\n");
  951. fprintf(fp,"\n");
  952. fprintf(fp,"\n");
  953. if(cgen->make_ansi) {
  954. sprintf(ptt,"int %s_count(struct %s *o, int flag)",
  955. cgen->functname,cgen->structname);
  956. fprintf(fp,"%s\n",ptt);
  957. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  958. if(ret<=0)
  959. return(ret);
  960. } else {
  961. fprintf(fp,"int %s_count(o,flag)\n",cgen->functname);
  962. fprintf(fp,"struct %s *o;\n",cgen->structname);
  963. fprintf(fp,"int flag;\n");
  964. }
  965. fprintf(fp,"/* flag: bit1= count from start of list */\n");
  966. fprintf(fp,"{\n");
  967. fprintf(fp," int counter= 0;\n");
  968. fprintf(fp,"\n");
  969. fprintf(fp," if(flag&2)\n");
  970. fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
  971. fprintf(fp," for(;o!=NULL;o= o->next)\n");
  972. fprintf(fp," counter++;\n");
  973. fprintf(fp," return(counter);\n");
  974. fprintf(fp,"}\n");
  975. fprintf(fp,"\n");
  976. fprintf(fp,"\n");
  977. if(cgen->make_ansi) {
  978. sprintf(ptt,
  979. "int %s_by_idx(struct %s *o, int idx, struct %s **pt, int flag)",
  980. cgen->functname,cgen->structname,cgen->structname);
  981. fprintf(fp,"%s\n",ptt);
  982. ret= Cgen_write_to_ptt(cgen, ptt, 0);
  983. if(ret<=0)
  984. return(ret);
  985. } else {
  986. fprintf(fp,"int %s_count(o,idx,pt,flag)\n",cgen->functname);
  987. fprintf(fp,"struct %s *o;\n",cgen->structname);
  988. fprintf(fp,"int idx;\n");
  989. fprintf(fp,"struct %s **pt;\n",cgen->structname);
  990. fprintf(fp,"int flag;\n");
  991. }
  992. fprintf(fp,
  993. "/* flag: bit0= fetch first (idx<0) or last (idx>0) item in list\n");
  994. fprintf(fp,
  995. " bit1= address from start of list */\n");
  996. fprintf(fp,"{\n");
  997. fprintf(fp," int i,abs_idx;\n");
  998. fprintf(fp," struct %s *npt;\n",cgen->structname);
  999. fprintf(fp,"\n");
  1000. fprintf(fp," if(flag&2)\n");
  1001. fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
  1002. fprintf(fp," abs_idx= (idx>0?idx:-idx);\n");
  1003. fprintf(fp," *pt= o;\n");
  1004. fprintf(fp," for(i= 0;(i<abs_idx || (flag&1)) && *pt!=NULL;i++) {\n");
  1005. fprintf(fp," if(idx>0)\n");
  1006. fprintf(fp," npt= o->next;\n");
  1007. fprintf(fp," else\n");
  1008. fprintf(fp," npt= o->prev;\n");
  1009. fprintf(fp," if(npt==NULL && (flag&1))\n");
  1010. fprintf(fp," break;\n");
  1011. fprintf(fp," *pt= npt;\n");
  1012. fprintf(fp," }\n");
  1013. fprintf(fp," return(*pt!=NULL);\n");
  1014. fprintf(fp,"}\n");
  1015. fprintf(fp,"\n");
  1016. }
  1017. return(1);
  1018. }
  1019. int Cgen_write_c_method_include(cgen,flag)
  1020. struct CgeN *cgen;
  1021. int flag;
  1022. {
  1023. FILE *fp= NULL;
  1024. char filename[4096],line[4096];
  1025. struct stat stbuf;
  1026. time_t t0;
  1027. sprintf(filename,"%s.c.methods",cgen->classname);
  1028. if(stat(filename,&stbuf)!=-1)
  1029. goto write_include;
  1030. fp= fopen(filename,"w");
  1031. if(fp==NULL) {
  1032. sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
  1033. filename,"w",strerror(errno));
  1034. return(0);
  1035. }
  1036. fprintf(fp,"\n");
  1037. fprintf(fp,"/* File %s */\n",filename);
  1038. fprintf(fp,"/* Manually provided C code for class %s */\n",
  1039. cgen->classname);
  1040. fprintf(fp,"/* This file gets copied to the end of %s.c */\n",
  1041. cgen->classname);
  1042. fprintf(fp,"\n");
  1043. fclose(fp); fp= NULL;
  1044. write_include:;
  1045. fp= fopen(filename,"r");
  1046. if(fp==NULL) {
  1047. sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
  1048. filename,"r",strerror(errno));
  1049. return(0);
  1050. }
  1051. fprintf(cgen->fp,"\n");
  1052. fprintf(cgen->fp,
  1053. "/* -------------- end of automatically regenerated code -------------- */\n");
  1054. fprintf(cgen->fp,"\n");
  1055. while(1) {
  1056. if(Sfile_fgets(line,sizeof(line)-1,fp)==NULL)
  1057. break;
  1058. fprintf(cgen->fp,"%s\n",line);
  1059. }
  1060. fclose(fp); fp= NULL;
  1061. return(1);
  1062. }
  1063. int Cgen_write_c(cgen,flag)
  1064. struct CgeN *cgen;
  1065. int flag;
  1066. /*
  1067. bit0= also write access functions *_set_* *_get_* [*_link_*]
  1068. */
  1069. {
  1070. int ret;
  1071. sprintf(cgen->filename,"%s.c",cgen->classname);
  1072. ret= Cgen_open_wfile(cgen,0);
  1073. if(ret<=0)
  1074. goto ex;
  1075. ret= Cgen_write_c_head(cgen,0);
  1076. if(ret<=0)
  1077. goto ex;
  1078. ret= Cgen_write_c_new(cgen,0);
  1079. if(ret<=0)
  1080. goto ex;
  1081. ret= Cgen_write_c_destroy(cgen,0);
  1082. if(ret<=0)
  1083. goto ex;
  1084. if(flag&1) {
  1085. ret= Cgen_write_c_access(cgen,0);
  1086. if(ret<=0)
  1087. goto ex;
  1088. }
  1089. ret= Cgen_write_c_method_include(cgen,0);
  1090. if(ret<=0)
  1091. goto ex;
  1092. if(cgen->make_ansi) { /* public .h file collected ANSI prototypes */
  1093. ret= Cgen_finish_public_h(cgen,0);
  1094. if(ret<=0)
  1095. goto ex;
  1096. }
  1097. ret= 1;
  1098. ex:;
  1099. if(cgen->fp!=NULL)
  1100. {fclose(cgen->fp); cgen->fp= NULL;}
  1101. return(ret);
  1102. }
  1103. int Cgen__write_global_include(global_include_file,flag)
  1104. char *global_include_file;
  1105. int flag;
  1106. /*
  1107. bit0= write footer rather than header
  1108. bit1= allow overwriting of existing file
  1109. */
  1110. {
  1111. FILE *fp= NULL;
  1112. int ret;
  1113. char fmode[4],timetext[81],macro_name[4096],*cpt;
  1114. time_t t0;
  1115. struct stat stbuf;
  1116. strcpy(macro_name,global_include_file);
  1117. for(cpt= macro_name; *cpt!=0; cpt++) {
  1118. if(*cpt>='A' && *cpt<='Z')
  1119. *cpt= tolower(*cpt);
  1120. else if((*cpt>='a' && *cpt<='z') || (*cpt>='0' && *cpt<='9') || *cpt=='_')
  1121. ;
  1122. else
  1123. *cpt= '_';
  1124. }
  1125. macro_name[0]= toupper(macro_name[0]);
  1126. strcat(macro_name,"_includeD");
  1127. strcpy(fmode,"w");
  1128. if(flag&1) {
  1129. strcpy(fmode,"a");
  1130. } else {
  1131. if(stat(global_include_file,&stbuf)!=-1 && !(flag&2)) {
  1132. fprintf(stderr,"+++ File '%s' already existing.",global_include_file);
  1133. ret= 0; goto ex;
  1134. }
  1135. }
  1136. fp= fopen(global_include_file,fmode);
  1137. if(fp==NULL) {
  1138. fprintf(stderr,"+++ Cannot open file '%s' in %s-mode. %s",
  1139. global_include_file,fmode,strerror(errno));
  1140. ret= 0; goto ex;
  1141. }
  1142. if(flag&1) {
  1143. fprintf(fp,"\n");
  1144. fprintf(fp,"#endif /* %s */\n\n",macro_name);
  1145. t0= time(0);
  1146. strftime(timetext,sizeof(timetext),"%a, %d %b %Y %H:%M:%S GMT",
  1147. gmtime(&t0));
  1148. fprintf(fp,"/* ( derived from stub generated by CgeN on %s ) */\n",
  1149. timetext);
  1150. } else {
  1151. fprintf(fp,"\n");
  1152. fprintf(fp,"#ifndef %s\n",macro_name);
  1153. fprintf(fp,"#define %s\n",macro_name);
  1154. fprintf(fp,"\n");
  1155. }
  1156. ex:;
  1157. if(fp!=NULL)
  1158. fclose(fp);
  1159. return(ret);
  1160. }
  1161. /* ---------------- Sfile and Sregex Emancipation copies ---------------- */
  1162. char *Sfile_fgets(line,maxl,fp)
  1163. char *line;
  1164. int maxl;
  1165. FILE *fp;
  1166. {
  1167. int l;
  1168. char *ret;
  1169. ret= fgets(line,maxl,fp);
  1170. if(ret==NULL)
  1171. return(NULL);
  1172. l= strlen(line);
  1173. if(l>0) if(line[l-1]=='\r') line[--l]= 0;
  1174. if(l>0) if(line[l-1]=='\n') line[--l]= 0;
  1175. if(l>0) if(line[l-1]=='\r') line[--l]= 0;
  1176. return(ret);
  1177. }
  1178. int Sregex_string_cut(handle,text,len,flag)
  1179. char **handle;
  1180. char *text;
  1181. int len;
  1182. int flag;
  1183. /*
  1184. bit0= append (text!=NULL)
  1185. bit1= prepend (text!=NULL)
  1186. */
  1187. {
  1188. int l=0;
  1189. char *old_handle;
  1190. if((flag&(1|2))&&*handle!=NULL)
  1191. l+= strlen(*handle);
  1192. old_handle= *handle;
  1193. if(text!=NULL) {
  1194. l+= len;
  1195. *handle= TSOB_FELD(char,l+1);
  1196. if(*handle==NULL) {
  1197. *handle= old_handle;
  1198. return(0);
  1199. }
  1200. if((flag&2) && old_handle!=NULL) {
  1201. strncpy(*handle,text,len);
  1202. strcpy((*handle)+len,old_handle);
  1203. } else {
  1204. if((flag&1) && old_handle!=NULL)
  1205. strcpy(*handle,old_handle);
  1206. else
  1207. (*handle)[0]= 0;
  1208. if(len>0)
  1209. strncat(*handle,text,len);
  1210. }
  1211. } else {
  1212. *handle= NULL;
  1213. }
  1214. if(old_handle!=NULL)
  1215. Smem_freE(old_handle);
  1216. return(1);
  1217. }
  1218. int Sregex_string(handle,text,flag)
  1219. char **handle;
  1220. char *text;
  1221. int flag;
  1222. /*
  1223. bit0= append (text!=NULL)
  1224. bit1= prepend (text!=NULL)
  1225. */
  1226. {
  1227. int ret,l=0;
  1228. if(text!=NULL)
  1229. l= strlen(text);
  1230. /* #define Sregex_looking_for_contenT 1 */
  1231. #ifdef Sregex_looking_for_contenT
  1232. /* a debugging point if a certain text content has to be caught */
  1233. if(text!=NULL)
  1234. if(strcmp(text,"clear")==0)
  1235. ret= 0;
  1236. #endif
  1237. ret= Sregex_string_cut(handle,text,l,flag&(1|2));
  1238. return(ret);
  1239. }
  1240. int Sregex_trimline(line,flag)
  1241. /*
  1242. removes line endings as well as leading and trailing blanks
  1243. */
  1244. char *line;
  1245. int flag;
  1246. /*
  1247. bit0= do not remove line end (protects trailing blanks if line end is present)
  1248. bit1= do not remove leading blanks
  1249. bit2= do not remove trailing blanks
  1250. bit3= remove surrounding quotation marks (after removing line end)
  1251. */
  1252. {
  1253. char *cpt,*wpt;
  1254. int l;
  1255. if(!(flag&1)){
  1256. l= strlen(line);
  1257. if(l>0) if(line[l-1]=='\r') line[--l]= 0;
  1258. if(l>0) if(line[l-1]=='\n') line[--l]= 0;
  1259. if(l>0) if(line[l-1]=='\r') line[--l]= 0;
  1260. }
  1261. if(flag&3){
  1262. l= strlen(line);
  1263. if(l>1) if(line[0]==34 && line[l-1]==34) {
  1264. wpt= line;
  1265. cpt= wpt+1;
  1266. while(*cpt!=0)
  1267. *(wpt++)= *(cpt++);
  1268. line[l-2]= 0;
  1269. }
  1270. }
  1271. if(!(flag&2)){
  1272. wpt= cpt= line;
  1273. while(*(cpt)!=0) {
  1274. if(!isspace(*cpt))
  1275. break;
  1276. cpt++;
  1277. }
  1278. while(*(cpt)!=0)
  1279. *(wpt++)= *(cpt++);
  1280. *wpt= 0;
  1281. }
  1282. if(!(flag&4)){
  1283. l= strlen(line);
  1284. if(l<=0)
  1285. return(1);
  1286. cpt= line+l;
  1287. while(cpt-->=line){
  1288. if(!isspace(*cpt))
  1289. break;
  1290. *(cpt)= 0;
  1291. }
  1292. }
  1293. return(1);
  1294. }
  1295. /* -------------------------------------------------------------- */
  1296. main(argc,argv)
  1297. int argc;
  1298. char **argv;
  1299. {
  1300. struct CgeN *cgen= NULL;
  1301. int ret, msg_printed= 0,first=1,gen_for_stic= 1, make_ansi= 0, i;
  1302. int make_lowercase= 0, may_overwrite= 0;
  1303. char global_include_file[4096];
  1304. global_include_file[0]= 0;
  1305. for(i= 1; i<argc; i++) {
  1306. if(strcmp(argv[i],"-no_stic")==0)
  1307. gen_for_stic= 0;
  1308. else if(strcmp(argv[i],"-smem_local")==0)
  1309. gen_for_stic= 2;
  1310. else if(strcmp(argv[i],"-ansi")==0)
  1311. make_ansi= 1;
  1312. else if(strcmp(argv[i],"-global_include")==0) {
  1313. if(i+1>=argc)
  1314. strcpy(global_include_file,"global_include.h");
  1315. else {
  1316. i++;
  1317. strcpy(global_include_file,argv[i]);
  1318. }
  1319. } else if(strcmp(argv[i],"-lowercase")==0) {
  1320. make_lowercase= 1;
  1321. } else if(strcmp(argv[i],"-overwrite")==0) {
  1322. may_overwrite= 1;
  1323. } else {
  1324. fprintf(stderr,"+++ %s: Unrecognized option: %s\n",argv[0],argv[i]);
  1325. {ret= 0; goto ex;}
  1326. }
  1327. }
  1328. if(strlen(global_include_file)>0) {
  1329. /* begin */
  1330. ret= Cgen__write_global_include(global_include_file,(!!may_overwrite)<<1);
  1331. if(ret<=0)
  1332. goto ex;
  1333. }
  1334. while(!feof(stdin)) {
  1335. ret= Cgen_new(&cgen,0);
  1336. if(ret<=0)
  1337. goto ex;
  1338. /* <<< can be done neater */
  1339. cgen->gen_for_stic= gen_for_stic;
  1340. cgen->make_ansi= make_ansi;
  1341. strcpy(cgen->global_include_file,global_include_file);
  1342. cgen->make_lowercase= make_lowercase;
  1343. cgen->may_overwrite= may_overwrite;
  1344. ret= Cgen_read_fp(cgen,stdin,first);
  1345. if(ret<=0)
  1346. goto ex;
  1347. if(ret==2)
  1348. break;
  1349. first= 0;
  1350. ret= Cgen_write_h(cgen,0);
  1351. if(ret<=0)
  1352. goto ex;
  1353. ret= Cgen_write_c(cgen,1);
  1354. if(ret<=0)
  1355. goto ex;
  1356. }
  1357. if(strlen(global_include_file)>0) {
  1358. /* finalize */
  1359. ret= Cgen__write_global_include(global_include_file,1);
  1360. if(ret<=0)
  1361. goto ex;
  1362. }
  1363. ret= 1;
  1364. ex:
  1365. if(cgen!=NULL)
  1366. if(cgen->msg[0]!=0) {
  1367. fprintf(stderr,"+++ %s\n",cgen->msg);
  1368. msg_printed= 1;
  1369. }
  1370. if(ret<=0 &&!msg_printed) {
  1371. if(errno>0)
  1372. fprintf(stderr,"+++ Error : %s\n",strerror(errno));
  1373. else if(ret==-1)
  1374. fprintf(stderr,
  1375. "+++ Program run failed (probably due to lack of memory)\n");
  1376. else
  1377. fprintf(stderr,"+++ Program run failed\n");
  1378. }
  1379. Cgen_destroy(&cgen,0);
  1380. exit(1-ret);
  1381. }