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

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