home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cweb28.zip / common.c < prev    next >
C/C++ Source or Header  |  1992-10-03  |  19KB  |  1,091 lines

  1. #define tangle 0
  2. #define weave 1 \
  3.  
  4. #define and_and 04
  5. #define lt_lt 020
  6. #define gt_gt 021
  7. #define plus_plus 013
  8. #define minus_minus 01
  9. #define minus_gt 031
  10. #define not_eq 032
  11. #define lt_eq 034
  12. #define gt_eq 035
  13. #define eq_eq 036
  14. #define or_or 037 \
  15.  
  16. #define buf_size 100
  17. #define long_buf_size 500 \
  18.  
  19. #define max_include_depth 10 \
  20.  
  21. #define max_file_name_length 60
  22. #define cur_file file[include_depth]
  23. #define cur_file_name file_name[include_depth]
  24. #define cur_line line[include_depth]
  25. #define web_file file[0]
  26. #define web_file_name file_name[0] \
  27.  
  28. #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
  29. strncmp(buffer,change_buffer,limit-buffer)) \
  30.  
  31. #define if_section_start_make_pending(b){*limit= '!'; \
  32. for(loc= buffer;isspace(*loc);loc++); \
  33. *limit= ' '; \
  34. if(*loc=='@'&&(isspace(*(loc+1))||*(loc+1)=='*'))change_pending= b; \
  35. } \
  36.  
  37. #define max_sections 2000 \
  38.  \
  39.  
  40. #define max_bytes 90000 \
  41.  
  42. #define max_names 4000 \
  43.  \
  44.  
  45. #define length(c)(c+1)->byte_start-(c)->byte_start
  46. #define print_id(c)term_write((c)->byte_start,length((c))) \
  47.  
  48. #define hash_size 353 \
  49.  
  50. #define llink link
  51. #define rlink dummy.Rlink
  52. #define root name_dir->rlink \
  53.  \
  54.  
  55. #define first_chunk(p)((p)->byte_start+2)
  56. #define prefix_length(p)((unsigned char)*((p)->byte_start)*256+ \
  57. (unsigned char)*((p)->byte_start+1))
  58. #define set_prefix_length(p,m)(*((p)->byte_start)= (m)/256, \
  59. *((p)->byte_start+1)= (m)%256) \
  60.  
  61. #define less 0
  62. #define equal 1
  63. #define greater 2
  64. #define prefix 3
  65. #define extension 4 \
  66.  
  67. #define bad_extension 5 \
  68.  
  69. #define spotless 0
  70. #define harmless_message 1
  71. #define error_message 2
  72. #define fatal_message 3
  73. #define mark_harmless {if(history==spotless)history= harmless_message;}
  74. #define mark_error history= error_message \
  75.  
  76. #define fatal(s,t){ \
  77. printf(s);err_print(t); \
  78. history= fatal_message;wrap_up(); \
  79. } \
  80.  
  81. #define confusion(s)fatal("! This can't happen: ",s) \
  82.  \
  83.  
  84. #define overflow(t){ \
  85. printf("\n! Sorry, %s capacity exceeded",t);fatal("",""); \
  86. } \
  87.  \
  88.  
  89. #define show_banner flags['b']
  90. #define show_progress flags['p']
  91. #define show_stats flags['s']
  92. #define show_happiness flags['h'] \
  93.  
  94. #define update_terminal fflush(stdout) \
  95.  
  96. #define new_line putchar('\n')
  97. #define putxchar putchar
  98. #define term_write(a,b)fflush(stdout),write(1,a,b)
  99. #define C_printf(c,a)fprintf(C_file,c,a)
  100. #define C_putc(c)putc(c,C_file) \
  101.  
  102. /*1:*/
  103. #line 57 "common.w"
  104.  
  105. /*5:*/
  106. #line 99 "common.w"
  107.  
  108. #include <ctype.h>
  109.  
  110. /*:5*//*8:*/
  111. #line 155 "common.w"
  112.  
  113. #include <stdio.h>
  114.  
  115. /*:8*/
  116. #line 58 "common.w"
  117.  
  118. /*2:*/
  119. #line 71 "common.w"
  120.  
  121. typedef short boolean;
  122. boolean program;
  123.  
  124. /*:2*//*7:*/
  125. #line 149 "common.w"
  126.  
  127. char buffer[long_buf_size];
  128. char*buffer_end= buffer+buf_size-2;
  129. char*limit= buffer;
  130. char*loc= buffer;
  131.  
  132. /*:7*//*10:*/
  133. #line 204 "common.w"
  134.  
  135. int include_depth;
  136. FILE*file[max_include_depth];
  137. FILE*change_file;
  138. char file_name[max_include_depth][max_file_name_length];
  139.  
  140. char change_file_name[max_file_name_length];
  141. char alt_web_file_name[max_file_name_length];
  142. int line[max_include_depth];
  143. int change_line;
  144. boolean input_has_ended;
  145. boolean changing;
  146. boolean web_file_open= 0;
  147.  
  148. /*:10*//*20:*/
  149. #line 402 "common.w"
  150.  
  151. typedef unsigned short sixteen_bits;
  152. sixteen_bits section_count;
  153. boolean changed_section[max_sections];
  154. boolean change_pending;
  155.  
  156. boolean print_where= 0;
  157.  
  158. /*:20*//*26:*/
  159. #line 543 "common.w"
  160.  
  161. typedef struct name_info{
  162. char*byte_start;
  163. /*30:*/
  164. #line 580 "common.w"
  165.  
  166. struct name_info*link;
  167.  
  168. /*:30*//*37:*/
  169. #line 670 "common.w"
  170.  
  171. union{
  172. struct name_info*Rlink;
  173.  
  174. char Ilk;
  175. }dummy;
  176.  
  177. /*:37*//*48:*/
  178. #line 989 "common.w"
  179.  
  180. char*equiv_or_xref;
  181.  
  182. /*:48*/
  183. #line 546 "common.w"
  184.  
  185. }name_info;
  186. typedef name_info*name_pointer;
  187. char byte_mem[max_bytes];
  188. char*byte_mem_end= byte_mem+max_bytes-1;
  189. name_info name_dir[max_names];
  190. name_pointer name_dir_end= name_dir+max_names-1;
  191.  
  192. /*:26*//*28:*/
  193. #line 566 "common.w"
  194.  
  195. name_pointer name_ptr;
  196. char*byte_ptr;
  197.  
  198. /*:28*//*31:*/
  199. #line 593 "common.w"
  200.  
  201. typedef name_pointer*hash_pointer;
  202. name_pointer hash[hash_size];
  203. hash_pointer hash_end= hash+hash_size-1;
  204. hash_pointer h;
  205.  
  206. /*:31*//*49:*/
  207. #line 1009 "common.w"
  208.  
  209. int history= spotless;
  210.  
  211. /*:49*//*57:*/
  212. #line 1120 "common.w"
  213.  
  214. int argc;
  215. char**argv;
  216. char C_file_name[max_file_name_length];
  217. char tex_file_name[max_file_name_length];
  218. boolean flags[128];
  219.  
  220. /*:57*//*66:*/
  221. #line 1250 "common.w"
  222.  
  223. FILE*C_file;
  224. FILE*tex_file;
  225.  
  226. /*:66*/
  227. #line 59 "common.w"
  228.  
  229. /*3:*/
  230. #line 81 "common.w"
  231. int phase;
  232.  
  233. /*:3*//*11:*/
  234. #line 229 "common.w"
  235.  
  236. char change_buffer[buf_size];
  237. char*change_limit;
  238.  
  239. /*:11*/
  240. #line 60 "common.w"
  241.  
  242. /*4:*/
  243. #line 87 "common.w"
  244.  
  245. common_init()
  246. {
  247. /*29:*/
  248. #line 570 "common.w"
  249.  
  250. name_dir->byte_start= byte_ptr= byte_mem;
  251. name_ptr= name_dir+1;
  252. name_ptr->byte_start= byte_mem;
  253.  
  254. /*:29*//*32:*/
  255. #line 601 "common.w"
  256.  
  257. for(h= hash;h<=hash_end;*h++= NULL);
  258.  
  259. /*:32*//*38:*/
  260. #line 677 "common.w"
  261.  
  262. root= NULL;
  263.  
  264. /*:38*/
  265. #line 90 "common.w"
  266. ;
  267. /*58:*/
  268. #line 1131 "common.w"
  269.  
  270. show_banner= show_happiness= show_progress= 1;
  271.  
  272. /*:58*/
  273. #line 91 "common.w"
  274. ;
  275. /*67:*/
  276. #line 1254 "common.w"
  277.  
  278. scan_args();
  279. if(program==tangle){
  280. if((C_file= fopen(C_file_name,"w"))==NULL)
  281. fatal("! Cannot open output file ",C_file_name);
  282.  
  283. }
  284. else{
  285. if((tex_file= fopen(tex_file_name,"w"))==NULL)
  286. fatal("! Cannot open output file ",tex_file_name);
  287. }
  288.  
  289. /*:67*/
  290. #line 92 "common.w"
  291. ;
  292. }
  293.  
  294. /*:4*//*9:*/
  295. #line 162 "common.w"
  296.  
  297. input_ln(fp)
  298. FILE*fp;
  299. {
  300. register int c;
  301. register char*k;
  302. if(feof(fp))return(0);
  303. limit= k= buffer;
  304. while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
  305. if((*(k++)= c)!=' ')limit= k;
  306. if(k>buffer_end)
  307. if((c= getc(fp))!=EOF&&c!='\n'){
  308. ungetc(c,fp);loc= buffer;err_print("! Input line too long");
  309.  
  310. }
  311. if(c==EOF&&limit==buffer)return(0);
  312.  
  313. return(1);
  314. }
  315.  
  316. /*:9*//*12:*/
  317. #line 240 "common.w"
  318.  
  319. prime_the_change_buffer()
  320. {
  321. change_limit= change_buffer;
  322. /*13:*/
  323. #line 253 "common.w"
  324.  
  325. while(1){
  326. change_line++;
  327. if(!input_ln(change_file))return;
  328. if(limit<buffer+2)continue;
  329. if(buffer[0]!='@')continue;
  330. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  331. if(buffer[1]=='x')break;
  332. if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
  333. loc= buffer+2;
  334. err_print("! Missing @x in change file");
  335.  
  336. }
  337. }
  338.  
  339. /*:13*/
  340. #line 244 "common.w"
  341. ;
  342. /*14:*/
  343. #line 270 "common.w"
  344.  
  345. do{
  346. change_line++;
  347. if(!input_ln(change_file)){
  348. err_print("! Change file ended after @x");
  349.  
  350. return;
  351. }
  352. }while(limit==buffer);
  353.  
  354. /*:14*/
  355. #line 245 "common.w"
  356. ;
  357. /*15:*/
  358. #line 280 "common.w"
  359.  
  360. {
  361. change_limit= change_buffer-buffer+limit;
  362. strncpy(change_buffer,buffer,limit-buffer+1);
  363. }
  364.  
  365. /*:15*/
  366. #line 246 "common.w"
  367. ;
  368. }
  369.  
  370. /*:12*//*16:*/
  371. #line 308 "common.w"
  372.  
  373. check_change()
  374. {
  375. int n= 0;
  376. if(lines_dont_match)return;
  377. change_pending= 0;
  378. if(!changed_section[section_count]){
  379. if_section_start_make_pending(1);
  380. if(!change_pending)changed_section[section_count]= 1;
  381. }
  382. while(1){
  383. changing= 1;print_where= 1;change_line++;
  384. if(!input_ln(change_file)){
  385. err_print("! Change file ended before @y");
  386.  
  387. change_limit= change_buffer;changing= 0;
  388. return;
  389. }
  390. if(limit>buffer+1&&buffer[0]=='@'){
  391. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  392. /*17:*/
  393. #line 345 "common.w"
  394.  
  395. if(buffer[1]=='x'||buffer[1]=='z'){
  396. loc= buffer+2;err_print("! Where is the matching @y?");
  397.  
  398. }
  399. else if(buffer[1]=='y'){
  400. if(n>0){
  401. loc= buffer+2;
  402. printf("\n! Hmm... %d ",n);
  403. err_print("of the preceding lines failed to match");
  404.  
  405. }
  406. return;
  407. }
  408.  
  409. /*:17*/
  410. #line 329 "common.w"
  411. ;
  412. }
  413. /*15:*/
  414. #line 280 "common.w"
  415.  
  416. {
  417. change_limit= change_buffer-buffer+limit;
  418. strncpy(change_buffer,buffer,limit-buffer+1);
  419. }
  420.  
  421. /*:15*/
  422. #line 331 "common.w"
  423. ;
  424. changing= 0;cur_line++;
  425. while(!input_ln(cur_file)){
  426. if(include_depth==0){
  427. err_print("! WEB file ended during a change");
  428.  
  429. input_has_ended= 1;return;
  430. }
  431. include_depth--;cur_line++;
  432. }
  433. if(lines_dont_match)n++;
  434. }
  435. }
  436.  
  437. /*:16*//*18:*/
  438. #line 364 "common.w"
  439.  
  440. reset_input()
  441. {
  442. limit= buffer;loc= buffer+1;buffer[0]= ' ';
  443. /*19:*/
  444. #line 377 "common.w"
  445.  
  446. if((web_file= fopen(web_file_name,"r"))==NULL){
  447. strcpy(web_file_name,alt_web_file_name);
  448. if((web_file= fopen(web_file_name,"r"))==NULL)
  449. fatal("! Cannot open input file ",web_file_name);
  450. }
  451.  
  452.  
  453. web_file_open= 1;
  454. if((change_file= fopen(change_file_name,"r"))==NULL)
  455. fatal("! Cannot open change file ",change_file_name);
  456.  
  457. /*:19*/
  458. #line 368 "common.w"
  459. ;
  460. include_depth= 0;cur_line= 0;change_line= 0;
  461. changing= 1;prime_the_change_buffer();changing= !changing;
  462. limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
  463. }
  464.  
  465. /*:18*//*21:*/
  466. #line 410 "common.w"
  467.  
  468. get_line()
  469. {
  470. restart:
  471. if(changing)/*24:*/
  472. #line 487 "common.w"
  473. {
  474. change_line++;
  475. if(!input_ln(change_file)){
  476. err_print("! Change file ended without @z");
  477.  
  478. buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
  479. }
  480. if(limit>buffer){
  481. if(change_pending){
  482. if_section_start_make_pending(0);
  483. if(change_pending){
  484. changed_section[section_count]= 1;change_pending= 0;
  485. }
  486. }
  487. *limit= ' ';
  488. if(buffer[0]=='@'){
  489. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  490. if(buffer[1]=='x'||buffer[1]=='y'){
  491. loc= buffer+2;
  492. err_print("! Where is the matching @z?");
  493.  
  494. }
  495. else if(buffer[1]=='z'){
  496. prime_the_change_buffer();changing= !changing;print_where= 1;
  497. }
  498. }
  499. }
  500. }
  501.  
  502. /*:24*/
  503. #line 414 "common.w"
  504. ;
  505. if(!changing){
  506. /*23:*/
  507. #line 474 "common.w"
  508. {
  509. cur_line++;
  510. while(!input_ln(cur_file)){
  511. print_where= 1;
  512. if(include_depth==0){input_has_ended= 1;break;}
  513. else{fclose(cur_file);include_depth--;cur_line++;}
  514. }
  515. if(!input_has_ended)
  516. if(limit==change_limit-change_buffer+buffer)
  517. if(buffer[0]==change_buffer[0])
  518. if(change_limit>change_buffer)check_change();
  519. }
  520.  
  521. /*:23*/
  522. #line 416 "common.w"
  523. ;
  524. if(changing)goto restart;
  525. }
  526. loc= buffer;*limit= ' ';
  527. if(*buffer=='@'&&(*(buffer+1)=='i'||*(buffer+1)=='I'))
  528. /*22:*/
  529. #line 436 "common.w"
  530. {
  531. char*k,*j;
  532. loc= buffer+2;
  533. while(loc<=limit&&(*loc==' '||*loc=='\t'||*loc=='"'))loc++;
  534. if(loc>=limit)err_print("! Include file name not given");
  535.  
  536. else{
  537. if(++include_depth<max_include_depth){
  538. k= cur_file_name;j= loc;
  539. while(*loc!=' '&&*loc!='\t'&&*loc!='"')*k++= *loc++;
  540. *k= '\0';
  541. if((cur_file= fopen(cur_file_name,"r"))==NULL){
  542. #ifdef INCLUDEDIR
  543. strcpy(cur_file_name,INCLUDEDIR);
  544. k= cur_file_name+strlen(cur_file_name);
  545. while(*j!=' '&&*j!='\t'&&*j!='"')*k++= *j++;
  546. *k= '\0';
  547. if((cur_file= fopen(cur_file_name,"r"))==NULL){
  548. #endif 
  549. include_depth--;
  550. err_print("! Cannot open include file");
  551.  
  552. }
  553. #ifdef INCLUDEDIR
  554. else{cur_line= 0;print_where= 1;}
  555. }
  556. #endif 
  557. else{cur_line= 0;print_where= 1;}
  558. }
  559. else{
  560. include_depth--;
  561. err_print("! Too many nested includes");
  562.  
  563. }
  564. }
  565. goto restart;
  566. }
  567.  
  568. /*:22*/
  569. #line 421 "common.w"
  570. ;
  571. return(!input_has_ended);
  572. }
  573.  
  574. /*:21*//*25:*/
  575. #line 519 "common.w"
  576.  
  577. check_complete(){
  578. if(change_limit!=change_buffer){
  579. strncpy(buffer,change_buffer,change_limit-change_buffer+1);
  580. limit= change_limit-change_buffer+buffer;
  581. changing= 1;loc= buffer;
  582. err_print("! Change file entry did not match");
  583.  
  584. }
  585. }
  586.  
  587. /*:25*//*50:*/
  588. #line 1019 "common.w"
  589.  
  590. err_print(s)
  591. char*s;
  592. {
  593. char*k,*l;
  594. printf(*s=='!'?"\n%s":"%s",s);
  595. if(web_file_open)/*51:*/
  596. #line 1038 "common.w"
  597.  
  598. {if(changing)printf(". (l. %d of change file)\n",change_line);
  599. else if(include_depth==0)printf(". (l. %d)\n",cur_line);
  600. else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
  601. l= (loc>=limit?limit:loc);
  602. if(l>buffer){
  603. for(k= buffer;k<l;k++)
  604. if(*k=='\t')putchar(' ');
  605. else putchar(*k);
  606. putchar('\n');
  607. for(k= buffer;k<l;k++)putchar(' ');
  608. }
  609. for(k= l;k<limit;k++)putchar(*k);
  610. if(*limit=='|')putchar('|');
  611. putchar(' ');
  612. }
  613.  
  614. /*:51*/
  615. #line 1025 "common.w"
  616. ;
  617. update_terminal;mark_error;
  618. }
  619.  
  620. /*:50*//*55:*/
  621. #line 1085 "common.w"
  622.  
  623. wrap_up(){
  624. putchar('\n');
  625. #ifdef STAT
  626. if(show_stats)print_stats();
  627. #endif 
  628. /*56:*/
  629. #line 1096 "common.w"
  630.  
  631. switch(history){
  632. case spotless:if(show_happiness)printf("(No errors were found.)\n");break;
  633. case harmless_message:
  634. printf("(Did you see the warning message above?)\n");break;
  635. case error_message:
  636. printf("(Pardon me, but I think I spotted something wrong.)\n");break;
  637. case fatal_message:printf("(That was a fatal error, my friend.)\n");
  638. }
  639.  
  640. /*:56*/
  641. #line 1091 "common.w"
  642. ;
  643. if(history>harmless_message)exit(1);
  644. else exit(0);
  645. }
  646.  
  647. /*:55*//*59:*/
  648. #line 1149 "common.w"
  649.  
  650. scan_args()
  651. {
  652. char*dot_pos;
  653. char*name_pos;
  654. register char*s;
  655. boolean found_web= 0,found_change= 0,found_out= 0;
  656.  
  657. boolean flag_change;
  658.  
  659. while(--argc>0){
  660. if(**(++argv)=='-'||**argv=='+')/*63:*/
  661. #line 1226 "common.w"
  662.  
  663. {
  664. if(**argv=='-')flag_change= 0;
  665. else flag_change= 1;
  666. for(dot_pos= *argv+1;*dot_pos>'\0';dot_pos++)
  667. flags[*dot_pos]= flag_change;
  668. }
  669.  
  670. /*:63*/
  671. #line 1160 "common.w"
  672.  
  673. else{
  674. s= name_pos= *argv;dot_pos= NULL;
  675. while(*s){
  676. if(*s=='.')dot_pos= s++;
  677. else if(*s=='/')dot_pos= NULL,name_pos= ++s;
  678. else s++;
  679. }
  680. if(!found_web)/*60:*/
  681. #line 1186 "common.w"
  682.  
  683. {
  684. if(s-*argv>max_file_name_length-5)
  685. /*65:*/
  686. #line 1245 "common.w"
  687. fatal("! Filename too long\n",*argv);
  688.  
  689. /*:65*/
  690. #line 1189 "common.w"
  691. ;
  692. if(dot_pos==NULL)
  693. sprintf(web_file_name,"%s.w",*argv);
  694. else{
  695. strcpy(web_file_name,*argv);
  696. *dot_pos= 0;
  697. }
  698. sprintf(alt_web_file_name,"%s.web",*argv);
  699. sprintf(tex_file_name,"%s.tex",name_pos);
  700. sprintf(C_file_name,"%s.c",name_pos);
  701. found_web= 1;
  702. }
  703.  
  704. /*:60*/
  705. #line 1169 "common.w"
  706.  
  707. else if(!found_change)/*61:*/
  708. #line 1202 "common.w"
  709.  
  710. {
  711. if(s-*argv>max_file_name_length-4)
  712. /*65:*/
  713. #line 1245 "common.w"
  714. fatal("! Filename too long\n",*argv);
  715.  
  716. /*:65*/
  717. #line 1205 "common.w"
  718. ;
  719. if(dot_pos==NULL)
  720. sprintf(change_file_name,"%s.ch",*argv);
  721. else strcpy(change_file_name,*argv);
  722. found_change= 1;
  723. }
  724.  
  725. /*:61*/
  726. #line 1170 "common.w"
  727.  
  728. else if(!found_out)/*62:*/
  729. #line 1212 "common.w"
  730.  
  731. {
  732. if(s-*argv>max_file_name_length-5)
  733. /*65:*/
  734. #line 1245 "common.w"
  735. fatal("! Filename too long\n",*argv);
  736.  
  737. /*:65*/
  738. #line 1215 "common.w"
  739. ;
  740. if(dot_pos==NULL){
  741. sprintf(tex_file_name,"%s.tex",*argv);
  742. sprintf(C_file_name,"%s.c",*argv);
  743. }else{
  744. strcpy(tex_file_name,*argv);
  745. strcpy(C_file_name,*argv);
  746. }
  747. found_out= 1;
  748. }
  749.  
  750. /*:62*/
  751. #line 1171 "common.w"
  752.  
  753. else/*64:*/
  754. #line 1234 "common.w"
  755.  
  756. {
  757. if(program==tangle)
  758. fatal(
  759. "! Usage: ctangle [options] webfile[.w] [changefile[.ch] [outfile[.c]]]\n"
  760. ,"")
  761. else fatal(
  762. "! Usage: cweave [options] webfile[.w] [changefile[.ch] [outfile[.tex]]]\n"
  763. ,"");
  764. }
  765.  
  766. /*:64*/
  767. #line 1172 "common.w"
  768. ;
  769. }
  770. }
  771. if(!found_web)/*64:*/
  772. #line 1234 "common.w"
  773.  
  774. {
  775. if(program==tangle)
  776. fatal(
  777. "! Usage: ctangle [options] webfile[.w] [changefile[.ch] [outfile[.c]]]\n"
  778. ,"")
  779. else fatal(
  780. "! Usage: cweave [options] webfile[.w] [changefile[.ch] [outfile[.tex]]]\n"
  781. ,"");
  782. }
  783.  
  784. /*:64*/
  785. #line 1175 "common.w"
  786. ;
  787. if(!found_change)strcpy(change_file_name,"/dev/null");
  788. }
  789.  
  790. /*:59*/
  791. #line 61 "common.w"
  792.  
  793.  
  794. /*:1*//*33:*/
  795. #line 606 "common.w"
  796. name_pointer
  797. id_lookup(first,last,t)
  798. char*first;
  799. char*last;
  800. char t;
  801. {
  802. char*i= first;
  803. int h;
  804. int l;
  805. name_pointer p;
  806. if(last==NULL)for(last= first;*last!='\0';last++);
  807. l= last-first;
  808. /*34:*/
  809. #line 628 "common.w"
  810.  
  811. h= *i;while(++i<last)h= (h+h+*i)%hash_size;
  812.  
  813. /*:34*/
  814. #line 618 "common.w"
  815. ;
  816. /*35:*/
  817. #line 634 "common.w"
  818.  
  819. p= hash[h];
  820. while(p&&!names_match(p,first,l,t))p= p->link;
  821. if(p==NULL){
  822. p= name_ptr;
  823. p->link= hash[h];hash[h]= p;
  824. }
  825.  
  826. /*:35*/
  827. #line 619 "common.w"
  828. ;
  829. if(p==name_ptr)/*36:*/
  830. #line 646 "common.w"
  831. {
  832. if(byte_ptr+l>byte_mem_end)overflow("byte memory");
  833. if(name_ptr>=name_dir_end)overflow("name");
  834. strncpy(byte_ptr,first,l);
  835. (++name_ptr)->byte_start= byte_ptr+= l;
  836. if(program==weave)init_p(p,t);
  837. }
  838.  
  839. /*:36*/
  840. #line 620 "common.w"
  841. ;
  842. return(p);
  843. }
  844.  
  845. /*:33*//*39:*/
  846. #line 704 "common.w"
  847.  
  848. print_section_name(p)
  849. name_pointer p;
  850. {
  851. char*ss,*s= first_chunk(p);
  852. name_pointer q= p+1;
  853. while(p!=name_dir){
  854. ss= (p+1)->byte_start-1;
  855. if(*ss==' '&&ss>=s){
  856. term_write(s,ss-s);p= q->link;q= p;
  857. }else{
  858. term_write(s,ss+1-s);p= name_dir;q= NULL;
  859. }
  860. s= p->byte_start;
  861. }
  862. if(q)term_write("...",3);
  863. }
  864.  
  865. sprint_section_name(dest,p)
  866. char*dest;
  867. name_pointer p;
  868. {
  869. char*ss,*s= first_chunk(p);
  870. name_pointer q= p+1;
  871. while(p!=name_dir){
  872. ss= (p+1)->byte_start-1;
  873. if(*ss==' '&&ss>=s){
  874. p= q->link;q= p;
  875. }else{
  876. ss++;p= name_dir;
  877. }
  878. strncpy(dest,s,ss-s),dest+= ss-s;
  879. s= p->byte_start;
  880. }
  881. *dest= '\0';
  882. }
  883.  
  884. print_prefix_name(p)
  885. name_pointer p;
  886. {
  887. char*s= first_chunk(p);
  888. int l= prefix_length(p);
  889. term_write(s,l);
  890. if(s+l<(p+1)->byte_start)term_write("...",3);
  891. }
  892.  
  893. /*:39*//*40:*/
  894. #line 760 "common.w"
  895.  
  896. web_strcmp(j,j_len,k,k_len)
  897. char*j,*k;
  898. int j_len,k_len;
  899. {
  900. char*j1= j+j_len,*k1= k+k_len;
  901. while(k<k1&&j<j1&&*j==*k)k++,j++;
  902. if(k==k1)if(j==j1)return equal;
  903. else return extension;
  904. else if(j==j1)return prefix;
  905. else if(*j<*k)return less;
  906. else return greater;
  907. }
  908.  
  909. /*:40*//*41:*/
  910. #line 786 "common.w"
  911.  
  912. name_pointer
  913. add_section_name(par,c,first,last,ispref)
  914. name_pointer par;
  915. int c;
  916. char*first;
  917. char*last;
  918. int ispref;
  919. {
  920. name_pointer p= name_ptr;
  921. char*s= first_chunk(p);
  922. int name_len= last-first+ispref;
  923. if(s+name_len>byte_mem_end)overflow("byte memory");
  924. if(name_ptr+1>=name_dir_end)overflow("name");
  925. (++name_ptr)->byte_start= byte_ptr= s+name_len;
  926. if(ispref){
  927. *(byte_ptr-1)= ' ';
  928. name_len--;
  929. name_ptr->link= name_dir;
  930. (++name_ptr)->byte_start= byte_ptr;
  931. }
  932. set_prefix_length(p,name_len);
  933. (void)strncpy(s,first,name_len);
  934. p->llink= NULL;
  935. p->rlink= NULL;
  936. init_node(p);
  937. return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
  938. }
  939.  
  940. /*:41*//*42:*/
  941. #line 815 "common.w"
  942.  
  943. extend_section_name(p,first,last,ispref)
  944. name_pointer p;
  945. char*first;
  946. char*last;
  947. int ispref;
  948. {
  949. char*s;
  950. name_pointer q= p+1;
  951. int name_len= last-first+ispref;
  952. if(name_ptr>=name_dir_end)overflow("name");
  953. while(q->link!=name_dir)q= q->link;
  954. q->link= name_ptr;
  955. s= name_ptr->byte_start;
  956. name_ptr->link= name_dir;
  957. if(s+name_len>byte_mem_end)overflow("byte memory");
  958. (++name_ptr)->byte_start= byte_ptr= s+name_len;
  959. (void)strncpy(s,first,name_len);
  960. if(ispref)*(byte_ptr-1)= ' ';
  961. }
  962.  
  963. /*:42*//*43:*/
  964. #line 842 "common.w"
  965.  
  966. name_pointer
  967. section_lookup(first,last,ispref)
  968. char*first,*last;
  969. int ispref;
  970. {
  971. int c;
  972. name_pointer p= root;
  973. name_pointer q= NULL;
  974. name_pointer r= NULL;
  975. name_pointer par= NULL;
  976.  
  977. int name_len= last-first+1;
  978. /*44:*/
  979. #line 866 "common.w"
  980.  
  981. while(p){
  982. c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
  983. if(c==less||c==greater){
  984. if(r==NULL)
  985. par= p;
  986. p= (c==less?p->llink:p->rlink);
  987. }else{
  988. if(r!=NULL){
  989. printf("\n! Ambiguous prefix: matches <");
  990.  
  991. print_prefix_name(p);
  992. printf(">\n and <");
  993. print_prefix_name(r);
  994. err_print(">");
  995. return name_dir;
  996. }
  997. r= p;
  998. p= p->llink;
  999. q= r->rlink;
  1000. }
  1001. if(p==NULL)
  1002. p= q,q= NULL;
  1003. }
  1004.  
  1005. /*:44*/
  1006. #line 856 "common.w"
  1007. ;
  1008. /*45:*/
  1009. #line 891 "common.w"
  1010.  
  1011. if(r==NULL)
  1012. return add_section_name(par,c,first,last+1,ispref);
  1013.  
  1014. /*:45*/
  1015. #line 857 "common.w"
  1016. ;
  1017. /*46:*/
  1018. #line 899 "common.w"
  1019.  
  1020. switch(section_name_cmp(&first,name_len,r)){
  1021.  
  1022. case less:case greater:
  1023. printf("\n! Section name incompatible with <");
  1024.  
  1025. print_prefix_name(r);
  1026. printf(">,\n which abbreviates <");
  1027. print_section_name(r);
  1028. err_print(">");
  1029. return r;
  1030. case prefix:
  1031. if(!ispref){
  1032. printf("\n! New name is a prefix of <");
  1033.  
  1034. print_section_name(r);
  1035. err_print(">");
  1036. }
  1037. else if(name_len<prefix_length(r))set_prefix_length(r,name_len);
  1038.  
  1039. case equal:return r;
  1040. case extension:if(!ispref||first<=last)
  1041. extend_section_name(r,first,last+1,ispref);
  1042. return r;
  1043. case bad_extension:
  1044. printf("\n! New name extends <");
  1045.  
  1046. print_section_name(r);
  1047. err_print(">");
  1048. return r;
  1049. }
  1050.  
  1051. /*:46*/
  1052. #line 858 "common.w"
  1053. ;
  1054. }
  1055.  
  1056. /*:43*//*47:*/
  1057. #line 947 "common.w"
  1058.  
  1059. section_name_cmp(pfirst,len,r)
  1060. char**pfirst;
  1061. int len;
  1062. name_pointer r;
  1063. {
  1064. char*first= *pfirst;
  1065. name_pointer q= r+1;
  1066. char*ss,*s= first_chunk(r);
  1067. int c;
  1068. int ispref;
  1069. while(1){
  1070. ss= (r+1)->byte_start-1;
  1071. if(*ss==' '&&ss>=r->byte_start)ispref= 1,q= q->link;
  1072. else ispref= 0,ss++,q= name_dir;
  1073. switch(c= web_strcmp(first,len,s,ss-s)){
  1074. case equal:if(q==name_dir)
  1075. if(ispref){
  1076. *pfirst= first+(ss-s);
  1077. return extension;
  1078. }else return equal;
  1079. else return(q->byte_start==(q+1)->byte_start)?equal:prefix;
  1080. case extension:
  1081. if(!ispref)return bad_extension;
  1082. first+= ss-s;
  1083. if(q!=name_dir){len-= ss-s;s= q->byte_start;r= q;continue;}
  1084. *pfirst= first;return extension;
  1085. default:return c;
  1086. }
  1087. }
  1088. }
  1089.  
  1090. /*:47*/
  1091.