home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d551 / cweb.lha / CWeb / cweb2.lzh / cweb / SAVEctangle.c < prev   
C/C++ Source or Header  |  1990-12-14  |  24KB  |  1,247 lines

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