18 #define banner "This is CTANGLE (Version 3.64)\n" \
20 #define max_bytes 90000 \
22 #define max_toks 270000
23 #define max_names 4000 \
25 #define max_texts 2500
27 #define longest_name 10000
29 #define buf_size 100 \
38 #define minus_minus 01
45 #define dot_dot_dot 016
46 #define colon_colon 06
47 #define period_ast 026
48 #define minus_gt_ast 027 \
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) ) \
57 #define length(c) (c+1) ->byte_start-(c) ->byte_start
58 #define print_id(c) term_write((c) ->byte_start,length((c) ) )
60 #define rlink dummy.Rlink
61 #define root name_dir->rlink \
63 #define chunk_marker 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) \
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] \
79 #define show_banner flags['b']
80 #define show_progress flags['p']
81 #define show_happiness flags['h'] \
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) \
90 #define equiv equiv_or_xref \
92 #define section_flag max_texts \
96 #define output_defs_flag (2*024000-1) \
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 \
104 #define section_number 0201
105 #define identifier 0202 \
110 #define unbreakable 3
113 #define max_files 256
114 #define translit_length 10 \
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
124 #define section_name 0311
125 #define new_section 0312 \
127 #define constant 03 \
129 #define isxalpha(c) ((c) =='_'||(c) =='$') \
131 #define ishigh(c) ((unsigned char) (c) > 0177) \
134 #define compress(c) if(loc++<=limit) return(c) \
137 #define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \
145 typedef short boolean
;
146 typedef char unsigned eight_bits
;
147 extern boolean program
;
153 char section_text
[longest_name
+1];
154 char*section_text_end
= section_text
+longest_name
;
161 extern char buffer
[];
162 extern char*buffer_end
;
169 typedef struct name_info
{
171 struct name_info
*link
;
173 struct name_info
*Rlink
;
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();
201 extern void overflow();
206 extern include_depth
;
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
];
215 extern char change_file_name
[];
218 extern boolean input_has_ended
;
219 extern boolean changing
;
220 extern boolean web_file_open
;
221 extern reset_input();
223 extern check_complete();
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
;
239 extern boolean flags
[];
245 extern FILE*tex_file
;
246 extern FILE*idx_file
;
247 extern FILE*scn_file
;
248 extern FILE*active_file
;
253 extern void common_init();
254 #line 128 "ctangle.w"
260 #line 152 "ctangle.w"
263 eight_bits
*tok_start
;
264 sixteen_bits text_link
;
266 typedef text
*text_pointer
;
269 #line 296 "ctangle.w"
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
;
278 typedef output_state
*stack_pointer
;
284 #line 159 "ctangle.w"
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;
294 #line 227 "ctangle.w"
296 text_pointer last_unnamed
;
299 #line 312 "ctangle.w"
301 output_state cur_state
;
303 output_state stack
[stack_size
+1];
304 stack_pointer stack_ptr
;
305 stack_pointer stack_end
= stack
+stack_size
;
308 #line 384 "ctangle.w"
313 #line 473 "ctangle.w"
315 eight_bits out_state
;
319 #line 502 "ctangle.w"
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
];
327 #line 599 "ctangle.w"
329 boolean output_defs_seen
= 0;
332 #line 710 "ctangle.w"
334 char translit
[128][translit_length
];
337 #line 789 "ctangle.w"
339 eight_bits ccode
[256];
342 #line 845 "ctangle.w"
344 boolean comment_continues
= 0;
347 #line 884 "ctangle.w"
349 name_pointer cur_section_name
;
353 #line 1195 "ctangle.w"
355 text_pointer cur_text
;
356 eight_bits next_control
;
359 #line 1350 "ctangle.w"
361 extern sixteen_bits section_count
;
371 extern char*strcpy();
372 extern int strncmp();
373 extern char*strncpy();
376 #line 533 "ctangle.w"
381 #line 602 "ctangle.w"
386 #line 648 "ctangle.w"
388 static void out_char();
391 #line 1457 "ctangle.w"
396 #line 1475 "ctangle.w"
414 #line 167 "ctangle.w"
416 text_info
->tok_start
= tok_ptr
= tok_mem
;
417 text_ptr
= text_info
+1;text_ptr
->tok_start
= tok_mem
;
421 #line 177 "ctangle.w"
423 name_dir
->equiv
= (char*)text_info
;
426 #line 230 "ctangle.w"
427 last_unnamed
= text_info
;text_info
->text_link
= 0;
430 #line 512 "ctangle.w"
432 cur_out_file
= end_output_files
= output_files
+max_files
;
435 #line 713 "ctangle.w"
439 for(i
= 0;i
<128;i
++)sprintf(translit
[i
],"X%02X",(unsigned)(128+i
));
443 #line 792 "ctangle.w"
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
;
458 ccode
['<']= ccode
['(']= section_name
;
463 #line 1116 "ctangle.w"
464 section_text
[0]= ' ';
470 if(show_banner
)printf(banner
);
477 #line 183 "ctangle.w"
479 int names_match(p
,first
,l
)
484 if(length(p
)!=l
)return 0;
485 return!strncmp(first
,p
->byte_start
,l
);
489 #line 198 "ctangle.w"
495 node
->equiv
= (char*)text_info
;
501 #line 260 "ctangle.w"
507 if(tok_ptr
+2> tok_mem_end
)overflow("token");
513 #line 336 "ctangle.w"
519 if(stack_ptr
==stack_end
)overflow("stack");
520 *stack_ptr
= cur_state
;
523 cur_name
= p
;cur_repl
= (text_pointer
)p
->equiv
;
524 cur_byte
= cur_repl
->tok_start
;cur_end
= (cur_repl
+1)->tok_start
;
530 #line 355 "ctangle.w"
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
;
542 if(stack_ptr
> stack
)cur_state
= *stack_ptr
;
546 #line 391 "ctangle.w"
552 restart
:if(stack_ptr
==stack
)return;
553 if(cur_byte
==cur_end
){
554 cur_val
= -((int)cur_section
);
556 if(cur_val
==0)goto restart
;
557 out_char(section_number
);return;
560 if(out_state
==verbatim
&&a
!=string
&&a
!=constant
&&a
!='\n')
562 else if(a
<0200)out_char(a
);
564 a
= (a
-0200)*0400+*cur_byte
++;
566 case 0:cur_val
= a
;out_char(identifier
);break;
567 case 1:if(a
==output_defs_flag
)output_defs();
569 #line 423 "ctangle.w"
573 if((a
+name_dir
)->equiv
!=(char*)text_info
)push_level(a
+name_dir
);
575 printf("\n! Not present: <");
576 print_section_name(a
+name_dir
);err_print(">");
583 #line 412 "ctangle.w"
586 default:cur_val
= a
-050000;if(cur_val
> 0)cur_section
= cur_val
;
587 out_char(section_number
);
593 #line 481 "ctangle.w"
599 if(cur_line
%100==0&&show_progress
){
601 if(cur_line
%500==0)printf("%d",cur_line
);
608 #line 536 "ctangle.w"
615 #line 325 "ctangle.w"
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;
621 #line 541 "ctangle.w"
624 #line 595 "ctangle.w"
626 if(!output_defs_seen
)
630 #line 542 "ctangle.w"
632 if(text_info
->text_link
==0&&cur_out_file
==end_output_files
){
633 printf("\n! No program text was specified.");mark_harmless
;
637 if(cur_out_file
==end_output_files
){
639 printf("\nWriting the output file (%s):",C_file_name
);
643 printf("\nWriting the output files:");
645 printf(" (%s)",C_file_name
);
648 if(text_info
->text_link
==0)goto writeloop
;
650 while(stack_ptr
> stack
)get_output();
653 #line 572 "ctangle.w"
655 for(an_output_file
= end_output_files
;an_output_file
> cur_out_file
;){
657 sprint_section_name(output_file_name
,*an_output_file
);
659 C_file
= fopen(output_file_name
,"w");
660 if(C_file
==0)fatal("! Cannot open output file:",output_file_name
);
662 printf("\n(%s)",output_file_name
);update_terminal
;
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();
674 #line 563 "ctangle.w"
676 if(show_happiness
)printf("\nDone.");
681 #line 605 "ctangle.w"
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 ");
695 while(cur_byte
<cur_end
){
697 if(cur_byte
==cur_end
&&a
=='\n')break;
698 if(out_state
==verbatim
&&a
!=string
&&a
!=constant
&&a
!='\n')
701 else if(a
<0200)out_char(a
);
703 a
= (a
-0200)*0400+*cur_byte
++;
705 cur_val
= a
;out_char(identifier
);
707 else if(a
<050000){confusion("macro defs have strange char");}
709 cur_val
= a
-050000;cur_section
= cur_val
;out_char(section_number
);
721 #line 651 "ctangle.w"
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;
734 #line 719 "ctangle.w"
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
;
741 if((unsigned char)(*j
)<0200)C_putc(*j
);
743 else C_printf("%s",translit
[(unsigned char)(*j
)-0200]);
746 out_state
= num_or_id
;break;
749 #line 662 "ctangle.w"
752 #line 732 "ctangle.w"
755 if(cur_val
> 0)C_printf("/*%d:*/",cur_val
);
756 else if(cur_val
<0)C_printf("/*:%d*/",-cur_val
);
765 C_printf("\n#line %d \"",a
);
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
;
771 if(*j
=='\\'||*j
=='"')C_putc('\\');
774 C_printf("%s","\"\n");
779 #line 663 "ctangle.w"
782 #line 681 "ctangle.w"
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
;
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
;
803 #line 664 "ctangle.w"
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;
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(' ');
817 default:C_putc(cur_char
);out_state
= normal
;break;
822 #line 813 "ctangle.w"
829 if(loc
> limit
&&(get_line()==0))return(new_section
);
831 while(*loc
!='@')loc
++;
833 loc
++;c
= ccode
[(eight_bits
)*loc
];loc
++;
834 if(c
!=ignore
||*(loc
-1)=='>')return(c
);
840 #line 848 "ctangle.w"
842 int skip_comment(is_long_comment
)
843 boolean is_long_comment
;
849 if(get_line())return(comment_continues
= 1);
851 err_print("! Input ended in mid-comment");
853 return(comment_continues
= 0);
856 else return(comment_continues
= 0);
859 if(is_long_comment
&&c
=='*'&&*loc
=='/'){
860 loc
++;return(comment_continues
= 0);
863 if(ccode
[(eight_bits
)*loc
]==new_section
){
864 err_print("! Section name ended in mid-comment");loc
--;
866 return(comment_continues
= 0);
874 #line 900 "ctangle.w"
879 static int preprocessing
= 0;
883 if(preprocessing
&&*(limit
-1)!='\\')preprocessing
= 0;
884 if(get_line()==0)return(new_section
);
885 else if(print_where
&&!no_where
){
888 #line 1225 "ctangle.w"
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);
900 #line 912 "ctangle.w"
906 if(comment_continues
||(c
=='/'&&(*(loc
+1)=='*'||*(loc
+1)=='/'))){
907 skip_comment(comment_continues
||*(loc
+1)=='*');
909 if(comment_continues
)return('\n');
913 if(xisdigit(c
)||c
=='.')/*66:*/
914 #line 978 "ctangle.w"
917 if(*id_first
=='.'&&!xisdigit(*loc
))goto mistake
;
919 if(*loc
=='x'||*loc
=='X'){
920 loc
++;while(xisxdigit(*loc
))loc
++;goto found
;
923 while(xisdigit(*loc
))loc
++;
926 while(xisdigit(*loc
))loc
++;
928 if(*loc
=='e'||*loc
=='E'){
929 if(*++loc
=='+'||*loc
=='-')loc
++;
930 while(xisdigit(*loc
))loc
++;
932 found
:while(*loc
=='u'||*loc
=='U'||*loc
=='l'||*loc
=='L'
933 ||*loc
=='f'||*loc
=='F')loc
++;
939 #line 924 "ctangle.w"
941 else if(c
=='\''||c
=='"'||(c
=='L'&&(*loc
=='\''||*loc
=='"')))
943 #line 1006 "ctangle.w"
946 id_first
= section_text
+1;
947 id_loc
= section_text
;*++id_loc
= delim
;
949 delim
= *loc
++;*++id_loc
= delim
;
953 if(*(limit
-1)!='\\'){
954 err_print("! String didn't end");loc
= limit
;break;
958 err_print("! Input ended in middle of string");loc
= buffer
;break;
961 else if(++id_loc
<=section_text_end
)*id_loc
= '\n';
964 if((c
= *loc
++)==delim
){
965 if(++id_loc
<=section_text_end
)*id_loc
= c
;
969 if(loc
>=limit
)continue;
970 if(++id_loc
<=section_text_end
)*id_loc
= '\\';
973 if(++id_loc
<=section_text_end
)*id_loc
= c
;
975 if(id_loc
>=section_text_end
){
976 printf("\n! String too long: ");
978 term_write(section_text
+1,25);
986 #line 926 "ctangle.w"
988 else if(isalpha(c
)||isxalpha(c
)||ishigh(c
))
990 #line 972 "ctangle.w"
993 while(isalpha(*++loc
)||isdigit(*loc
)||isxalpha(*loc
)||ishigh(*loc
));
994 id_loc
= loc
;return(identifier
);
998 #line 928 "ctangle.w"
1000 else if(c
=='@')/*68:*/
1001 #line 1050 "ctangle.w"
1003 c
= ccode
[(eight_bits
)*loc
++];
1005 case ignore
:continue;
1006 case translit_code
:err_print("! Use @l in limbo only");continue;
1008 case control_text
:while((c
= skip_ahead())=='@');
1011 err_print("! Double @ should be used in control text");
1015 cur_section_name_char
= *(loc
-1);
1017 #line 1098 "ctangle.w"
1021 #line 1118 "ctangle.w"
1025 if(loc
> limit
&&get_line()==0){
1026 err_print("! Input ended in section name");
1028 loc
= buffer
+1;break;
1032 #line 1142 "ctangle.w"
1039 if(ccode
[(eight_bits
)c
]==new_section
){
1040 err_print("! Section name didn't end");break;
1043 if(ccode
[(eight_bits
)c
]==section_name
){
1044 err_print("! Nesting of section names not allowed");break;
1051 #line 1127 "ctangle.w"
1053 loc
++;if(k
<section_text_end
)k
++;
1055 c
= ' ';if(*(k
-1)==' ')k
--;
1059 if(k
>=section_text_end
){
1060 printf("\n! Section name too long: ");
1062 term_write(section_text
+1,25);
1063 printf("...");mark_harmless
;
1065 if(*k
==' '&&k
> section_text
)k
--;
1068 #line 1100 "ctangle.w"
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
=='(')
1075 #line 516 "ctangle.w"
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
;
1085 overflow("output files");
1091 #line 1106 "ctangle.w"
1093 return(section_name
);
1097 #line 1064 "ctangle.w"
1100 #line 1164 "ctangle.w"
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");
1106 id_loc
= loc
;loc
+= 2;
1111 #line 1065 "ctangle.w"
1114 #line 1077 "ctangle.w"
1118 if(*++loc
=='\'')loc
++;
1123 err_print("! Double @ should be used in ASCII constant");
1129 err_print("! String didn't end");loc
= limit
-1;break;
1137 #line 1066 "ctangle.w"
1144 #line 929 "ctangle.w"
1146 else if(xisspace(c
)){
1147 if(!preprocessing
||loc
> limit
)continue;
1151 else if(c
=='#'&&loc
==buffer
+1)preprocessing
= 1;
1153 #line 950 "ctangle.w"
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
);
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;
1177 #line 936 "ctangle.w"
1184 #line 1199 "ctangle.w"
1191 if(t
==section_name
){/*77:*/
1192 #line 1225 "ctangle.w"
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);
1204 #line 1205 "ctangle.w"
1206 while(1)switch(a
= get_next()){
1208 #line 1235 "ctangle.w"
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
;
1216 #line 1268 "ctangle.w"
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");
1229 #line 1241 "ctangle.w"
1231 a
= cur_section_name
-name_dir
;
1232 app_repl((a
/0400)+0250);
1235 #line 1225 "ctangle.w"
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);
1247 #line 1245 "ctangle.w"
1250 case output_defs_code
:if(t
!=section_name
)err_print("! Misplaced @h");
1253 output_defs_seen
= 1;
1254 a
= output_defs_flag
;
1255 app_repl((a
/0400)+0200);
1258 #line 1225 "ctangle.w"
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);
1270 #line 1254 "ctangle.w"
1274 case constant
:case string
:
1276 #line 1279 "ctangle.w"
1279 while(id_first
<id_loc
){
1281 if(*(id_first
+1)=='@')id_first
++;
1282 else err_print("! Double @ should be used in string");
1285 app_repl(*id_first
++);
1290 #line 1258 "ctangle.w"
1294 #line 1295 "ctangle.w"
1296 int c
= (eight_bits
)*id_first
;
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';
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;
1317 if(xisdigit(*(id_first
+1)))c
= *(++id_first
)-'0';
1318 else if(xisxdigit(*(id_first
+1))){
1320 c
= toupper(*id_first
)-'A'+10;
1322 if(xisdigit(*(id_first
+1)))c
= 16*c
+*(++id_first
)-'0';
1323 else if(xisxdigit(*(id_first
+1))){
1325 c
= 16*c
+toupper(*id_first
)-'A'+10;
1328 case'\\':c
= '\\';break;
1329 case'\'':c
= '\'';break;
1330 case'\"':c
= '\"';break;
1331 default:err_print("! Unrecognized escape sequence");
1337 if(c
>=100)app_repl('0'+c
/100);
1338 if(c
>=10)app_repl('0'+(c
/10)%10);
1345 #line 1260 "ctangle.w"
1347 case definition
:case format_code
:case begin_C
:if(t
!=section_name
)goto done
;
1349 err_print("! @d, @f and @c are ignored in C text");continue;
1352 case new_section
:goto done
;
1355 #line 1210 "ctangle.w"
1357 case')':app_repl(a
);
1358 if(t
==macro
)app_repl(' ');
1360 default:app_repl(a
);
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
;
1368 #line 1357 "ctangle.w"
1376 section_count
++;no_where
= 1;
1377 if(*(loc
-1)=='*'&&show_progress
){
1378 printf("*%d",section_count
);update_terminal
;
1383 #line 1396 "ctangle.w"
1385 while(next_control
<definition
)
1387 if((next_control
= skip_ahead())==section_name
){
1388 loc
-= 2;next_control
= get_next();
1392 #line 1371 "ctangle.w"
1394 if(next_control
==definition
){
1396 #line 1403 "ctangle.w"
1398 while((next_control
= get_next())=='\n');
1399 if(next_control
!=identifier
){
1400 err_print("! Definition flushed, must start with identifier");
1404 app_repl(((a
= id_lookup(id_first
,id_loc
,0)-name_dir
)/0400)+0200);
1408 app_repl(string
);app_repl(' ');app_repl(string
);
1411 cur_text
->text_link
= 0;
1415 #line 1373 "ctangle.w"
1419 if(next_control
==begin_C
){
1422 if(next_control
==section_name
){
1423 p
= cur_section_name
;
1425 #line 1428 "ctangle.w"
1427 while((next_control
= get_next())=='+');
1428 if(next_control
!='='&&next_control
!=eq_eq
)
1432 #line 1381 "ctangle.w"
1438 no_where
= print_where
= 0;
1440 #line 1433 "ctangle.w"
1443 #line 1438 "ctangle.w"
1445 store_two_bytes((sixteen_bits
)(0150000+section_count
));
1449 #line 1434 "ctangle.w"
1451 scan_repl(section_name
);
1453 #line 1442 "ctangle.w"
1455 if(p
==name_dir
||p
==0){
1456 (last_unnamed
)->text_link
= cur_text
-text_info
;last_unnamed
= cur_text
;
1458 else if(p
->equiv
==(char*)text_info
)p
->equiv
= (char*)cur_text
;
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
;
1466 cur_text
->text_link
= section_flag
;
1470 #line 1436 "ctangle.w"
1474 #line 1387 "ctangle.w"
1479 #line 1460 "ctangle.w"
1487 while(!input_has_ended
)scan_section();
1493 #line 1478 "ctangle.w"
1500 if(loc
> limit
&&get_line()==0)return;
1502 while(*loc
!='@')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"
1510 while(xisspace(*loc
)&&loc
<limit
)loc
++;
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");
1519 sscanf(loc
-3,"%x",&i
);
1520 while(xisspace(*loc
)&&loc
<limit
)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");
1527 strncpy(translit
[i
-0200],beg
,loc
-beg
);
1528 translit
[i
-0200][loc
-beg
]= '\0';
1533 #line 1491 "ctangle.w"
1535 case format_code
:case'@':break;
1536 case control_text
:if(c
=='q'||c
=='Q'){
1537 while((c
= skip_ahead())=='@');
1539 err_print("! Double @ should be used in control text");
1543 default:err_print("! Double @ should be used in limbo");
1551 #line 1533 "ctangle.w"
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
);