home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / dev / misc / cweb / examples / wmerge.c.save < prev    next >
Encoding:
Text File  |  1993-12-21  |  13.4 KB  |  738 lines

  1. #define buf_size 100 \
  2.  
  3. #define max_include_depth 10 \
  4.  \
  5.  
  6. #define max_file_name_length 256 \
  7.  
  8. #define cur_file file[include_depth]
  9. #define cur_file_name file_name[include_depth]
  10. #define cur_line line[include_depth]
  11. #define web_file file[0]
  12. #define web_file_name file_name[0] \
  13.  
  14. #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
  15. strncmp(buffer,change_buffer,limit-buffer) )  \
  16.  
  17. #define PATH_SEPARATOR ','
  18. #define DIR_SEPARATOR '/'
  19. #define DEVICE_SEPARATOR ':' \
  20.  
  21. #define too_long() {include_depth--; \
  22. err_print("! Include file name too long") ;goto restart;} \
  23.  
  24. #define spotless 0
  25. #define harmless_message 1
  26. #define error_message 2
  27. #define fatal_message 3
  28. #define mark_harmless {if(history==spotless) history= harmless_message;}
  29. #define mark_error history= error_message \
  30.  
  31. #define fatal(s,t) { \
  32. fprintf(stderr,s) ;err_print(t) ; \
  33. history= fatal_message;exit(wrap_up() ) ; \
  34. } \
  35.  \
  36.  
  37. #define RETURN_OK 0
  38. #define RETURN_WARN 5
  39. #define RETURN_ERROR 10
  40. #define RETURN_FAIL 20 \
  41.  
  42. #define show_banner flags['b']
  43. #define show_happiness flags['h'] \
  44.  
  45. #define update_terminal fflush(stderr)  \
  46.  \
  47.  
  48. #define MAXPATHLENGTH 4095
  49. #define CWEBINPUTS ",CWeb:,CWeb:include,CWeb:inputs" \
  50.  
  51. /*1:*/
  52. #line 13 "wmerge.w"
  53.  
  54. #line 63 "wmerge-p.ch"
  55. #include <stdio.h>
  56. #include <string.h>
  57. #line 15 "wmerge.w"
  58. #include <stdlib.h> 
  59. #include <ctype.h> 
  60. /*2:*/
  61. #line 35 "wmerge.w"
  62.  
  63. typedef short boolean;
  64. typedef unsigned char eight_bits;
  65. typedef char ASCII;
  66.  
  67. /*:2*//*5:*/
  68. #line 68 "wmerge.w"
  69.  
  70. ASCII buffer[buf_size];
  71. ASCII*buffer_end= buffer+buf_size-2;
  72. ASCII*limit;
  73. ASCII*loc;
  74.  
  75. /*:5*//*7:*/
  76. #line 134 "wmerge.w"
  77.  
  78. int include_depth;
  79. FILE*file[max_include_depth];
  80. FILE*change_file;
  81. char file_name[max_include_depth][max_file_name_length];
  82.  
  83. char change_file_name[max_file_name_length];
  84. char alt_web_file_name[max_file_name_length];
  85. int line[max_include_depth];
  86. int change_line;
  87. int change_depth;
  88. boolean input_has_ended;
  89. boolean changing;
  90. boolean web_file_open= 0;
  91.  
  92. /*:7*//*8:*/
  93. #line 160 "wmerge.w"
  94.  
  95. char change_buffer[buf_size];
  96. char*change_limit;
  97.  
  98. /*:8*//*23:*/
  99. #line 478 "wmerge.w"
  100.  
  101. int history= spotless;
  102.  
  103. /*:23*//*30:*/
  104. #line 575 "wmerge.w"
  105.  
  106. int argc;
  107. char**argv;
  108. char out_file_name[max_file_name_length];
  109. #line 299 "wmerge-p.ch"
  110. boolean flags[256];
  111. #line 580 "wmerge.w"
  112.  
  113. /*:30*//*40:*/
  114. #line 692 "wmerge.w"
  115.  
  116. FILE*out_file;
  117.  
  118. /*:40*//*44:*/
  119. #line 372 "wmerge-p.ch"
  120.  
  121. char include_path[MAXPATHLENGTH+1]= CWEBINPUTS;
  122. char*p,*path_prefix,*next_path_prefix;
  123.  
  124. /*:44*/
  125. #line 17 "wmerge.w"
  126.  
  127. /*4:*/
  128. #line 51 "wmerge.w"
  129.  
  130. #line 52 "wmerge.w"
  131.  
  132. /*:4*//*24:*/
  133. #line 239 "wmerge-p.ch"
  134.  
  135. #line 240 "wmerge-p.ch"
  136. void err_print(char*);
  137.  
  138. /*:24*//*32:*/
  139. #line 320 "wmerge-p.ch"
  140.  
  141. #line 321 "wmerge-p.ch"
  142. void scan_args(void);
  143.  
  144. /*:32*//*45:*/
  145. #line 379 "wmerge-p.ch"
  146.  
  147. int input_ln(FILE*fp);
  148. void prime_the_change_buffer(void);
  149. void check_change(void);
  150. void reset_input(void);
  151. int get_line(void);
  152. void put_line(void);
  153. void check_complete(void);
  154. void err_print(char*s);
  155. int wrap_up(void);
  156. void scan_args(void);
  157. static boolean set_path(char*ptr,char*override);
  158. int main(int argc,char**argv);
  159.  
  160. /*:45*/
  161. #line 18 "wmerge.w"
  162.  
  163. /*6:*/
  164. #line 93 "wmerge.w"
  165.  
  166. #line 80 "wmerge-p.ch"
  167. int input_ln(FILE*fp)
  168.  
  169. #line 96 "wmerge.w"
  170. {
  171. register int c= EOF;
  172. register char*k;
  173. if(feof(fp))return(0);
  174. limit= k= buffer;
  175. while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
  176. if((*(k++)= c)!=' ')limit= k;
  177. if(k>buffer_end)
  178. if((c= getc(fp))!=EOF&&c!='\n'){
  179. ungetc(c,fp);loc= buffer;err_print("! Input line too long");
  180.  
  181. }
  182. if(c==EOF&&limit==buffer)return(0);
  183.  
  184. return(1);
  185. }
  186.  
  187. /*:6*//*9:*/
  188. #line 171 "wmerge.w"
  189.  
  190. #line 97 "wmerge-p.ch"
  191. void prime_the_change_buffer(void)
  192. #line 174 "wmerge.w"
  193. {
  194. change_limit= change_buffer;
  195. /*10:*/
  196. #line 185 "wmerge.w"
  197.  
  198. while(1){
  199. change_line++;
  200. if(!input_ln(change_file))return;
  201. if(limit<buffer+2)continue;
  202. if(buffer[0]!='@')continue;
  203. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  204. if(buffer[1]=='x')break;
  205. if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
  206. loc= buffer+2;
  207. err_print("! Missing @x in change file");
  208.  
  209. }
  210. }
  211.  
  212. /*:10*/
  213. #line 176 "wmerge.w"
  214. ;
  215. /*11:*/
  216. #line 202 "wmerge.w"
  217.  
  218. do{
  219. change_line++;
  220. if(!input_ln(change_file)){
  221. err_print("! Change file ended after @x");
  222.  
  223. return;
  224. }
  225. }while(limit==buffer);
  226.  
  227. /*:11*/
  228. #line 177 "wmerge.w"
  229. ;
  230. /*12:*/
  231. #line 212 "wmerge.w"
  232.  
  233. {
  234. change_limit= change_buffer-buffer+limit;
  235. strncpy(change_buffer,buffer,limit-buffer+1);
  236. }
  237.  
  238. /*:12*/
  239. #line 178 "wmerge.w"
  240. ;
  241. }
  242.  
  243. /*:9*//*13:*/
  244. #line 230 "wmerge.w"
  245.  
  246. #line 105 "wmerge-p.ch"
  247. void check_change(void)
  248. #line 233 "wmerge.w"
  249. {
  250. int n= 0;
  251. if(lines_dont_match)return;
  252. while(1){
  253. changing= 1;change_line++;
  254. if(!input_ln(change_file)){
  255. err_print("! Change file ended before @y");
  256.  
  257. change_limit= change_buffer;changing= 0;
  258. return;
  259. }
  260. if(limit>buffer+1&&buffer[0]=='@'){
  261. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  262. /*14:*/
  263. #line 263 "wmerge.w"
  264.  
  265. if(buffer[1]=='x'||buffer[1]=='z'){
  266. loc= buffer+2;err_print("! Where is the matching @y?");
  267.  
  268. }
  269. else if(buffer[1]=='y'){
  270. if(n>0){
  271. loc= buffer+2;
  272. fprintf(stderr,"\n! Hmm... %d ",n);
  273. err_print("of the preceding lines failed to match");
  274.  
  275. }
  276. change_depth= include_depth;
  277. return;
  278. }
  279.  
  280. /*:14*/
  281. #line 247 "wmerge.w"
  282. ;
  283. }
  284. /*12:*/
  285. #line 212 "wmerge.w"
  286.  
  287. {
  288. change_limit= change_buffer-buffer+limit;
  289. strncpy(change_buffer,buffer,limit-buffer+1);
  290. }
  291.  
  292. /*:12*/
  293. #line 249 "wmerge.w"
  294. ;
  295. changing= 0;cur_line++;
  296. while(!input_ln(cur_file)){
  297. if(include_depth==0){
  298. err_print("! CWEB file ended during a change");
  299.  
  300. input_has_ended= 1;return;
  301. }
  302. include_depth--;cur_line++;
  303. }
  304. if(lines_dont_match)n++;
  305. }
  306. }
  307.  
  308. /*:13*//*15:*/
  309. #line 282 "wmerge.w"
  310.  
  311. #line 113 "wmerge-p.ch"
  312. void reset_input(void)
  313. #line 285 "wmerge.w"
  314. {
  315. limit= buffer;loc= buffer+1;buffer[0]= ' ';
  316. /*16:*/
  317. #line 297 "wmerge.w"
  318.  
  319. if((web_file= fopen(web_file_name,"r"))==NULL){
  320. strcpy(web_file_name,alt_web_file_name);
  321. if((web_file= fopen(web_file_name,"r"))==NULL)
  322. fatal("! Cannot open input file ",web_file_name);
  323. }
  324.  
  325.  
  326. web_file_open= 1;
  327. if((change_file= fopen(change_file_name,"r"))==NULL)
  328. fatal("! Cannot open change file ",change_file_name);
  329.  
  330. /*:16*/
  331. #line 287 "wmerge.w"
  332. ;
  333. include_depth= 0;cur_line= 0;change_line= 0;
  334. change_depth= include_depth;
  335. changing= 1;prime_the_change_buffer();changing= !changing;
  336. limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
  337. }
  338.  
  339. /*:15*//*17:*/
  340. #line 315 "wmerge.w"
  341.  
  342. get_line()
  343. {
  344. restart:
  345. if(changing&&include_depth==change_depth)
  346. /*21:*/
  347. #line 423 "wmerge.w"
  348. {
  349. change_line++;
  350. if(!input_ln(change_file)){
  351. err_print("! Change file ended without @z");
  352.  
  353. buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
  354. }
  355. if(limit>buffer){
  356. *limit= ' ';
  357. if(buffer[0]=='@'){
  358. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  359. if(buffer[1]=='x'||buffer[1]=='y'){
  360. loc= buffer+2;
  361. err_print("! Where is the matching @z?");
  362.  
  363. }
  364. else if(buffer[1]=='z'){
  365. prime_the_change_buffer();changing= !changing;
  366. }
  367. }
  368. }
  369. }
  370.  
  371. /*:21*/
  372. #line 320 "wmerge.w"
  373. ;
  374. if(!changing||include_depth>change_depth){
  375. /*20:*/
  376. #line 407 "wmerge.w"
  377. {
  378. cur_line++;
  379. while(!input_ln(cur_file)){
  380. if(include_depth==0){input_has_ended= 1;break;}
  381. else{
  382. fclose(cur_file);include_depth--;
  383. if(changing&&include_depth==change_depth)break;
  384. cur_line++;
  385. }
  386. }
  387. if(!changing&&!input_has_ended)
  388. if(limit-buffer==change_limit-change_buffer)
  389. if(buffer[0]==change_buffer[0])
  390. if(change_limit>change_buffer)check_change();
  391. }
  392.  
  393. /*:20*/
  394. #line 322 "wmerge.w"
  395. ;
  396. if(changing&&include_depth==change_depth)goto restart;
  397. }
  398. loc= buffer;*limit= ' ';
  399. if(*buffer=='@'&&(*(buffer+1)=='i'||*(buffer+1)=='I')){
  400. loc= buffer+2;
  401. while(loc<=limit&&(*loc==' '||*loc=='\t'||*loc=='"'))loc++;
  402. if(loc>=limit){
  403. err_print("! Include file name not given");
  404.  
  405. goto restart;
  406. }
  407. if(include_depth>=max_include_depth-1){
  408. err_print("! Too many nested includes");
  409.  
  410. goto restart;
  411. }
  412. include_depth++;
  413. /*19:*/
  414. #line 366 "wmerge.w"
  415. {
  416. char temp_file_name[max_file_name_length];
  417. char*cur_file_name_end= cur_file_name+max_file_name_length-1;
  418. char*k= cur_file_name,*kk;
  419. int l;
  420.  
  421. while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
  422. if(k>cur_file_name_end)too_long();
  423.  
  424. *k= '\0';
  425. if((cur_file= fopen(cur_file_name,"r"))!=NULL){
  426. cur_line= 0;
  427. goto restart;
  428. }
  429. #line 197 "wmerge-p.ch"
  430. if(0==set_path(include_path,getenv("CWEBINPUTS"))){
  431. include_depth--;goto restart;
  432. }
  433. path_prefix= include_path;
  434. while(path_prefix){
  435. for(kk= temp_file_name,p= path_prefix,l= 0;
  436. p&&*p&&*p!=PATH_SEPARATOR;
  437. *kk++= *p++,l++);
  438. if(path_prefix&&*path_prefix&&*path_prefix!=PATH_SEPARATOR&&
  439. *--p!=DEVICE_SEPARATOR&&*p!=DIR_SEPARATOR){
  440. *kk++= DIR_SEPARATOR;l++;
  441. }
  442. if(k+l+2>=cur_file_name_end)too_long();
  443. strcpy(kk,cur_file_name);
  444. if(cur_file= fopen(temp_file_name,"r")){
  445. cur_line= 0;goto restart;
  446. }
  447. if(next_path_prefix= strchr(path_prefix,PATH_SEPARATOR))
  448. path_prefix= next_path_prefix+1;
  449. else break;
  450. }
  451. #line 404 "wmerge.w"
  452. include_depth--;err_print("! Cannot open include file");goto restart;
  453. }
  454.  
  455. /*:19*/
  456. #line 340 "wmerge.w"
  457. ;
  458. }
  459. return(!input_has_ended);
  460. }
  461.  
  462. #line 127 "wmerge-p.ch"
  463. void put_line(void)
  464. {
  465. char*ptr= buffer;
  466. while(ptr<limit)
  467. {
  468. putc(*ptr,out_file);
  469. *ptr++;
  470. }
  471. putc('\n',out_file);
  472. }
  473. #line 351 "wmerge.w"
  474.  
  475. #line 151 "wmerge-p.ch"
  476. /*:17*//*22:*/
  477. #line 449 "wmerge.w"
  478.  
  479. #line 225 "wmerge-p.ch"
  480. void check_complete(void){
  481. #line 452 "wmerge.w"
  482. if(change_limit!=change_buffer){
  483. strncpy(buffer,change_buffer,change_limit-change_buffer+1);
  484. limit= buffer+(int)(change_limit-change_buffer);
  485. changing= 1;change_depth= include_depth;loc= buffer;
  486. err_print("! Change file entry did not match");
  487.  
  488. }
  489. }
  490.  
  491. /*:22*//*25:*/
  492. #line 243 "wmerge-p.ch"
  493.  
  494. void err_print(char*s)
  495. #line 498 "wmerge.w"
  496. {
  497. char*k,*l;
  498. fprintf(stderr,*s=='!'?"\n%s":"%s",s);
  499. if(web_file_open)/*26:*/
  500. #line 514 "wmerge.w"
  501.  
  502. {if(changing&&include_depth==change_depth)
  503. printf(". (l. %d of change file)\n",change_line);
  504. else if(include_depth==0)fprintf(stderr,". (l. %d)\n",cur_line);
  505. else fprintf(stderr,". (l. %d of include file %s)\n",cur_line,cur_file_name);
  506. l= (loc>=limit?limit:loc);
  507. if(l>buffer){
  508. for(k= buffer;k<l;k++)
  509. if(*k=='\t')putc(' ',stderr);
  510. else putc(*k,stderr);
  511. putchar('\n');
  512. for(k= buffer;k<l;k++)putc(' ',stderr);
  513. }
  514. for(k= l;k<limit;k++)putc(*k,stderr);
  515. putc('\n',stderr);
  516. }
  517.  
  518. /*:26*/
  519. #line 501 "wmerge.w"
  520. ;
  521. update_terminal;mark_error;
  522. }
  523.  
  524. /*:25*//*28:*/
  525. #line 278 "wmerge-p.ch"
  526.  
  527. int wrap_up(void){
  528. /*29:*/
  529. #line 553 "wmerge.w"
  530.  
  531. switch(history){
  532. case spotless:if(show_happiness)fprintf(stderr,"(No errors were found.)\n");break;
  533. case harmless_message:
  534. fprintf(stderr,"(Did you see the warning message above?)\n");break;
  535. case error_message:
  536. fprintf(stderr,"(Pardon me, but I think I spotted something wrong.)\n");break;
  537. case fatal_message:fprintf(stderr,"(That was a fatal error, my friend.)\n");
  538. }
  539.  
  540. /*:29*/
  541. #line 280 "wmerge-p.ch"
  542. ;
  543. switch(history){
  544. case harmless_message:return(RETURN_WARN);break;
  545. case error_message:return(RETURN_ERROR);break;
  546. case fatal_message:return(RETURN_FAIL);break;
  547. default:return(RETURN_OK);
  548. }
  549. }
  550. #line 552 "wmerge.w"
  551.  
  552. /*:28*//*33:*/
  553. #line 324 "wmerge-p.ch"
  554.  
  555. void scan_args(void)
  556. #line 606 "wmerge.w"
  557. {
  558. char*dot_pos;
  559. char*name_pos;
  560. register char*s;
  561. boolean found_web= 0,found_change= 0,found_out= 0;
  562.  
  563. boolean flag_change;
  564.  
  565. while(--argc>0){
  566. if(**(++argv)=='-'||**argv=='+')/*37:*/
  567. #line 674 "wmerge.w"
  568.  
  569. {
  570. if(**argv=='-')flag_change= 0;
  571. else flag_change= 1;
  572. for(dot_pos= *argv+1;*dot_pos>'\0';dot_pos++)
  573. flags[*dot_pos]= flag_change;
  574. }
  575.  
  576. /*:37*/
  577. #line 615 "wmerge.w"
  578.  
  579. else{
  580. s= name_pos= *argv;dot_pos= NULL;
  581. while(*s){
  582. if(*s=='.')dot_pos= s++;
  583. else if(*s=='/')dot_pos= NULL,name_pos= ++s;
  584. else s++;
  585. }
  586. if(!found_web)/*34:*/
  587. #line 640 "wmerge.w"
  588.  
  589. {
  590. if(s-*argv>max_file_name_length-5)
  591. /*39:*/
  592. #line 687 "wmerge.w"
  593. fatal("! Filename too long\n",*argv);
  594.  
  595. /*:39*/
  596. #line 643 "wmerge.w"
  597. ;
  598. if(dot_pos==NULL)
  599. sprintf(web_file_name,"%s.w",*argv);
  600. else{
  601. strcpy(web_file_name,*argv);
  602. *dot_pos= 0;
  603. }
  604. sprintf(alt_web_file_name,"%s.web",*argv);
  605. *out_file_name= '\0';
  606. found_web= 1;
  607. }
  608.  
  609. /*:34*/
  610. #line 623 "wmerge.w"
  611.  
  612. else if(!found_change)/*35:*/
  613. #line 655 "wmerge.w"
  614.  
  615. {
  616. if(s-*argv>max_file_name_length-4)
  617. /*39:*/
  618. #line 687 "wmerge.w"
  619. fatal("! Filename too long\n",*argv);
  620.  
  621. /*:39*/
  622. #line 658 "wmerge.w"
  623. ;
  624. if(dot_pos==NULL)
  625. sprintf(change_file_name,"%s.ch",*argv);
  626. else strcpy(change_file_name,*argv);
  627. found_change= 1;
  628. }
  629.  
  630. /*:35*/
  631. #line 624 "wmerge.w"
  632.  
  633. else if(!found_out)/*36:*/
  634. #line 665 "wmerge.w"
  635.  
  636. {
  637. if(s-*argv>max_file_name_length-5)
  638. /*39:*/
  639. #line 687 "wmerge.w"
  640. fatal("! Filename too long\n",*argv);
  641.  
  642. /*:39*/
  643. #line 668 "wmerge.w"
  644. ;
  645. if(dot_pos==NULL)sprintf(out_file_name,"%s.out",*argv);
  646. else strcpy(out_file_name,*argv);
  647. found_out= 1;
  648. }
  649.  
  650. /*:36*/
  651. #line 625 "wmerge.w"
  652.  
  653. else/*38:*/
  654. #line 682 "wmerge.w"
  655.  
  656. {
  657. fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")
  658. }
  659.  
  660. /*:38*/
  661. #line 626 "wmerge.w"
  662. ;
  663. }
  664. }
  665. if(!found_web)/*38:*/
  666. #line 682 "wmerge.w"
  667.  
  668. {
  669. fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")
  670. }
  671.  
  672. /*:38*/
  673. #line 629 "wmerge.w"
  674. ;
  675. #line 331 "wmerge-p.ch"
  676. #if defined( __TURBOC__ )
  677. if(!found_change)strcpy(change_file_name,"nul");
  678. #elif defined( _AMIGA )
  679. if(!found_change)strcpy(change_file_name,"NIL:");
  680. #else
  681. if(!found_change)strcpy(change_file_name,"/dev/null");
  682. #endif
  683. #line 631 "wmerge.w"
  684. }
  685.  
  686. /*:33*//*43:*/
  687. #line 350 "wmerge-p.ch"
  688.  
  689. static boolean set_path(char*ptr,char*override)
  690. {
  691. if(override){
  692. if(strlen(override)>=MAXPATHLENGTH){
  693. err_print("! Include path too long");return(0);
  694.  
  695. }
  696. else strcpy(ptr,override);
  697. }
  698. return(1);
  699. }
  700.  
  701. /*:43*/
  702. #line 19 "wmerge.w"
  703.  
  704. main(ac,av)
  705. int ac;char**av;
  706. {
  707. argc= ac;argv= av;
  708. /*31:*/
  709. #line 583 "wmerge.w"
  710.  
  711. show_banner= show_happiness= 1;
  712.  
  713. /*:31*/
  714. #line 24 "wmerge.w"
  715. ;
  716. /*41:*/
  717. #line 695 "wmerge.w"
  718.  
  719. scan_args();
  720. if(out_file_name[0]=='\0')out_file= stdout;
  721. else if((out_file= fopen(out_file_name,"w"))==NULL)
  722. fatal("! Cannot open output file ",out_file_name);
  723.  
  724.  
  725. /*:41*/
  726. #line 25 "wmerge.w"
  727. ;
  728. reset_input();
  729. while(get_line())
  730. put_line();
  731. fflush(out_file);
  732. check_complete();
  733. fflush(out_file);
  734. return wrap_up();
  735. }
  736.  
  737. /*:1*/
  738.