Back to index

tetex-bin  3.0
common.c
Go to the documentation of this file.
00001 /*1:*/
00002 #line 58 "common.w"
00003 
00004 /*5:*/
00005 #line 102 "common.w"
00006 
00007 #include <ctype.h> 
00008 
00009 /*:5*//*8:*/
00010 #line 165 "common.w"
00011 
00012 #include <stdio.h> 
00013 
00014 /*:8*//*22:*/
00015 #line 471 "common.w"
00016 
00017 #include <stdlib.h>  
00018 
00019 /*:22*/
00020 #line 59 "common.w"
00021 
00022 #define ctangle 0
00023 #define cweave 1 \
00024 
00025 #define and_and 04
00026 #define lt_lt 020
00027 #define gt_gt 021
00028 #define plus_plus 013
00029 #define minus_minus 01
00030 #define minus_gt 031
00031 #define not_eq 032
00032 #define lt_eq 034
00033 #define gt_eq 035
00034 #define eq_eq 036
00035 #define or_or 037
00036 #define dot_dot_dot 016
00037 #define colon_colon 06
00038 #define period_ast 026
00039 #define minus_gt_ast 027 \
00040 
00041 #define buf_size 100
00042 #define longest_name 1000
00043 #define long_buf_size (buf_size+longest_name) 
00044 #define xisspace(c) (isspace(c) &&((unsigned char) c<0200) ) 
00045 #define xisupper(c) (isupper(c) &&((unsigned char) c<0200) )  \
00046 
00047 #define max_include_depth 10 \
00048 
00049 #define max_file_name_length 60
00050 #define cur_file file[include_depth]
00051 #define cur_file_name file_name[include_depth]
00052 #define cur_line line[include_depth]
00053 #define web_file file[0]
00054 #define web_file_name file_name[0] \
00055 
00056 #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
00057 strncmp(buffer,change_buffer,limit-buffer) )  \
00058 
00059 #define if_section_start_make_pending(b) {*limit= '!'; \
00060 for(loc= buffer;xisspace(*loc) ;loc++) ; \
00061 *limit= ' '; \
00062 if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b; \
00063 } \
00064 
00065 #define max_sections 2000 \
00066  \
00067 
00068 #define too_long() {include_depth--; \
00069 err_print("! Include file name too long") ;goto restart;} \
00070 
00071 #define max_bytes 90000 \
00072 
00073 #define max_names 4000 \
00074  \
00075 
00076 #define length(c) (c+1) ->byte_start-(c) ->byte_start
00077 #define print_id(c) term_write((c) ->byte_start,length((c) ) )  \
00078 
00079 #define hash_size 353 \
00080 
00081 #define llink link
00082 #define rlink dummy.Rlink
00083 #define root name_dir->rlink \
00084  \
00085 
00086 #define first_chunk(p) ((p) ->byte_start+2) 
00087 #define prefix_length(p) (int) ((unsigned char) *((p) ->byte_start) *256+ \
00088 (unsigned char) *((p) ->byte_start+1) ) 
00089 #define set_prefix_length(p,m) (*((p) ->byte_start) = (m) /256, \
00090 *((p) ->byte_start+1) = (m) %256)  \
00091 
00092 #define less 0
00093 #define equal 1
00094 #define greater 2
00095 #define prefix 3
00096 #define extension 4 \
00097 
00098 #define bad_extension 5 \
00099 
00100 #define spotless 0
00101 #define harmless_message 1
00102 #define error_message 2
00103 #define fatal_message 3
00104 #define mark_harmless {if(history==spotless) history= harmless_message;}
00105 #define mark_error history= error_message \
00106 
00107 #define confusion(s) fatal("! This can't happen: ",s)  \
00108  \
00109 
00110 #define show_banner flags['b']
00111 #define show_progress flags['p']
00112 #define show_stats flags['s']
00113 #define show_happiness flags['h'] \
00114 
00115 #define update_terminal fflush(stdout)  \
00116 
00117 #define new_line putchar('\n') 
00118 #define putxchar putchar
00119 #define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) 
00120 #define C_printf(c,a) fprintf(C_file,c,a) 
00121 #define C_putc(c) putc(c,C_file)  \
00122 
00123 
00124 #line 60 "common.w"
00125 
00126 /*2:*/
00127 #line 73 "common.w"
00128 
00129 typedef short boolean;
00130 boolean program;
00131 
00132 /*:2*//*7:*/
00133 #line 159 "common.w"
00134 
00135 char buffer[long_buf_size];
00136 char*buffer_end= buffer+buf_size-2;
00137 char*limit= buffer;
00138 char*loc= buffer;
00139 
00140 /*:7*//*10:*/
00141 #line 214 "common.w"
00142 
00143 int include_depth;
00144 FILE*file[max_include_depth];
00145 FILE*change_file;
00146 char file_name[max_include_depth][max_file_name_length];
00147 
00148 char change_file_name[max_file_name_length];
00149 char alt_web_file_name[max_file_name_length];
00150 int line[max_include_depth];
00151 int change_line;
00152 int change_depth;
00153 boolean input_has_ended;
00154 boolean changing;
00155 boolean web_file_open= 0;
00156 
00157 /*:10*//*20:*/
00158 #line 418 "common.w"
00159 
00160 typedef unsigned short sixteen_bits;
00161 sixteen_bits section_count;
00162 boolean changed_section[max_sections];
00163 boolean change_pending;
00164 
00165 boolean print_where= 0;
00166 
00167 /*:20*//*27:*/
00168 #line 594 "common.w"
00169 
00170 typedef struct name_info{
00171 char*byte_start;
00172 /*31:*/
00173 #line 631 "common.w"
00174 
00175 struct name_info*link;
00176 
00177 /*:31*//*40:*/
00178 #line 730 "common.w"
00179 
00180 union{
00181 struct name_info*Rlink;
00182 
00183 char Ilk;
00184 }dummy;
00185 
00186 /*:40*//*55:*/
00187 #line 1062 "common.w"
00188 
00189 char*equiv_or_xref;
00190 
00191 /*:55*/
00192 #line 597 "common.w"
00193 
00194 }name_info;
00195 typedef name_info*name_pointer;
00196 char byte_mem[max_bytes];
00197 char*byte_mem_end= byte_mem+max_bytes-1;
00198 name_info name_dir[max_names];
00199 name_pointer name_dir_end= name_dir+max_names-1;
00200 
00201 /*:27*//*29:*/
00202 #line 617 "common.w"
00203 
00204 name_pointer name_ptr;
00205 char*byte_ptr;
00206 
00207 /*:29*//*32:*/
00208 #line 644 "common.w"
00209 
00210 typedef name_pointer*hash_pointer;
00211 name_pointer hash[hash_size];
00212 hash_pointer hash_end= hash+hash_size-1;
00213 hash_pointer h;
00214 
00215 /*:32*//*56:*/
00216 #line 1082 "common.w"
00217 
00218 int history= spotless;
00219 
00220 /*:56*//*67:*/
00221 #line 1220 "common.w"
00222 
00223 int argc;
00224 char**argv;
00225 char C_file_name[max_file_name_length];
00226 char tex_file_name[max_file_name_length];
00227 char idx_file_name[max_file_name_length];
00228 char scn_file_name[max_file_name_length];
00229 boolean flags[128];
00230 
00231 /*:67*//*77:*/
00232 #line 1370 "common.w"
00233 
00234 FILE*C_file;
00235 FILE*tex_file;
00236 FILE*idx_file;
00237 FILE*scn_file;
00238 FILE*active_file;
00239 
00240 /*:77*/
00241 #line 61 "common.w"
00242 
00243 /*3:*/
00244 #line 83 "common.w"
00245 int phase;
00246 
00247 /*:3*//*11:*/
00248 #line 240 "common.w"
00249 
00250 char change_buffer[buf_size];
00251 char*change_limit;
00252 
00253 /*:11*/
00254 #line 62 "common.w"
00255 
00256 /*33:*/
00257 #line 650 "common.w"
00258 
00259 extern int names_match();
00260 
00261 /*:33*//*38:*/
00262 #line 703 "common.w"
00263 
00264 void init_p();
00265 
00266 /*:38*//*46:*/
00267 #line 852 "common.w"
00268 
00269 extern void init_node();
00270 
00271 /*:46*//*53:*/
00272 #line 1017 "common.w"
00273 
00274 int section_name_cmp();
00275 
00276 /*:53*//*57:*/
00277 #line 1092 "common.w"
00278 
00279 void err_print();
00280 
00281 /*:57*//*60:*/
00282 #line 1140 "common.w"
00283 
00284 int wrap_up();
00285 extern void print_stats();
00286 
00287 /*:60*//*63:*/
00288 #line 1173 "common.w"
00289 
00290 void fatal(),overflow();
00291 
00292 /*:63*//*69:*/
00293 #line 1251 "common.w"
00294 
00295 void scan_args();
00296 
00297 /*:69*//*81:*/
00298 #line 1411 "common.w"
00299 
00300 extern int strlen();
00301 extern int strcmp();
00302 extern char*strcpy();
00303 extern int strncmp();
00304 extern char*strncpy();
00305 
00306 /*:81*/
00307 #line 63 "common.w"
00308 
00309 
00310 /*:1*//*4:*/
00311 #line 89 "common.w"
00312 
00313 void
00314 common_init()
00315 {
00316 /*30:*/
00317 #line 621 "common.w"
00318 
00319 name_dir->byte_start= byte_ptr= byte_mem;
00320 name_ptr= name_dir+1;
00321 name_ptr->byte_start= byte_mem;
00322 
00323 /*:30*//*34:*/
00324 #line 655 "common.w"
00325 
00326 for(h= hash;h<=hash_end;*h++= NULL);
00327 
00328 /*:34*//*41:*/
00329 #line 737 "common.w"
00330 
00331 root= NULL;
00332 
00333 /*:41*/
00334 #line 93 "common.w"
00335 ;
00336 /*68:*/
00337 #line 1233 "common.w"
00338 
00339 show_banner= show_happiness= show_progress= 1;
00340 
00341 /*:68*/
00342 #line 94 "common.w"
00343 ;
00344 /*78:*/
00345 #line 1377 "common.w"
00346 
00347 scan_args();
00348 if(program==ctangle){
00349 if((C_file= fopen(C_file_name,"w"))==NULL)
00350 fatal("! Cannot open output file ",C_file_name);
00351 
00352 }
00353 else{
00354 if((tex_file= fopen(tex_file_name,"w"))==NULL)
00355 fatal("! Cannot open output file ",tex_file_name);
00356 }
00357 
00358 /*:78*/
00359 #line 95 "common.w"
00360 ;
00361 }
00362 
00363 /*:4*//*9:*/
00364 #line 172 "common.w"
00365 
00366 int input_ln(fp)
00367 FILE*fp;
00368 {
00369 register int c= EOF;
00370 register char*k;
00371 if(feof(fp))return(0);
00372 limit= k= buffer;
00373 while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
00374 if((*(k++)= c)!=' ')limit= k;
00375 if(k> buffer_end)
00376 if((c= getc(fp))!=EOF&&c!='\n'){
00377 ungetc(c,fp);loc= buffer;err_print("! Input line too long");
00378 
00379 }
00380 if(c==EOF&&limit==buffer)return(0);
00381 
00382 return(1);
00383 }
00384 
00385 /*:9*//*12:*/
00386 #line 251 "common.w"
00387 
00388 void
00389 prime_the_change_buffer()
00390 {
00391 change_limit= change_buffer;
00392 /*13:*/
00393 #line 265 "common.w"
00394 
00395 while(1){
00396 change_line++;
00397 if(!input_ln(change_file))return;
00398 if(limit<buffer+2)continue;
00399 if(buffer[0]!='@')continue;
00400 if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
00401 if(buffer[1]=='x')break;
00402 if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
00403 loc= buffer+2;
00404 err_print("! Missing @x in change file");
00405 
00406 }
00407 }
00408 
00409 /*:13*/
00410 #line 256 "common.w"
00411 ;
00412 /*14:*/
00413 #line 282 "common.w"
00414 
00415 do{
00416 change_line++;
00417 if(!input_ln(change_file)){
00418 err_print("! Change file ended after @x");
00419 
00420 return;
00421 }
00422 }while(limit==buffer);
00423 
00424 /*:14*/
00425 #line 257 "common.w"
00426 ;
00427 /*15:*/
00428 #line 292 "common.w"
00429 
00430 {
00431 change_limit= change_buffer+(limit-buffer);
00432 strncpy(change_buffer,buffer,limit-buffer+1);
00433 }
00434 
00435 /*:15*/
00436 #line 258 "common.w"
00437 ;
00438 }
00439 
00440 /*:12*//*16:*/
00441 #line 320 "common.w"
00442 
00443 void
00444 check_change()
00445 {
00446 int n= 0;
00447 if(lines_dont_match)return;
00448 change_pending= 0;
00449 if(!changed_section[section_count]){
00450 if_section_start_make_pending(1);
00451 if(!change_pending)changed_section[section_count]= 1;
00452 }
00453 while(1){
00454 changing= 1;print_where= 1;change_line++;
00455 if(!input_ln(change_file)){
00456 err_print("! Change file ended before @y");
00457 
00458 change_limit= change_buffer;changing= 0;
00459 return;
00460 }
00461 if(limit> buffer+1&&buffer[0]=='@'){
00462 char xyz_code= xisupper(buffer[1])?tolower(buffer[1]):buffer[1];
00463 /*17:*/
00464 #line 358 "common.w"
00465 
00466 if(xyz_code=='x'||xyz_code=='z'){
00467 loc= buffer+2;err_print("! Where is the matching @y?");
00468 
00469 }
00470 else if(xyz_code=='y'){
00471 if(n> 0){
00472 loc= buffer+2;
00473 printf("\n! Hmm... %d ",n);
00474 err_print("of the preceding lines failed to match");
00475 
00476 }
00477 change_depth= include_depth;
00478 return;
00479 }
00480 
00481 /*:17*/
00482 #line 342 "common.w"
00483 ;
00484 }
00485 /*15:*/
00486 #line 292 "common.w"
00487 
00488 {
00489 change_limit= change_buffer+(limit-buffer);
00490 strncpy(change_buffer,buffer,limit-buffer+1);
00491 }
00492 
00493 /*:15*/
00494 #line 344 "common.w"
00495 ;
00496 changing= 0;cur_line++;
00497 while(!input_ln(cur_file)){
00498 if(include_depth==0){
00499 err_print("! CWEB file ended during a change");
00500 
00501 input_has_ended= 1;return;
00502 }
00503 include_depth--;cur_line++;
00504 }
00505 if(lines_dont_match)n++;
00506 }
00507 }
00508 
00509 /*:16*//*18:*/
00510 #line 378 "common.w"
00511 
00512 void
00513 reset_input()
00514 {
00515 limit= buffer;loc= buffer+1;buffer[0]= ' ';
00516 /*19:*/
00517 #line 393 "common.w"
00518 
00519 if((web_file= fopen(web_file_name,"r"))==NULL){
00520 strcpy(web_file_name,alt_web_file_name);
00521 if((web_file= fopen(web_file_name,"r"))==NULL)
00522 fatal("! Cannot open input file ",web_file_name);
00523 }
00524 
00525 
00526 web_file_open= 1;
00527 if((change_file= fopen(change_file_name,"r"))==NULL)
00528 fatal("! Cannot open change file ",change_file_name);
00529 
00530 /*:19*/
00531 #line 383 "common.w"
00532 ;
00533 include_depth= 0;cur_line= 0;change_line= 0;
00534 change_depth= include_depth;
00535 changing= 1;prime_the_change_buffer();changing= !changing;
00536 limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
00537 }
00538 
00539 /*:18*//*21:*/
00540 #line 426 "common.w"
00541 
00542 int get_line()
00543 {
00544 restart:
00545 if(changing&&include_depth==change_depth)
00546 /*25:*/
00547 #line 537 "common.w"
00548 {
00549 change_line++;
00550 if(!input_ln(change_file)){
00551 err_print("! Change file ended without @z");
00552 
00553 buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
00554 }
00555 if(limit> buffer){
00556 if(change_pending){
00557 if_section_start_make_pending(0);
00558 if(change_pending){
00559 changed_section[section_count]= 1;change_pending= 0;
00560 }
00561 }
00562 *limit= ' ';
00563 if(buffer[0]=='@'){
00564 if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
00565 if(buffer[1]=='x'||buffer[1]=='y'){
00566 loc= buffer+2;
00567 err_print("! Where is the matching @z?");
00568 
00569 }
00570 else if(buffer[1]=='z'){
00571 prime_the_change_buffer();changing= !changing;print_where= 1;
00572 }
00573 }
00574 }
00575 }
00576 
00577 /*:25*/
00578 #line 431 "common.w"
00579 ;
00580 if(!changing||include_depth> change_depth){
00581 /*24:*/
00582 #line 520 "common.w"
00583 {
00584 cur_line++;
00585 while(!input_ln(cur_file)){
00586 print_where= 1;
00587 if(include_depth==0){input_has_ended= 1;break;}
00588 else{
00589 fclose(cur_file);include_depth--;
00590 if(changing&&include_depth==change_depth)break;
00591 cur_line++;
00592 }
00593 }
00594 if(!changing&&!input_has_ended)
00595 if(limit-buffer==change_limit-change_buffer)
00596 if(buffer[0]==change_buffer[0])
00597 if(change_limit> change_buffer)check_change();
00598 }
00599 
00600 /*:24*/
00601 #line 433 "common.w"
00602 ;
00603 if(changing&&include_depth==change_depth)goto restart;
00604 }
00605 if(input_has_ended)return 0;
00606 loc= buffer;*limit= ' ';
00607 if(buffer[0]=='@'&&(buffer[1]=='i'||buffer[1]=='I')){
00608 loc= buffer+2;*limit= '"';
00609 while(*loc==' '||*loc=='\t')loc++;
00610 if(loc>=limit){
00611 err_print("! Include file name not given");
00612 
00613 goto restart;
00614 }
00615 if(include_depth>=max_include_depth-1){
00616 err_print("! Too many nested includes");
00617 
00618 goto restart;
00619 }
00620 include_depth++;
00621 /*23:*/
00622 #line 474 "common.w"
00623 {
00624 char temp_file_name[max_file_name_length];
00625 char*cur_file_name_end= cur_file_name+max_file_name_length-1;
00626 char*k= cur_file_name,*kk;
00627 int l;
00628 
00629 if(*loc=='"'){
00630 loc++;
00631 while(*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
00632 if(loc==limit)k= cur_file_name_end+1;
00633 }else
00634 while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
00635 if(k> cur_file_name_end)too_long();
00636 
00637 *k= '\0';
00638 if((cur_file= fopen(cur_file_name,"r"))!=NULL){
00639 cur_line= 0;print_where= 1;
00640 goto restart;
00641 }
00642 kk= getenv("CWEBINPUTS");
00643 if(kk!=NULL){
00644 if((l= strlen(kk))> max_file_name_length-2)too_long();
00645 strcpy(temp_file_name,kk);
00646 }
00647 else{
00648 #ifdef CWEBINPUTS
00649 if((l= strlen(CWEBINPUTS))> max_file_name_length-2)too_long();
00650 strcpy(temp_file_name,CWEBINPUTS);
00651 #else
00652 l= 0;
00653 #endif 
00654 }
00655 if(l> 0){
00656 if(k+l+2>=cur_file_name_end)too_long();
00657 
00658 for(;k>=cur_file_name;k--)*(k+l+1)= *k;
00659 strcpy(cur_file_name,temp_file_name);
00660 cur_file_name[l]= '/';
00661 if((cur_file= fopen(cur_file_name,"r"))!=NULL){
00662 cur_line= 0;print_where= 1;
00663 goto restart;
00664 }
00665 }
00666 include_depth--;err_print("! Cannot open include file");goto restart;
00667 }
00668 
00669 /*:23*/
00670 #line 452 "common.w"
00671 ;
00672 }
00673 return 1;
00674 }
00675 
00676 /*:21*//*26:*/
00677 #line 569 "common.w"
00678 
00679 void
00680 check_complete(){
00681 if(change_limit!=change_buffer){
00682 strncpy(buffer,change_buffer,change_limit-change_buffer+1);
00683 limit= buffer+(int)(change_limit-change_buffer);
00684 changing= 1;change_depth= include_depth;loc= buffer;
00685 err_print("! Change file entry did not match");
00686 
00687 }
00688 }
00689 
00690 /*:26*//*35:*/
00691 #line 660 "common.w"
00692 
00693 name_pointer
00694 id_lookup(first,last,t)
00695 char*first;
00696 char*last;
00697 char t;
00698 {
00699 char*i= first;
00700 int h;
00701 int l;
00702 name_pointer p;
00703 if(last==NULL)for(last= first;*last!='\0';last++);
00704 l= last-first;
00705 /*36:*/
00706 #line 683 "common.w"
00707 
00708 h= (unsigned char)*i;
00709 while(++i<last)h= (h+h+(int)((unsigned char)*i))%hash_size;
00710 
00711 
00712 /*:36*/
00713 #line 673 "common.w"
00714 ;
00715 /*37:*/
00716 #line 691 "common.w"
00717 
00718 p= hash[h];
00719 while(p&&!names_match(p,first,l,t))p= p->link;
00720 if(p==NULL){
00721 p= name_ptr;
00722 p->link= hash[h];hash[h]= p;
00723 }
00724 
00725 /*:37*/
00726 #line 674 "common.w"
00727 ;
00728 if(p==name_ptr)/*39:*/
00729 #line 706 "common.w"
00730 {
00731 if(byte_ptr+l> byte_mem_end)overflow("byte memory");
00732 if(name_ptr>=name_dir_end)overflow("name");
00733 strncpy(byte_ptr,first,l);
00734 (++name_ptr)->byte_start= byte_ptr+= l;
00735 if(program==cweave)init_p(p,t);
00736 }
00737 
00738 /*:39*/
00739 #line 675 "common.w"
00740 ;
00741 return(p);
00742 }
00743 
00744 /*:35*//*42:*/
00745 #line 764 "common.w"
00746 
00747 void
00748 print_section_name(p)
00749 name_pointer p;
00750 {
00751 char*ss,*s= first_chunk(p);
00752 name_pointer q= p+1;
00753 while(p!=name_dir){
00754 ss= (p+1)->byte_start-1;
00755 if(*ss==' '&&ss>=s){
00756 term_write(s,ss-s);p= q->link;q= p;
00757 }else{
00758 term_write(s,ss+1-s);p= name_dir;q= NULL;
00759 }
00760 s= p->byte_start;
00761 }
00762 if(q)term_write("...",3);
00763 }
00764 
00765 /*:42*//*43:*/
00766 #line 783 "common.w"
00767 
00768 void
00769 sprint_section_name(dest,p)
00770 char*dest;
00771 name_pointer p;
00772 {
00773 char*ss,*s= first_chunk(p);
00774 name_pointer q= p+1;
00775 while(p!=name_dir){
00776 ss= (p+1)->byte_start-1;
00777 if(*ss==' '&&ss>=s){
00778 p= q->link;q= p;
00779 }else{
00780 ss++;p= name_dir;
00781 }
00782 strncpy(dest,s,ss-s),dest+= ss-s;
00783 s= p->byte_start;
00784 }
00785 *dest= '\0';
00786 }
00787 
00788 /*:43*//*44:*/
00789 #line 804 "common.w"
00790 
00791 void
00792 print_prefix_name(p)
00793 name_pointer p;
00794 {
00795 char*s= first_chunk(p);
00796 int l= prefix_length(p);
00797 term_write(s,l);
00798 if(s+l<(p+1)->byte_start)term_write("...",3);
00799 }
00800 
00801 /*:44*//*45:*/
00802 #line 825 "common.w"
00803 
00804 int web_strcmp(j,j_len,k,k_len)
00805 char*j,*k;
00806 int j_len,k_len;
00807 {
00808 char*j1= j+j_len,*k1= k+k_len;
00809 while(k<k1&&j<j1&&*j==*k)k++,j++;
00810 if(k==k1)if(j==j1)return equal;
00811 else return extension;
00812 else if(j==j1)return prefix;
00813 else if(*j<*k)return less;
00814 else return greater;
00815 }
00816 
00817 /*:45*//*47:*/
00818 #line 855 "common.w"
00819 
00820 name_pointer
00821 add_section_name(par,c,first,last,ispref)
00822 name_pointer par;
00823 int c;
00824 char*first;
00825 char*last;
00826 int ispref;
00827 {
00828 name_pointer p= name_ptr;
00829 char*s= first_chunk(p);
00830 int name_len= last-first+ispref;
00831 if(s+name_len> byte_mem_end)overflow("byte memory");
00832 if(name_ptr+1>=name_dir_end)overflow("name");
00833 (++name_ptr)->byte_start= byte_ptr= s+name_len;
00834 if(ispref){
00835 *(byte_ptr-1)= ' ';
00836 name_len--;
00837 name_ptr->link= name_dir;
00838 (++name_ptr)->byte_start= byte_ptr;
00839 }
00840 set_prefix_length(p,name_len);
00841 strncpy(s,first,name_len);
00842 p->llink= NULL;
00843 p->rlink= NULL;
00844 init_node(p);
00845 return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
00846 }
00847 
00848 /*:47*//*48:*/
00849 #line 884 "common.w"
00850 
00851 void
00852 extend_section_name(p,first,last,ispref)
00853 name_pointer p;
00854 char*first;
00855 char*last;
00856 int ispref;
00857 {
00858 char*s;
00859 name_pointer q= p+1;
00860 int name_len= last-first+ispref;
00861 if(name_ptr>=name_dir_end)overflow("name");
00862 while(q->link!=name_dir)q= q->link;
00863 q->link= name_ptr;
00864 s= name_ptr->byte_start;
00865 name_ptr->link= name_dir;
00866 if(s+name_len> byte_mem_end)overflow("byte memory");
00867 (++name_ptr)->byte_start= byte_ptr= s+name_len;
00868 strncpy(s,first,name_len);
00869 if(ispref)*(byte_ptr-1)= ' ';
00870 }
00871 
00872 /*:48*//*49:*/
00873 #line 912 "common.w"
00874 
00875 name_pointer
00876 section_lookup(first,last,ispref)
00877 char*first,*last;
00878 int ispref;
00879 {
00880 int c= 0;
00881 name_pointer p= root;
00882 name_pointer q= NULL;
00883 name_pointer r= NULL;
00884 name_pointer par= NULL;
00885 
00886 int name_len= last-first+1;
00887 /*50:*/
00888 #line 936 "common.w"
00889 
00890 while(p){
00891 c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
00892 if(c==less||c==greater){
00893 if(r==NULL)
00894 par= p;
00895 p= (c==less?p->llink:p->rlink);
00896 }else{
00897 if(r!=NULL){
00898 printf("\n! Ambiguous prefix: matches <");
00899 
00900 print_prefix_name(p);
00901 printf(">\n and <");
00902 print_prefix_name(r);
00903 err_print(">");
00904 return name_dir;
00905 }
00906 r= p;
00907 p= p->llink;
00908 q= r->rlink;
00909 }
00910 if(p==NULL)
00911 p= q,q= NULL;
00912 }
00913 
00914 /*:50*/
00915 #line 926 "common.w"
00916 ;
00917 /*51:*/
00918 #line 961 "common.w"
00919 
00920 if(r==NULL)
00921 return add_section_name(par,c,first,last+1,ispref);
00922 
00923 /*:51*/
00924 #line 927 "common.w"
00925 ;
00926 /*52:*/
00927 #line 969 "common.w"
00928 
00929 switch(section_name_cmp(&first,name_len,r)){
00930 
00931 case prefix:
00932 if(!ispref){
00933 printf("\n! New name is a prefix of <");
00934 
00935 print_section_name(r);
00936 err_print(">");
00937 }
00938 else if(name_len<prefix_length(r))set_prefix_length(r,name_len);
00939 
00940 case equal:return r;
00941 case extension:if(!ispref||first<=last)
00942 extend_section_name(r,first,last+1,ispref);
00943 return r;
00944 case bad_extension:
00945 printf("\n! New name extends <");
00946 
00947 print_section_name(r);
00948 err_print(">");
00949 return r;
00950 default:
00951 printf("\n! Section name incompatible with <");
00952 
00953 print_prefix_name(r);
00954 printf(">,\n which abbreviates <");
00955 print_section_name(r);
00956 err_print(">");
00957 return r;
00958 }
00959 
00960 /*:52*/
00961 #line 928 "common.w"
00962 ;
00963 }
00964 
00965 /*:49*//*54:*/
00966 #line 1020 "common.w"
00967 
00968 int section_name_cmp(pfirst,len,r)
00969 char**pfirst;
00970 int len;
00971 name_pointer r;
00972 {
00973 char*first= *pfirst;
00974 name_pointer q= r+1;
00975 char*ss,*s= first_chunk(r);
00976 int c;
00977 int ispref;
00978 while(1){
00979 ss= (r+1)->byte_start-1;
00980 if(*ss==' '&&ss>=r->byte_start)ispref= 1,q= q->link;
00981 else ispref= 0,ss++,q= name_dir;
00982 switch(c= web_strcmp(first,len,s,ss-s)){
00983 case equal:if(q==name_dir)
00984 if(ispref){
00985 *pfirst= first+(ss-s);
00986 return extension;
00987 }else return equal;
00988 else return(q->byte_start==(q+1)->byte_start)?equal:prefix;
00989 case extension:
00990 if(!ispref)return bad_extension;
00991 first+= ss-s;
00992 if(q!=name_dir){len-= ss-s;s= q->byte_start;r= q;continue;}
00993 *pfirst= first;return extension;
00994 default:return c;
00995 }
00996 }
00997 }
00998 
00999 /*:54*//*58:*/
01000 #line 1095 "common.w"
01001 
01002 void
01003 err_print(s)
01004 char*s;
01005 {
01006 char*k,*l;
01007 printf(*s=='!'?"\n%s":"%s",s);
01008 if(web_file_open)/*59:*/
01009 #line 1115 "common.w"
01010 
01011 {if(changing&&include_depth==change_depth)
01012 printf(". (l. %d of change file)\n",change_line);
01013 else if(include_depth==0)printf(". (l. %d)\n",cur_line);
01014 else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
01015 l= (loc>=limit?limit:loc);
01016 if(l> buffer){
01017 for(k= buffer;k<l;k++)
01018 if(*k=='\t')putchar(' ');
01019 else putchar(*k);
01020 putchar('\n');
01021 for(k= buffer;k<l;k++)putchar(' ');
01022 }
01023 for(k= l;k<limit;k++)putchar(*k);
01024 if(*limit=='|')putchar('|');
01025 putchar(' ');
01026 }
01027 
01028 /*:59*/
01029 #line 1102 "common.w"
01030 ;
01031 update_terminal;mark_error;
01032 }
01033 
01034 /*:58*//*61:*/
01035 #line 1150 "common.w"
01036 
01037 int wrap_up(){
01038 putchar('\n');
01039 if(show_stats)
01040 print_stats();
01041 /*62:*/
01042 #line 1160 "common.w"
01043 
01044 switch(history){
01045 case spotless:if(show_happiness)printf("(No errors were found.)\n");break;
01046 case harmless_message:
01047 printf("(Did you see the warning message above?)\n");break;
01048 case error_message:
01049 printf("(Pardon me, but I think I spotted something wrong.)\n");break;
01050 case fatal_message:printf("(That was a fatal error, my friend.)\n");
01051 }
01052 
01053 /*:62*/
01054 #line 1155 "common.w"
01055 ;
01056 if(history> harmless_message)return(1);
01057 else return(0);
01058 }
01059 
01060 /*:61*//*64:*/
01061 #line 1179 "common.w"
01062 void
01063 fatal(s,t)
01064 char*s,*t;
01065 {
01066 if(*s)printf(s);
01067 err_print(t);
01068 history= fatal_message;exit(wrap_up());
01069 }
01070 
01071 /*:64*//*65:*/
01072 #line 1190 "common.w"
01073 void
01074 overflow(t)
01075 char*t;
01076 {
01077 printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
01078 }
01079 
01080 
01081 /*:65*//*70:*/
01082 #line 1254 "common.w"
01083 
01084 void
01085 scan_args()
01086 {
01087 char*dot_pos;
01088 char*name_pos;
01089 register char*s;
01090 boolean found_web= 0,found_change= 0,found_out= 0;
01091 
01092 boolean flag_change;
01093 
01094 while(--argc> 0){
01095 if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*74:*/
01096 #line 1344 "common.w"
01097 
01098 {
01099 if(**argv=='-')flag_change= 0;
01100 else flag_change= 1;
01101 for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++)
01102 flags[*dot_pos]= flag_change;
01103 }
01104 
01105 /*:74*/
01106 #line 1266 "common.w"
01107 
01108 else{
01109 s= name_pos= *argv;dot_pos= NULL;
01110 while(*s){
01111 if(*s=='.')dot_pos= s++;
01112 else if(*s=='/')dot_pos= NULL,name_pos= ++s;
01113 else s++;
01114 }
01115 if(!found_web)/*71:*/
01116 #line 1292 "common.w"
01117 
01118 {
01119 if(s-*argv> max_file_name_length-5)
01120 /*76:*/
01121 #line 1364 "common.w"
01122 fatal("! Filename too long\n",*argv);
01123 
01124 
01125 /*:76*/
01126 #line 1295 "common.w"
01127 ;
01128 if(dot_pos==NULL)
01129 sprintf(web_file_name,"%s.w",*argv);
01130 else{
01131 strcpy(web_file_name,*argv);
01132 *dot_pos= 0;
01133 }
01134 sprintf(alt_web_file_name,"%s.web",*argv);
01135 sprintf(tex_file_name,"%s.tex",name_pos);
01136 sprintf(idx_file_name,"%s.idx",name_pos);
01137 sprintf(scn_file_name,"%s.scn",name_pos);
01138 sprintf(C_file_name,"%s.c",name_pos);
01139 found_web= 1;
01140 }
01141 
01142 /*:71*/
01143 #line 1275 "common.w"
01144 
01145 else if(!found_change)/*72:*/
01146 #line 1310 "common.w"
01147 
01148 {
01149 if(strcmp(*argv,"-")==0)found_change= -1;
01150 else{
01151 if(s-*argv> max_file_name_length-4)
01152 /*76:*/
01153 #line 1364 "common.w"
01154 fatal("! Filename too long\n",*argv);
01155 
01156 
01157 /*:76*/
01158 #line 1315 "common.w"
01159 ;
01160 if(dot_pos==NULL)
01161 sprintf(change_file_name,"%s.ch",*argv);
01162 else strcpy(change_file_name,*argv);
01163 found_change= 1;
01164 }
01165 }
01166 
01167 /*:72*/
01168 #line 1276 "common.w"
01169 
01170 else if(!found_out)/*73:*/
01171 #line 1323 "common.w"
01172 
01173 {
01174 if(s-*argv> max_file_name_length-5)
01175 /*76:*/
01176 #line 1364 "common.w"
01177 fatal("! Filename too long\n",*argv);
01178 
01179 
01180 /*:76*/
01181 #line 1326 "common.w"
01182 ;
01183 if(dot_pos==NULL){
01184 sprintf(tex_file_name,"%s.tex",*argv);
01185 sprintf(idx_file_name,"%s.idx",*argv);
01186 sprintf(scn_file_name,"%s.scn",*argv);
01187 sprintf(C_file_name,"%s.c",*argv);
01188 }else{
01189 strcpy(tex_file_name,*argv);
01190 strcpy(C_file_name,*argv);
01191 if(flags['x']){
01192 *dot_pos= 0;
01193 sprintf(idx_file_name,"%s.idx",*argv);
01194 sprintf(scn_file_name,"%s.scn",*argv);
01195 }
01196 }
01197 found_out= 1;
01198 }
01199 
01200 /*:73*/
01201 #line 1277 "common.w"
01202 
01203 else/*75:*/
01204 #line 1352 "common.w"
01205 
01206 {
01207 if(program==ctangle)
01208 fatal(
01209 "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
01210 ,"");
01211 
01212 else fatal(
01213 "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
01214 ,"");
01215 }
01216 
01217 /*:75*/
01218 #line 1278 "common.w"
01219 ;
01220 }
01221 }
01222 if(!found_web)/*75:*/
01223 #line 1352 "common.w"
01224 
01225 {
01226 if(program==ctangle)
01227 fatal(
01228 "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
01229 ,"");
01230 
01231 else fatal(
01232 "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
01233 ,"");
01234 }
01235 
01236 /*:75*/
01237 #line 1281 "common.w"
01238 ;
01239 if(found_change<=0)strcpy(change_file_name,"/dev/null");
01240 }
01241 
01242 /*:70*/