1 /*1:*/
2 #line 64 "ctangle.w"
3 
4 /*6:*/
5 #line 35 "common.h"
6 
7 #include <stdio.h>
8 
9 /*:6*//*62:*/
10 #line 888 "ctangle.w"
11 
12 #include <ctype.h>
13 #include <stdlib.h>
14 
15 /*:62*/
16 #line 65 "ctangle.w"
17 
18 #define banner "This is CTANGLE (Version 3.64)\n" \
19 
20 #define max_bytes 90000 \
21 
22 #define max_toks 270000
23 #define max_names 4000 \
24 
25 #define max_texts 2500
26 #define hash_size 353
27 #define longest_name 10000
28 #define stack_size 50
29 #define buf_size 100 \
30 
31 #define ctangle 0
32 #define cweave 1 \
33 
34 #define and_and 04
35 #define lt_lt 020
36 #define gt_gt 021
37 #define plus_plus 013
38 #define minus_minus 01
39 #define minus_gt 031
40 #define not_eq 032
41 #define lt_eq 034
42 #define gt_eq 035
43 #define eq_eq 036
44 #define or_or 037
45 #define dot_dot_dot 016
46 #define colon_colon 06
47 #define period_ast 026
48 #define minus_gt_ast 027 \
49 
50 #define xisalpha(c) (isalpha(c) &&((eight_bits) c<0200) )
51 #define xisdigit(c) (isdigit(c) &&((eight_bits) c<0200) )
52 #define xisspace(c) (isspace(c) &&((eight_bits) c<0200) )
53 #define xislower(c) (islower(c) &&((eight_bits) c<0200) )
54 #define xisupper(c) (isupper(c) &&((eight_bits) c<0200) )
55 #define xisxdigit(c) (isxdigit(c) &&((eight_bits) c<0200) )  \
56 
57 #define length(c) (c+1) ->byte_start-(c) ->byte_start
58 #define print_id(c) term_write((c) ->byte_start,length((c) ) )
59 #define llink link
60 #define rlink dummy.Rlink
61 #define root name_dir->rlink \
62 
63 #define chunk_marker 0 \
64 
65 #define spotless 0
66 #define harmless_message 1
67 #define error_message 2
68 #define fatal_message 3
69 #define mark_harmless {if(history==spotless) history= harmless_message;}
70 #define mark_error history= error_message
71 #define confusion(s) fatal("! This can't happen: ",s)  \
72 
73 #define max_file_name_length 60
74 #define cur_file file[include_depth]
75 #define cur_file_name file_name[include_depth]
76 #define web_file_name file_name[0]
77 #define cur_line line[include_depth] \
78 
79 #define show_banner flags['b']
80 #define show_progress flags['p']
81 #define show_happiness flags['h'] \
82 
83 #define update_terminal fflush(stdout)
84 #define new_line putchar('\n')
85 #define putxchar putchar
86 #define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout)
87 #define C_printf(c,a) fprintf(C_file,c,a)
88 #define C_putc(c) putc(c,C_file)  \
89 
90 #define equiv equiv_or_xref \
91 
92 #define section_flag max_texts \
93 
94 #define string 02
95 #define join 0177
96 #define output_defs_flag (2*024000-1)  \
97 
98 #define cur_end cur_state.end_field
99 #define cur_byte cur_state.byte_field
100 #define cur_name cur_state.name_field
101 #define cur_repl cur_state.repl_field
102 #define cur_section cur_state.section_field \
103 
104 #define section_number 0201
105 #define identifier 0202 \
106 
107 #define normal 0
108 #define num_or_id 1
109 #define post_slash 2
110 #define unbreakable 3
111 #define verbatim 4 \
112 
113 #define max_files 256
114 #define translit_length 10 \
115 
116 #define ignore 0
117 #define ord 0302
118 #define control_text 0303
119 #define translit_code 0304
120 #define output_defs_code 0305
121 #define format_code 0306
122 #define definition 0307
123 #define begin_C 0310
124 #define section_name 0311
125 #define new_section 0312 \
126 
127 #define constant 03 \
128 
129 #define isxalpha(c) ((c) =='_'||(c) =='$')  \
130 
131 #define ishigh(c) ((unsigned char) (c) > 0177)  \
132  \
133 
134 #define compress(c) if(loc++<=limit) return(c)  \
135 
136 #define macro 0
137 #define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \
138 
139 
140 #line 66 "ctangle.w"
141 
142 /*5:*/
143 #line 29 "common.h"
144 
145 typedef short boolean;
146 typedef char unsigned eight_bits;
147 extern boolean program;
148 extern int phase;
149 
150 /*:5*//*7:*/
151 #line 57 "common.h"
152 
153 char section_text[longest_name+1];
154 char*section_text_end= section_text+longest_name;
155 char*id_first;
156 char*id_loc;
157 
158 /*:7*//*8:*/
159 #line 72 "common.h"
160 
161 extern char buffer[];
162 extern char*buffer_end;
163 extern char*loc;
164 extern char*limit;
165 
166 /*:8*//*9:*/
167 #line 87 "common.h"
168 
169 typedef struct name_info{
170 char*byte_start;
171 struct name_info*link;
172 union{
173 struct name_info*Rlink;
174 
175 char Ilk;
176 }dummy;
177 char*equiv_or_xref;
178 }name_info;
179 typedef name_info*name_pointer;
180 typedef name_pointer*hash_pointer;
181 extern char byte_mem[];
182 extern char*byte_mem_end;
183 extern name_info name_dir[];
184 extern name_pointer name_dir_end;
185 extern name_pointer name_ptr;
186 extern char*byte_ptr;
187 extern name_pointer hash[];
188 extern hash_pointer hash_end;
189 extern hash_pointer h;
190 extern name_pointer id_lookup();
191 extern name_pointer section_lookup();
192 extern void print_section_name(),sprint_section_name();
193 
194 /*:9*//*10:*/
195 #line 122 "common.h"
196 
197 extern history;
198 extern err_print();
199 extern wrap_up();
200 extern void fatal();
201 extern void overflow();
202 
203 /*:10*//*11:*/
204 #line 137 "common.h"
205 
206 extern include_depth;
207 extern FILE*file[];
208 extern FILE*change_file;
209 extern char C_file_name[];
210 extern char tex_file_name[];
211 extern char idx_file_name[];
212 extern char scn_file_name[];
213 extern char file_name[][max_file_name_length];
214 
215 extern char change_file_name[];
216 extern line[];
217 extern change_line;
218 extern boolean input_has_ended;
219 extern boolean changing;
220 extern boolean web_file_open;
221 extern reset_input();
222 extern get_line();
223 extern check_complete();
224 
225 /*:11*//*12:*/
226 #line 158 "common.h"
227 
228 typedef unsigned short sixteen_bits;
229 extern sixteen_bits section_count;
230 extern boolean changed_section[];
231 extern boolean change_pending;
232 extern boolean print_where;
233 
234 /*:12*//*13:*/
235 #line 170 "common.h"
236 
237 extern int argc;
238 extern char**argv;
239 extern boolean flags[];
240 
241 /*:13*//*14:*/
242 #line 182 "common.h"
243 
244 extern FILE*C_file;
245 extern FILE*tex_file;
246 extern FILE*idx_file;
247 extern FILE*scn_file;
248 extern FILE*active_file;
249 
250 /*:14*//*15:*/
251 #line 191 "common.h"
252 
253 extern void common_init();
254 #line 128 "ctangle.w"
255 
256 /*:15*/
257 #line 67 "ctangle.w"
258 
259 /*16:*/
260 #line 152 "ctangle.w"
261 
262 typedef struct{
263 eight_bits*tok_start;
264 sixteen_bits text_link;
265 }text;
266 typedef text*text_pointer;
267 
268 /*:16*//*27:*/
269 #line 296 "ctangle.w"
270 
271 typedef struct{
272 eight_bits*end_field;
273 eight_bits*byte_field;
274 name_pointer name_field;
275 text_pointer repl_field;
276 sixteen_bits section_field;
277 }output_state;
278 typedef output_state*stack_pointer;
279 
280 /*:27*/
281 #line 68 "ctangle.w"
282 
283 /*17:*/
284 #line 159 "ctangle.w"
285 
286 text text_info[max_texts];
287 text_pointer text_info_end= text_info+max_texts-1;
288 text_pointer text_ptr;
289 eight_bits tok_mem[max_toks];
290 eight_bits*tok_mem_end= tok_mem+max_toks-1;
291 eight_bits*tok_ptr;
292 
293 /*:17*//*23:*/
294 #line 227 "ctangle.w"
295 
296 text_pointer last_unnamed;
297 
298 /*:23*//*28:*/
299 #line 312 "ctangle.w"
300 
301 output_state cur_state;
302 
303 output_state stack[stack_size+1];
304 stack_pointer stack_ptr;
305 stack_pointer stack_end= stack+stack_size;
306 
307 /*:28*//*32:*/
308 #line 384 "ctangle.w"
309 
310 int cur_val;
311 
312 /*:32*//*36:*/
313 #line 473 "ctangle.w"
314 
315 eight_bits out_state;
316 boolean protect;
317 
318 /*:36*//*38:*/
319 #line 502 "ctangle.w"
320 
321 name_pointer output_files[max_files];
322 name_pointer*cur_out_file,*end_output_files,*an_output_file;
323 char cur_section_name_char;
324 char output_file_name[longest_name];
325 
326 /*:38*//*45:*/
327 #line 599 "ctangle.w"
328 
329 boolean output_defs_seen= 0;
330 
331 /*:45*//*51:*/
332 #line 710 "ctangle.w"
333 
334 char translit[128][translit_length];
335 
336 /*:51*//*56:*/
337 #line 789 "ctangle.w"
338 
339 eight_bits ccode[256];
340 
341 /*:56*//*59:*/
342 #line 845 "ctangle.w"
343 
344 boolean comment_continues= 0;
345 
346 /*:59*//*61:*/
347 #line 884 "ctangle.w"
348 
349 name_pointer cur_section_name;
350 int no_where;
351 
352 /*:61*//*75:*/
353 #line 1195 "ctangle.w"
354 
355 text_pointer cur_text;
356 eight_bits next_control;
357 
358 /*:75*//*82:*/
359 #line 1350 "ctangle.w"
360 
361 extern sixteen_bits section_count;
362 
363 /*:82*/
364 #line 69 "ctangle.w"
365 
366 /*2:*/
367 #line 77 "ctangle.w"
368 
369 extern int strlen();
370 extern int strcmp();
371 extern char*strcpy();
372 extern int strncmp();
373 extern char*strncpy();
374 
375 /*:2*//*41:*/
376 #line 533 "ctangle.w"
377 
378 void phase_two();
379 
380 /*:41*//*46:*/
381 #line 602 "ctangle.w"
382 
383 void output_defs();
384 
385 /*:46*//*48:*/
386 #line 648 "ctangle.w"
387 
388 static void out_char();
389 
390 /*:48*//*90:*/
391 #line 1457 "ctangle.w"
392 
393 void phase_one();
394 
395 /*:90*//*92:*/
396 #line 1475 "ctangle.w"
397 
398 void skip_limbo();
399 
400 /*:92*/
401 #line 70 "ctangle.w"
402 
403 
404 /*:1*//*3:*/
405 #line 91 "ctangle.w"
406 
main(ac,av)407 int main(ac,av)
408 int ac;
409 char**av;
410 {
411 argc= ac;argv= av;
412 program= ctangle;
413 /*18:*/
414 #line 167 "ctangle.w"
415 
416 text_info->tok_start= tok_ptr= tok_mem;
417 text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
418 
419 
420 /*:18*//*20:*/
421 #line 177 "ctangle.w"
422 
423 name_dir->equiv= (char*)text_info;
424 
425 /*:20*//*24:*/
426 #line 230 "ctangle.w"
427 last_unnamed= text_info;text_info->text_link= 0;
428 
429 /*:24*//*39:*/
430 #line 512 "ctangle.w"
431 
432 cur_out_file= end_output_files= output_files+max_files;
433 
434 /*:39*//*52:*/
435 #line 713 "ctangle.w"
436 
437 {
438 int i;
439 for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned)(128+i));
440 }
441 
442 /*:52*//*57:*/
443 #line 792 "ctangle.w"
444 {
445 int c;
446 for(c= 0;c<256;c++)ccode[c]= ignore;
447 ccode[' ']= ccode['\t']= ccode['\n']= ccode['\v']= ccode['\r']= ccode['\f']
448 = ccode['*']= new_section;
449 ccode['@']= '@';ccode['=']= string;
450 ccode['d']= ccode['D']= definition;
451 ccode['f']= ccode['F']= ccode['s']= ccode['S']= format_code;
452 ccode['c']= ccode['C']= ccode['p']= ccode['P']= begin_C;
453 ccode['^']= ccode[':']= ccode['.']= ccode['t']= ccode['T']=
454 ccode['q']= ccode['Q']= control_text;
455 ccode['h']= ccode['H']= output_defs_code;
456 ccode['l']= ccode['L']= translit_code;
457 ccode['&']= join;
458 ccode['<']= ccode['(']= section_name;
459 ccode['\'']= ord;
460 }
461 
462 /*:57*//*71:*/
463 #line 1116 "ctangle.w"
464 section_text[0]= ' ';
465 
466 /*:71*/
467 #line 98 "ctangle.w"
468 ;
469 common_init();
470 if(show_banner)printf(banner);
471 phase_one();
472 phase_two();
473 return wrap_up();
474 }
475 
476 /*:3*//*21:*/
477 #line 183 "ctangle.w"
478 
names_match(p,first,l)479 int names_match(p,first,l)
480 name_pointer p;
481 char*first;
482 int l;
483 {
484 if(length(p)!=l)return 0;
485 return!strncmp(first,p->byte_start,l);
486 }
487 
488 /*:21*//*22:*/
489 #line 198 "ctangle.w"
490 
491 void
init_node(node)492 init_node(node)
493 name_pointer node;
494 {
495 node->equiv= (char*)text_info;
496 }
497 void
init_p()498 init_p(){}
499 
500 /*:22*//*26:*/
501 #line 260 "ctangle.w"
502 
503 void
store_two_bytes(x)504 store_two_bytes(x)
505 sixteen_bits x;
506 {
507 if(tok_ptr+2> tok_mem_end)overflow("token");
508 *tok_ptr++= x>>8;
509 *tok_ptr++= x&0377;
510 }
511 
512 /*:26*//*30:*/
513 #line 336 "ctangle.w"
514 
515 void
push_level(p)516 push_level(p)
517 name_pointer p;
518 {
519 if(stack_ptr==stack_end)overflow("stack");
520 *stack_ptr= cur_state;
521 stack_ptr++;
522 if(p!=NULL){
523 cur_name= p;cur_repl= (text_pointer)p->equiv;
524 cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;
525 cur_section= 0;
526 }
527 }
528 
529 /*:30*//*31:*/
530 #line 355 "ctangle.w"
531 
532 void
pop_level(flag)533 pop_level(flag)
534 int flag;
535 {
536 if(flag&&cur_repl->text_link<section_flag){
537 cur_repl= cur_repl->text_link+text_info;
538 cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;
539 return;
540 }
541 stack_ptr--;
542 if(stack_ptr> stack)cur_state= *stack_ptr;
543 }
544 
545 /*:31*//*33:*/
546 #line 391 "ctangle.w"
547 
548 void
get_output()549 get_output()
550 {
551 sixteen_bits a;
552 restart:if(stack_ptr==stack)return;
553 if(cur_byte==cur_end){
554 cur_val= -((int)cur_section);
555 pop_level(1);
556 if(cur_val==0)goto restart;
557 out_char(section_number);return;
558 }
559 a= *cur_byte++;
560 if(out_state==verbatim&&a!=string&&a!=constant&&a!='\n')
561 C_putc(a);
562 else if(a<0200)out_char(a);
563 else{
564 a= (a-0200)*0400+*cur_byte++;
565 switch(a/024000){
566 case 0:cur_val= a;out_char(identifier);break;
567 case 1:if(a==output_defs_flag)output_defs();
568 else/*34:*/
569 #line 423 "ctangle.w"
570 
571 {
572 a-= 024000;
573 if((a+name_dir)->equiv!=(char*)text_info)push_level(a+name_dir);
574 else if(a!=0){
575 printf("\n! Not present: <");
576 print_section_name(a+name_dir);err_print(">");
577 
578 }
579 goto restart;
580 }
581 
582 /*:34*/
583 #line 412 "ctangle.w"
584 ;
585 break;
586 default:cur_val= a-050000;if(cur_val> 0)cur_section= cur_val;
587 out_char(section_number);
588 }
589 }
590 }
591 
592 /*:33*//*37:*/
593 #line 481 "ctangle.w"
594 
595 void
flush_buffer()596 flush_buffer()
597 {
598 C_putc('\n');
599 if(cur_line%100==0&&show_progress){
600 printf(".");
601 if(cur_line%500==0)printf("%d",cur_line);
602 update_terminal;
603 }
604 cur_line++;
605 }
606 
607 /*:37*//*42:*/
608 #line 536 "ctangle.w"
609 
610 void
phase_two()611 phase_two(){
612 web_file_open= 0;
613 cur_line= 1;
614 /*29:*/
615 #line 325 "ctangle.w"
616 
617 stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info;
618 cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;cur_section= 0;
619 
620 /*:29*/
621 #line 541 "ctangle.w"
622 ;
623 /*44:*/
624 #line 595 "ctangle.w"
625 
626 if(!output_defs_seen)
627 output_defs();
628 
629 /*:44*/
630 #line 542 "ctangle.w"
631 ;
632 if(text_info->text_link==0&&cur_out_file==end_output_files){
633 printf("\n! No program text was specified.");mark_harmless;
634 
635 }
636 else{
637 if(cur_out_file==end_output_files){
638 if(show_progress)
639 printf("\nWriting the output file (%s):",C_file_name);
640 }
641 else{
642 if(show_progress){
643 printf("\nWriting the output files:");
644 
645 printf(" (%s)",C_file_name);
646 update_terminal;
647 }
648 if(text_info->text_link==0)goto writeloop;
649 }
650 while(stack_ptr> stack)get_output();
651 flush_buffer();
652 writeloop:/*43:*/
653 #line 572 "ctangle.w"
654 
655 for(an_output_file= end_output_files;an_output_file> cur_out_file;){
656 an_output_file--;
657 sprint_section_name(output_file_name,*an_output_file);
658 fclose(C_file);
659 C_file= fopen(output_file_name,"w");
660 if(C_file==0)fatal("! Cannot open output file:",output_file_name);
661 
662 printf("\n(%s)",output_file_name);update_terminal;
663 cur_line= 1;
664 stack_ptr= stack+1;
665 cur_name= (*an_output_file);
666 cur_repl= (text_pointer)cur_name->equiv;
667 cur_byte= cur_repl->tok_start;
668 cur_end= (cur_repl+1)->tok_start;
669 while(stack_ptr> stack)get_output();
670 flush_buffer();
671 }
672 
673 /*:43*/
674 #line 563 "ctangle.w"
675 ;
676 if(show_happiness)printf("\nDone.");
677 }
678 }
679 
680 /*:42*//*47:*/
681 #line 605 "ctangle.w"
682 
683 void
output_defs()684 output_defs()
685 {
686 sixteen_bits a;
687 push_level(NULL);
688 for(cur_text= text_info+1;cur_text<text_ptr;cur_text++)
689 if(cur_text->text_link==0){
690 cur_byte= cur_text->tok_start;
691 cur_end= (cur_text+1)->tok_start;
692 C_printf("%s","#define ");
693 out_state= normal;
694 protect= 1;
695 while(cur_byte<cur_end){
696 a= *cur_byte++;
697 if(cur_byte==cur_end&&a=='\n')break;
698 if(out_state==verbatim&&a!=string&&a!=constant&&a!='\n')
699 C_putc(a);
700 
701 else if(a<0200)out_char(a);
702 else{
703 a= (a-0200)*0400+*cur_byte++;
704 if(a<024000){
705 cur_val= a;out_char(identifier);
706 }
707 else if(a<050000){confusion("macro defs have strange char");}
708 else{
709 cur_val= a-050000;cur_section= cur_val;out_char(section_number);
710 }
711 
712 }
713 }
714 protect= 0;
715 flush_buffer();
716 }
717 pop_level(0);
718 }
719 
720 /*:47*//*49:*/
721 #line 651 "ctangle.w"
722 
723 static void
out_char(cur_char)724 out_char(cur_char)
725 eight_bits cur_char;
726 {
727 char*j,*k;
728 restart:
729 switch(cur_char){
730 case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
731 if(protect||out_state==verbatim)C_putc('\\');
732 flush_buffer();if(out_state!=verbatim)out_state= normal;break;
733 /*53:*/
734 #line 719 "ctangle.w"
735 
736 case identifier:
737 if(out_state==num_or_id)C_putc(' ');
738 j= (cur_val+name_dir)->byte_start;
739 k= (cur_val+name_dir+1)->byte_start;
740 while(j<k){
741 if((unsigned char)(*j)<0200)C_putc(*j);
742 
743 else C_printf("%s",translit[(unsigned char)(*j)-0200]);
744 j++;
745 }
746 out_state= num_or_id;break;
747 
748 /*:53*/
749 #line 662 "ctangle.w"
750 ;
751 /*54:*/
752 #line 732 "ctangle.w"
753 
754 case section_number:
755 if(cur_val> 0)C_printf("/*%d:*/",cur_val);
756 else if(cur_val<0)C_printf("/*:%d*/",-cur_val);
757 else if(protect){
758 cur_byte+= 4;
759 cur_char= '\n';
760 goto restart;
761 }else{
762 sixteen_bits a;
763 a= 0400**cur_byte++;
764 a+= *cur_byte++;
765 C_printf("\n#line %d \"",a);
766 
767 cur_val= *cur_byte++;
768 cur_val= 0400*(cur_val-0200)+*cur_byte++;
769 for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start;
770 j<k;j++){
771 if(*j=='\\'||*j=='"')C_putc('\\');
772 C_putc(*j);
773 }
774 C_printf("%s","\"\n");
775 }
776 break;
777 
778 /*:54*/
779 #line 663 "ctangle.w"
780 ;
781 /*50:*/
782 #line 681 "ctangle.w"
783 
784 case plus_plus:C_putc('+');C_putc('+');out_state= normal;break;
785 case minus_minus:C_putc('-');C_putc('-');out_state= normal;break;
786 case minus_gt:C_putc('-');C_putc('>');out_state= normal;break;
787 case gt_gt:C_putc('>');C_putc('>');out_state= normal;break;
788 case eq_eq:C_putc('=');C_putc('=');out_state= normal;break;
789 case lt_lt:C_putc('<');C_putc('<');out_state= normal;break;
790 case gt_eq:C_putc('>');C_putc('=');out_state= normal;break;
791 case lt_eq:C_putc('<');C_putc('=');out_state= normal;break;
792 case not_eq:C_putc('!');C_putc('=');out_state= normal;break;
793 case and_and:C_putc('&');C_putc('&');out_state= normal;break;
794 case or_or:C_putc('|');C_putc('|');out_state= normal;break;
795 case dot_dot_dot:C_putc('.');C_putc('.');C_putc('.');out_state= normal;
796 break;
797 case colon_colon:C_putc(':');C_putc(':');out_state= normal;break;
798 case period_ast:C_putc('.');C_putc('*');out_state= normal;break;
799 case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal;
800 break;
801 
802 /*:50*/
803 #line 664 "ctangle.w"
804 ;
805 case'=':case'>':C_putc(cur_char);C_putc(' ');
806 out_state= normal;break;
807 case join:out_state= unbreakable;break;
808 case constant:if(out_state==verbatim){
809 out_state= num_or_id;break;
810 }
811 if(out_state==num_or_id)C_putc(' ');out_state= verbatim;break;
812 case string:if(out_state==verbatim)out_state= normal;
813 else out_state= verbatim;break;
814 case'/':C_putc('/');out_state= post_slash;break;
815 case'*':if(out_state==post_slash)C_putc(' ');
816 
817 default:C_putc(cur_char);out_state= normal;break;
818 }
819 }
820 
821 /*:49*//*58:*/
822 #line 813 "ctangle.w"
823 
824 eight_bits
skip_ahead()825 skip_ahead()
826 {
827 eight_bits c;
828 while(1){
829 if(loc> limit&&(get_line()==0))return(new_section);
830 *(limit+1)= '@';
831 while(*loc!='@')loc++;
832 if(loc<=limit){
833 loc++;c= ccode[(eight_bits)*loc];loc++;
834 if(c!=ignore||*(loc-1)=='>')return(c);
835 }
836 }
837 }
838 
839 /*:58*//*60:*/
840 #line 848 "ctangle.w"
841 
skip_comment(is_long_comment)842 int skip_comment(is_long_comment)
843 boolean is_long_comment;
844 {
845 char c;
846 while(1){
847 if(loc> limit){
848 if(is_long_comment){
849 if(get_line())return(comment_continues= 1);
850 else{
851 err_print("! Input ended in mid-comment");
852 
853 return(comment_continues= 0);
854 }
855 }
856 else return(comment_continues= 0);
857 }
858 c= *(loc++);
859 if(is_long_comment&&c=='*'&&*loc=='/'){
860 loc++;return(comment_continues= 0);
861 }
862 if(c=='@'){
863 if(ccode[(eight_bits)*loc]==new_section){
864 err_print("! Section name ended in mid-comment");loc--;
865 
866 return(comment_continues= 0);
867 }
868 else loc++;
869 }
870 }
871 }
872 
873 /*:60*//*63:*/
874 #line 900 "ctangle.w"
875 
876 eight_bits
get_next()877 get_next()
878 {
879 static int preprocessing= 0;
880 eight_bits c;
881 while(1){
882 if(loc> limit){
883 if(preprocessing&&*(limit-1)!='\\')preprocessing= 0;
884 if(get_line()==0)return(new_section);
885 else if(print_where&&!no_where){
886 print_where= 0;
887 /*77:*/
888 #line 1225 "ctangle.w"
889 
890 store_two_bytes(0150000);
891 if(changing)id_first= change_file_name;
892 else id_first= cur_file_name;
893 id_loc= id_first+strlen(id_first);
894 if(changing)store_two_bytes((sixteen_bits)change_line);
895 else store_two_bytes((sixteen_bits)cur_line);
896 {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200);
897 app_repl(a%0400);}
898 
899 /*:77*/
900 #line 912 "ctangle.w"
901 ;
902 }
903 else return('\n');
904 }
905 c= *loc;
906 if(comment_continues||(c=='/'&&(*(loc+1)=='*'||*(loc+1)=='/'))){
907 skip_comment(comment_continues||*(loc+1)=='*');
908 
909 if(comment_continues)return('\n');
910 else continue;
911 }
912 loc++;
913 if(xisdigit(c)||c=='.')/*66:*/
914 #line 978 "ctangle.w"
915 {
916 id_first= loc-1;
917 if(*id_first=='.'&&!xisdigit(*loc))goto mistake;
918 if(*id_first=='0'){
919 if(*loc=='x'||*loc=='X'){
920 loc++;while(xisxdigit(*loc))loc++;goto found;
921 }
922 }
923 while(xisdigit(*loc))loc++;
924 if(*loc=='.'){
925 loc++;
926 while(xisdigit(*loc))loc++;
927 }
928 if(*loc=='e'||*loc=='E'){
929 if(*++loc=='+'||*loc=='-')loc++;
930 while(xisdigit(*loc))loc++;
931 }
932 found:while(*loc=='u'||*loc=='U'||*loc=='l'||*loc=='L'
933 ||*loc=='f'||*loc=='F')loc++;
934 id_loc= loc;
935 return(constant);
936 }
937 
938 /*:66*/
939 #line 924 "ctangle.w"
940 
941 else if(c=='\''||c=='"'||(c=='L'&&(*loc=='\''||*loc=='"')))
942 /*67:*/
943 #line 1006 "ctangle.w"
944 {
945 char delim= c;
946 id_first= section_text+1;
947 id_loc= section_text;*++id_loc= delim;
948 if(delim=='L'){
949 delim= *loc++;*++id_loc= delim;
950 }
951 while(1){
952 if(loc>=limit){
953 if(*(limit-1)!='\\'){
954 err_print("! String didn't end");loc= limit;break;
955 
956 }
957 if(get_line()==0){
958 err_print("! Input ended in middle of string");loc= buffer;break;
959 
960 }
961 else if(++id_loc<=section_text_end)*id_loc= '\n';
962 
963 }
964 if((c= *loc++)==delim){
965 if(++id_loc<=section_text_end)*id_loc= c;
966 break;
967 }
968 if(c=='\\'){
969 if(loc>=limit)continue;
970 if(++id_loc<=section_text_end)*id_loc= '\\';
971 c= *loc++;
972 }
973 if(++id_loc<=section_text_end)*id_loc= c;
974 }
975 if(id_loc>=section_text_end){
976 printf("\n! String too long: ");
977 
978 term_write(section_text+1,25);
979 err_print("...");
980 }
981 id_loc++;
982 return(string);
983 }
984 
985 /*:67*/
986 #line 926 "ctangle.w"
987 
988 else if(isalpha(c)||isxalpha(c)||ishigh(c))
989 /*65:*/
990 #line 972 "ctangle.w"
991 {
992 id_first= --loc;
993 while(isalpha(*++loc)||isdigit(*loc)||isxalpha(*loc)||ishigh(*loc));
994 id_loc= loc;return(identifier);
995 }
996 
997 /*:65*/
998 #line 928 "ctangle.w"
999 
1000 else if(c=='@')/*68:*/
1001 #line 1050 "ctangle.w"
1002 {
1003 c= ccode[(eight_bits)*loc++];
1004 switch(c){
1005 case ignore:continue;
1006 case translit_code:err_print("! Use @l in limbo only");continue;
1007 
1008 case control_text:while((c= skip_ahead())=='@');
1009 
1010 if(*(loc-1)!='>')
1011 err_print("! Double @ should be used in control text");
1012 
1013 continue;
1014 case section_name:
1015 cur_section_name_char= *(loc-1);
1016 /*70:*/
1017 #line 1098 "ctangle.w"
1018 {
1019 char*k;
1020 /*72:*/
1021 #line 1118 "ctangle.w"
1022 
1023 k= section_text;
1024 while(1){
1025 if(loc> limit&&get_line()==0){
1026 err_print("! Input ended in section name");
1027 
1028 loc= buffer+1;break;
1029 }
1030 c= *loc;
1031 /*73:*/
1032 #line 1142 "ctangle.w"
1033 
1034 if(c=='@'){
1035 c= *(loc+1);
1036 if(c=='>'){
1037 loc+= 2;break;
1038 }
1039 if(ccode[(eight_bits)c]==new_section){
1040 err_print("! Section name didn't end");break;
1041 
1042 }
1043 if(ccode[(eight_bits)c]==section_name){
1044 err_print("! Nesting of section names not allowed");break;
1045 
1046 }
1047 *(++k)= '@';loc++;
1048 }
1049 
1050 /*:73*/
1051 #line 1127 "ctangle.w"
1052 ;
1053 loc++;if(k<section_text_end)k++;
1054 if(xisspace(c)){
1055 c= ' ';if(*(k-1)==' ')k--;
1056 }
1057 *k= c;
1058 }
1059 if(k>=section_text_end){
1060 printf("\n! Section name too long: ");
1061 
1062 term_write(section_text+1,25);
1063 printf("...");mark_harmless;
1064 }
1065 if(*k==' '&&k> section_text)k--;
1066 
1067 /*:72*/
1068 #line 1100 "ctangle.w"
1069 ;
1070 if(k-section_text> 3&&strncmp(k-2,"...",3)==0)
1071 cur_section_name= section_lookup(section_text+1,k-3,1);
1072 else cur_section_name= section_lookup(section_text+1,k,0);
1073 if(cur_section_name_char=='(')
1074 /*40:*/
1075 #line 516 "ctangle.w"
1076 
1077 {
1078 for(an_output_file= cur_out_file;
1079 an_output_file<end_output_files;an_output_file++)
1080 if(*an_output_file==cur_section_name)break;
1081 if(an_output_file==end_output_files){
1082 if(cur_out_file> output_files)
1083 *--cur_out_file= cur_section_name;
1084 else{
1085 overflow("output files");
1086 }
1087 }
1088 }
1089 
1090 /*:40*/
1091 #line 1106 "ctangle.w"
1092 ;
1093 return(section_name);
1094 }
1095 
1096 /*:70*/
1097 #line 1064 "ctangle.w"
1098 ;
1099 case string:/*74:*/
1100 #line 1164 "ctangle.w"
1101 {
1102 id_first= loc++;*(limit+1)= '@';*(limit+2)= '>';
1103 while(*loc!='@'||*(loc+1)!='>')loc++;
1104 if(loc>=limit)err_print("! Verbatim string didn't end");
1105 
1106 id_loc= loc;loc+= 2;
1107 return(string);
1108 }
1109 
1110 /*:74*/
1111 #line 1065 "ctangle.w"
1112 ;
1113 case ord:/*69:*/
1114 #line 1077 "ctangle.w"
1115 
1116 id_first= loc;
1117 if(*loc=='\\'){
1118 if(*++loc=='\'')loc++;
1119 }
1120 while(*loc!='\''){
1121 if(*loc=='@'){
1122 if(*(loc+1)!='@')
1123 err_print("! Double @ should be used in ASCII constant");
1124 
1125 else loc++;
1126 }
1127 loc++;
1128 if(loc> limit){
1129 err_print("! String didn't end");loc= limit-1;break;
1130 
1131 }
1132 }
1133 loc++;
1134 return(ord);
1135 
1136 /*:69*/
1137 #line 1066 "ctangle.w"
1138 ;
1139 default:return(c);
1140 }
1141 }
1142 
1143 /*:68*/
1144 #line 929 "ctangle.w"
1145 
1146 else if(xisspace(c)){
1147 if(!preprocessing||loc> limit)continue;
1148 
1149 else return(' ');
1150 }
1151 else if(c=='#'&&loc==buffer+1)preprocessing= 1;
1152 mistake:/*64:*/
1153 #line 950 "ctangle.w"
1154 
1155 switch(c){
1156 case'+':if(*loc=='+')compress(plus_plus);break;
1157 case'-':if(*loc=='-'){compress(minus_minus);}
1158 else if(*loc=='>')if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);}
1159 else compress(minus_gt);break;
1160 case'.':if(*loc=='*'){compress(period_ast);}
1161 else if(*loc=='.'&&*(loc+1)=='.'){
1162 loc++;compress(dot_dot_dot);
1163 }
1164 break;
1165 case':':if(*loc==':')compress(colon_colon);break;
1166 case'=':if(*loc=='=')compress(eq_eq);break;
1167 case'>':if(*loc=='='){compress(gt_eq);}
1168 else if(*loc=='>')compress(gt_gt);break;
1169 case'<':if(*loc=='='){compress(lt_eq);}
1170 else if(*loc=='<')compress(lt_lt);break;
1171 case'&':if(*loc=='&')compress(and_and);break;
1172 case'|':if(*loc=='|')compress(or_or);break;
1173 case'!':if(*loc=='=')compress(not_eq);break;
1174 }
1175 
1176 /*:64*/
1177 #line 936 "ctangle.w"
1178 
1179 return(c);
1180 }
1181 }
1182 
1183 /*:63*//*76:*/
1184 #line 1199 "ctangle.w"
1185 
1186 void
1187 scan_repl(t)
1188 eight_bits t;
1189 {
1190 sixteen_bits a;
1191 if(t==section_name){/*77:*/
1192 #line 1225 "ctangle.w"
1193 
1194 store_two_bytes(0150000);
1195 if(changing)id_first= change_file_name;
1196 else id_first= cur_file_name;
1197 id_loc= id_first+strlen(id_first);
1198 if(changing)store_two_bytes((sixteen_bits)change_line);
1199 else store_two_bytes((sixteen_bits)cur_line);
1200 {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200);
1201 app_repl(a%0400);}
1202 
1203 /*:77*/
1204 #line 1205 "ctangle.w"
1205 ;}
1206 while(1)switch(a= get_next()){
1207 /*78:*/
1208 #line 1235 "ctangle.w"
1209 
1210 case identifier:a= id_lookup(id_first,id_loc,0)-name_dir;
1211 app_repl((a/0400)+0200);
1212 app_repl(a%0400);break;
1213 case section_name:if(t!=section_name)goto done;
1214 else{
1215 /*79:*/
1216 #line 1268 "ctangle.w"
1217 {
1218 char*try_loc= loc;
1219 while(*try_loc==' '&&try_loc<limit)try_loc++;
1220 if(*try_loc=='+'&&try_loc<limit)try_loc++;
1221 while(*try_loc==' '&&try_loc<limit)try_loc++;
1222 if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
1223 
1224 
1225 
1226 }
1227 
1228 /*:79*/
1229 #line 1241 "ctangle.w"
1230 ;
1231 a= cur_section_name-name_dir;
1232 app_repl((a/0400)+0250);
1233 app_repl(a%0400);
1234 /*77:*/
1235 #line 1225 "ctangle.w"
1236 
1237 store_two_bytes(0150000);
1238 if(changing)id_first= change_file_name;
1239 else id_first= cur_file_name;
1240 id_loc= id_first+strlen(id_first);
1241 if(changing)store_two_bytes((sixteen_bits)change_line);
1242 else store_two_bytes((sixteen_bits)cur_line);
1243 {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200);
1244 app_repl(a%0400);}
1245 
1246 /*:77*/
1247 #line 1245 "ctangle.w"
1248 ;break;
1249 }
1250 case output_defs_code:if(t!=section_name)err_print("! Misplaced @h");
1251 
1252 else{
1253 output_defs_seen= 1;
1254 a= output_defs_flag;
1255 app_repl((a/0400)+0200);
1256 app_repl(a%0400);
1257 /*77:*/
1258 #line 1225 "ctangle.w"
1259 
1260 store_two_bytes(0150000);
1261 if(changing)id_first= change_file_name;
1262 else id_first= cur_file_name;
1263 id_loc= id_first+strlen(id_first);
1264 if(changing)store_two_bytes((sixteen_bits)change_line);
1265 else store_two_bytes((sixteen_bits)cur_line);
1266 {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200);
1267 app_repl(a%0400);}
1268 
1269 /*:77*/
1270 #line 1254 "ctangle.w"
1271 ;
1272 }
1273 break;
1274 case constant:case string:
1275 /*80:*/
1276 #line 1279 "ctangle.w"
1277 
1278 app_repl(a);
1279 while(id_first<id_loc){
1280 if(*id_first=='@'){
1281 if(*(id_first+1)=='@')id_first++;
1282 else err_print("! Double @ should be used in string");
1283 
1284 }
1285 app_repl(*id_first++);
1286 }
1287 app_repl(a);break;
1288 
1289 /*:80*/
1290 #line 1258 "ctangle.w"
1291 ;
1292 case ord:
1293 /*81:*/
1294 #line 1295 "ctangle.w"
1295 {
1296 int c= (eight_bits)*id_first;
1297 if(c=='\\'){
1298 c= *++id_first;
1299 if(c>='0'&&c<='7'){
1300 c-= '0';
1301 if(*(id_first+1)>='0'&&*(id_first+1)<='7'){
1302 c= 8*c+*(++id_first)-'0';
1303 if(*(id_first+1)>='0'&&*(id_first+1)<='7'&&c<32)
1304 c= 8*c+*(++id_first)-'0';
1305 }
1306 }
1307 else switch(c){
1308 case't':c= '\t';break;
1309 case'n':c= '\n';break;
1310 case'b':c= '\b';break;
1311 case'f':c= '\f';break;
1312 case'v':c= '\v';break;
1313 case'r':c= '\r';break;
1314 case'a':c= '\7';break;
1315 case'?':c= '?';break;
1316 case'x':
1317 if(xisdigit(*(id_first+1)))c= *(++id_first)-'0';
1318 else if(xisxdigit(*(id_first+1))){
1319 ++id_first;
1320 c= toupper(*id_first)-'A'+10;
1321 }
1322 if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0';
1323 else if(xisxdigit(*(id_first+1))){
1324 ++id_first;
1325 c= 16*c+toupper(*id_first)-'A'+10;
1326 }
1327 break;
1328 case'\\':c= '\\';break;
1329 case'\'':c= '\'';break;
1330 case'\"':c= '\"';break;
1331 default:err_print("! Unrecognized escape sequence");
1332 
1333 }
1334 }
1335 
1336 app_repl(constant);
1337 if(c>=100)app_repl('0'+c/100);
1338 if(c>=10)app_repl('0'+(c/10)%10);
1339 app_repl('0'+c%10);
1340 app_repl(constant);
1341 }
1342 break;
1343 
1344 /*:81*/
1345 #line 1260 "ctangle.w"
1346 ;
1347 case definition:case format_code:case begin_C:if(t!=section_name)goto done;
1348 else{
1349 err_print("! @d, @f and @c are ignored in C text");continue;
1350 
1351 }
1352 case new_section:goto done;
1353 
1354 /*:78*/
1355 #line 1210 "ctangle.w"
1356 
1357 case')':app_repl(a);
1358 if(t==macro)app_repl(' ');
1359 break;
1360 default:app_repl(a);
1361 }
1362 done:next_control= (eight_bits)a;
1363 if(text_ptr> text_info_end)overflow("text");
1364 cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
1365 }
1366 
1367 /*:76*//*83:*/
1368 #line 1357 "ctangle.w"
1369 
1370 void
1371 scan_section()
1372 {
1373 name_pointer p;
1374 text_pointer q;
1375 sixteen_bits a;
1376 section_count++;no_where= 1;
1377 if(*(loc-1)=='*'&&show_progress){
1378 printf("*%d",section_count);update_terminal;
1379 }
1380 next_control= 0;
1381 while(1){
1382 /*84:*/
1383 #line 1396 "ctangle.w"
1384 
1385 while(next_control<definition)
1386 
1387 if((next_control= skip_ahead())==section_name){
1388 loc-= 2;next_control= get_next();
1389 }
1390 
1391 /*:84*/
1392 #line 1371 "ctangle.w"
1393 ;
1394 if(next_control==definition){
1395 /*85:*/
1396 #line 1403 "ctangle.w"
1397 {
1398 while((next_control= get_next())=='\n');
1399 if(next_control!=identifier){
1400 err_print("! Definition flushed, must start with identifier");
1401 
1402 continue;
1403 }
1404 app_repl(((a= id_lookup(id_first,id_loc,0)-name_dir)/0400)+0200);
1405 
1406 app_repl(a%0400);
1407 if(*loc!='('){
1408 app_repl(string);app_repl(' ');app_repl(string);
1409 }
1410 scan_repl(macro);
1411 cur_text->text_link= 0;
1412 }
1413 
1414 /*:85*/
1415 #line 1373 "ctangle.w"
1416 
1417 continue;
1418 }
1419 if(next_control==begin_C){
1420 p= name_dir;break;
1421 }
1422 if(next_control==section_name){
1423 p= cur_section_name;
1424 /*86:*/
1425 #line 1428 "ctangle.w"
1426 
1427 while((next_control= get_next())=='+');
1428 if(next_control!='='&&next_control!=eq_eq)
1429 continue;
1430 
1431 /*:86*/
1432 #line 1381 "ctangle.w"
1433 ;
1434 break;
1435 }
1436 return;
1437 }
1438 no_where= print_where= 0;
1439 /*87:*/
1440 #line 1433 "ctangle.w"
1441 
1442 /*88:*/
1443 #line 1438 "ctangle.w"
1444 
1445 store_two_bytes((sixteen_bits)(0150000+section_count));
1446 
1447 
1448 /*:88*/
1449 #line 1434 "ctangle.w"
1450 ;
1451 scan_repl(section_name);
1452 /*89:*/
1453 #line 1442 "ctangle.w"
1454 
1455 if(p==name_dir||p==0){
1456 (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
1457 }
1458 else if(p->equiv==(char*)text_info)p->equiv= (char*)cur_text;
1459 
1460 else{
1461 q= (text_pointer)p->equiv;
1462 while(q->text_link<section_flag)
1463 q= q->text_link+text_info;
1464 q->text_link= cur_text-text_info;
1465 }
1466 cur_text->text_link= section_flag;
1467 
1468 
1469 /*:89*/
1470 #line 1436 "ctangle.w"
1471 ;
1472 
1473 /*:87*/
1474 #line 1387 "ctangle.w"
1475 ;
1476 }
1477 
1478 /*:83*//*91:*/
1479 #line 1460 "ctangle.w"
1480 
1481 void
1482 phase_one(){
1483 phase= 1;
1484 section_count= 0;
1485 reset_input();
1486 skip_limbo();
1487 while(!input_has_ended)scan_section();
1488 check_complete();
1489 phase= 2;
1490 }
1491 
1492 /*:91*//*93:*/
1493 #line 1478 "ctangle.w"
1494 
1495 void
1496 skip_limbo()
1497 {
1498 char c;
1499 while(1){
1500 if(loc> limit&&get_line()==0)return;
1501 *(limit+1)= '@';
1502 while(*loc!='@')loc++;
1503 if(loc++<=limit){
1504 c= *loc++;
1505 if(ccode[(eight_bits)c]==new_section)break;
1506 switch(ccode[(eight_bits)c]){
1507 case translit_code:/*94:*/
1508 #line 1507 "ctangle.w"
1509 
1510 while(xisspace(*loc)&&loc<limit)loc++;
1511 loc+= 3;
1512 if(loc> limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2))
1513 ||(*(loc-3)>='0'&&*(loc-3)<='7')||!xisspace(*(loc-1)))
1514 err_print("! Improper hex number following @l");
1515 
1516 else{
1517 unsigned i;
1518 char*beg;
1519 sscanf(loc-3,"%x",&i);
1520 while(xisspace(*loc)&&loc<limit)loc++;
1521 beg= loc;
1522 while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++;
1523 if(loc-beg>=translit_length)
1524 err_print("! Replacement string in @l too long");
1525 
1526 else{
1527 strncpy(translit[i-0200],beg,loc-beg);
1528 translit[i-0200][loc-beg]= '\0';
1529 }
1530 }
1531 
1532 /*:94*/
1533 #line 1491 "ctangle.w"
1534 ;break;
1535 case format_code:case'@':break;
1536 case control_text:if(c=='q'||c=='Q'){
1537 while((c= skip_ahead())=='@');
1538 if(*(loc-1)!='>')
1539 err_print("! Double @ should be used in control text");
1540 
1541 break;
1542 }
1543 default:err_print("! Double @ should be used in limbo");
1544 
1545 }
1546 }
1547 }
1548 }
1549 
1550 /*:93*//*95:*/
1551 #line 1533 "ctangle.w"
1552 
1553 void
1554 print_stats(){
1555 printf("\nMemory usage statistics:\n");
1556 printf("%ld names (out of %ld)\n",
1557 (long)(name_ptr-name_dir),(long)max_names);
1558 printf("%ld replacement texts (out of %ld)\n",
1559 (long)(text_ptr-text_info),(long)max_texts);
1560 printf("%ld bytes (out of %ld)\n",
1561 (long)(byte_ptr-byte_mem),(long)max_bytes);
1562 printf("%ld tokens (out of %ld)\n",
1563 (long)(tok_ptr-tok_mem),(long)max_toks);
1564 }
1565 
1566 /*:95*/
1567