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