1 #define version_number "1.1"
2 #define banner "This is CTIE, Version 1.1"
4 "Copyright 2002,2003 Julian Gilbey. All rights reserved. There is no warranty.\n\
5 Run with the --version option for other important information." \
12 #define max_file_index 32 \
14 #define xisupper(c) (isupper(c) &&((unsigned char) c<0200) ) \
21 #define max_include_files 20 \
23 #define max_file_name_length 60 \
25 #define too_long() {total_include_files--;free(new_inc) ; \
26 err_print(i,"! Include file name too long") ;goto restart;} \
28 #define fatal_error(i,s,t) { \
29 fprintf(stderr,"\n%s",s) ; \
80 typedef int in_file_modes;
84 typedef int file_types;
93 typedef int out_md_type;
99 typedef int file_index;
105 typedef struct _indsc{
106 char file_name[max_file_name_length];
109 struct _indsc*parent;
110 }include_description;
116 typedef struct _idsc{
118 char buffer[buf_size];
121 file_types type_of_file;
122 include_description*current_include;
138 extern char*strcpy();
139 extern int strncmp();
140 extern char*strncpy();
141 extern char*strerror();
160 #line 1232 "./ctie.w"
163 void print_version_and_exit();
172 int history= spotless;
178 int total_include_files= 0;
183 file_index actual_input,test_input,no_ch;
184 file_types prod_chf= unknown;
185 out_md_type out_mode;
190 input_description*input_organisation[max_file_index+1];
196 boolean input_has_ended= false;
207 #line 1217 "./ctie.w"
210 "Usage: ctie -[mc] outfile master changefile(s)",
211 " Create a new master file or change file from the given",
212 " master (C)WEB file and changefiles.",
213 " All filenames are taken literally; no suffixes are added.",
215 "-m create a new master file from original (C)WEB and change file(s)",
216 "-c create a master change file for original (C)WEB file from changefile(s)",
217 "--help display this help and exit",
218 "--version display version information and exit",
233 fprintf(stderr,*s=='!'?"\n%s":"%s",s);
238 register input_description*inp_desc= input_organisation[i];
239 register include_description*inc_desc= inp_desc->current_include;
242 fprintf(stderr,". (l. %ld of include file %s",inc_desc->line,
243 inc_desc->file_name);
244 fprintf(stderr," included from l. %ld of %s file %s)\n",
246 inp_desc->type_of_file==master?"master":"change",
247 inp_desc->file_name);
250 fprintf(stderr,". (l. %ld of %s file %s)\n",inp_desc->line,
251 inp_desc->type_of_file==master?"master":"change",
252 inp_desc->file_name);
253 l= (inp_desc->loc>=inp_desc->limit?inp_desc->limit:inp_desc->loc);
254 if(l> inp_desc->buffer){
255 for(k= inp_desc->buffer;k<l;k++)
256 if(*k=='\t')putc(' ',stderr);
257 else putc(*k,stderr);
259 for(k= inp_desc->buffer;k<l;k++)
262 for(k= l;k<inp_desc->limit;k++)
271 else putc('\n',stderr);
273 history= troublesome;
279 void pfatal_error(s,t)
282 char*strerr= strerror(errno);
284 fprintf(stderr,"\n%s%s",s,t);
285 if(strerr)fprintf(stderr," (%s)\n",strerr);
286 else fprintf(stderr,"\n");
298 boolean get_line(i,do_includes)
299 file_index i;boolean do_includes;
301 register input_description*inp_desc= input_organisation[i];
304 if(inp_desc->mode==ignore)return false;
307 if(inp_desc->current_include!=NULL){
308 register include_description*inc_desc= inp_desc->current_include;
310 fp= inc_desc->the_file;
323 include_description*temp= inc_desc->parent;
327 total_include_files--;
328 inp_desc->current_include= temp;
337 inp_desc->limit= k= inp_desc->buffer;
338 while(k<=inp_desc->buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
339 if((*(k++)= c)!=' ')inp_desc->limit= k;
340 if(k> inp_desc->buffer_end)
341 if((c= getc(fp))!=EOF&&c!='\n'){
342 ungetc(c,fp);inp_desc->loc= inp_desc->buffer;
343 err_print(i,"! Input line too long");
346 if(c==EOF&&inp_desc->limit==inp_desc->buffer)
351 include_description*temp= inc_desc->parent;
355 total_include_files--;
356 inp_desc->current_include= temp;
373 fp= inp_desc->the_file;
386 inp_desc->mode= ignore;
387 inp_desc->limit= NULL;
388 if(inp_desc->type_of_file==master)input_has_ended= true;
398 inp_desc->limit= k= inp_desc->buffer;
399 while(k<=inp_desc->buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
400 if((*(k++)= c)!=' ')inp_desc->limit= k;
401 if(k> inp_desc->buffer_end)
402 if((c= getc(fp))!=EOF&&c!='\n'){
403 ungetc(c,fp);inp_desc->loc= inp_desc->buffer;
404 err_print(i,"! Input line too long");
407 if(c==EOF&&inp_desc->limit==inp_desc->buffer)
412 inp_desc->mode= ignore;
413 inp_desc->limit= NULL;
414 if(inp_desc->type_of_file==master)input_has_ended= true;
428 if(inp_desc->type_of_file==master&&inp_desc->line%100==0){
429 if(inp_desc->line%500==0)printf("%ld",inp_desc->line);
451 inp_desc->loc= inp_desc->buffer;
452 *inp_desc->limit= ' ';
453 if(*inp_desc->buffer=='@'&&
454 (inp_desc->buffer[1]=='i'||inp_desc->buffer[1]=='I')){
455 inp_desc->loc= inp_desc->buffer+2;
456 *inp_desc->limit= '"';
457 while(*inp_desc->loc==' '||*inp_desc->loc=='\t')
459 if(inp_desc->loc>=inp_desc->limit){
460 err_print(i,"! Include file name not given");
464 if(total_include_files>=max_include_files){
465 err_print(i,"! Too many nested includes");
469 total_include_files++;
474 include_description*new_inc;
475 char temp_file_name[max_file_name_length];
480 new_inc= (include_description*)malloc(sizeof(include_description));
482 fatal_error(i,"! No memory for new include descriptor","");
484 k= new_inc->file_name;
485 file_name_end= k+max_file_name_length-1;
487 if(*inp_desc->loc=='"'){
489 while(*inp_desc->loc!='"'&&k<=file_name_end)
490 *k++= *inp_desc->loc++;
491 if(inp_desc->loc==inp_desc->limit)
494 while(*inp_desc->loc!=' '&&*inp_desc->loc!='\t'&&
495 *inp_desc->loc!='"'&&k<=file_name_end)*k++= *inp_desc->loc++;
496 if(k> file_name_end)too_long();
499 if((new_inc->the_file= fopen(new_inc->file_name,"r"))!=NULL){
500 new_inc->parent= inp_desc->current_include;
501 inp_desc->current_include= new_inc;
504 kk= getenv("CWEBINPUTS");
506 if((l= strlen(kk))> max_file_name_length-2)too_long();
507 strcpy(temp_file_name,kk);
511 if((l= strlen(CWEBINPUTS))> max_file_name_length-2)too_long();
512 strcpy(temp_file_name,CWEBINPUTS);
518 if(k+l+2>=file_name_end)too_long();
519 for(;k>=new_inc->file_name;k--)*(k+l+1)= *k;
520 strcpy(new_inc->file_name,temp_file_name);
521 new_inc->file_name[l]= '/';
522 if((new_inc->the_file= fopen(new_inc->file_name,"r"))!=NULL){
523 new_inc->parent= inp_desc->current_include;
524 inp_desc->current_include= new_inc;
528 total_include_files--;
530 err_print(i,"! Cannot open include file");
561 printf("\n(No errors were found.)\n");break;
563 printf("\n(Pardon me, but I think I spotted something wrong.)\n");break;
564 case fatal:printf("(That was a fatal error, my friend.)\n");
571 if(history> spotless)return 1;
578 boolean lines_dont_match(i,j)
581 register input_description*iptr= input_organisation[i],
582 *jptr= input_organisation[j];
584 if(iptr->limit-iptr->buffer!=jptr->limit-jptr->buffer)
586 return strncmp(iptr->buffer,jptr->buffer,iptr->limit-iptr->buffer);
593 void init_change_file(i)
596 register input_description*inp_desc= input_organisation[i];
599 inp_desc->limit= inp_desc->buffer;
604 if(!get_line(i,false))return;
605 if(inp_desc->limit<inp_desc->buffer+2)continue;
606 if(inp_desc->buffer[0]!='@')continue;
607 ccode= inp_desc->buffer[1];
608 if(xisupper(ccode))ccode= tolower(ccode);
610 if(ccode=='y'||ccode=='z'||ccode=='i'){
611 inp_desc->loc= inp_desc->buffer+2;
612 err_print(i,"! Missing @x in change file");
624 if(!get_line(i,true)){
625 err_print(i,"! Change file ended after @x");
629 }while(inp_desc->limit==inp_desc->buffer);
635 inp_desc->dont_match= 0;
645 char*ptr= input_organisation[j]->buffer;
646 char*lmt= input_organisation[j]->limit;
648 while(ptr<lmt)putc(*ptr++,out_file);
656 boolean e_of_ch_module(i)
659 register input_description*inp_desc= input_organisation[i];
661 if(inp_desc->limit==NULL){
662 err_print(i,"! Change file ended without @z");
665 }else if(inp_desc->limit>=inp_desc->buffer+2)
666 if(inp_desc->buffer[0]=='@'&&
667 (inp_desc->buffer[1]=='Z'||inp_desc->buffer[1]=='z'))
676 boolean e_of_ch_preamble(i)
679 register input_description*inp_desc= input_organisation[i];
681 if(inp_desc->limit>=inp_desc->buffer+2&&inp_desc->buffer[0]=='@')
682 if(inp_desc->buffer[1]=='Y'||inp_desc->buffer[1]=='y'){
683 if(inp_desc->dont_match> 0){
684 inp_desc->loc= inp_desc->buffer+2;
685 fprintf(stderr,"\n! Hmm... %d ",inp_desc->dont_match);
686 err_print(i,"of the preceding lines failed to match");
696 #line 1105 "./ctie.w"
701 #line 1118 "./ctie.w"
703 printf("%s\n",banner);
704 printf("%s\n",copyright);
708 #line 1108 "./ctie.w"
710 fprintf(stderr,"Usage: ctie -[mc] outfile master changefile(s)\n");
711 fprintf(stderr,"Type ctie --help for more information\n");
723 int argc;string*argv;
735 #line 1135 "./ctie.w"
738 if(argc> max_file_index+5-1)usage_error();
742 if(strcmp("-help",*argv)==0||strcmp("--help",*argv)==0)
744 #line 1202 "./ctie.w"
751 #line 1142 "./ctie.w"
753 if(strcmp("-version",*argv)==0||strcmp("--version",*argv)==0)
755 #line 1208 "./ctie.w"
758 print_version_and_exit("CTIE",version_number);
764 #line 1144 "./ctie.w"
766 if(**argv=='-')/*62:*/
767 #line 1158 "./ctie.w"
769 if(prod_chf!=unknown)usage_error();
772 case'c':case'C':prod_chf= chf;break;
773 case'm':case'M':prod_chf= master;break;
774 default:usage_error();
779 #line 1145 "./ctie.w"
782 #line 1172 "./ctie.w"
788 register input_description*inp_desc;
790 inp_desc= (input_description*)malloc(sizeof(input_description));
792 fatal_error(-1,"! No memory for input descriptor","");
794 inp_desc->mode= search;
796 inp_desc->type_of_file= chf;
797 inp_desc->limit= inp_desc->buffer;
798 inp_desc->buffer[0]= ' ';
799 inp_desc->loc= inp_desc->buffer+1;
800 inp_desc->buffer_end= inp_desc->buffer+buf_size-2;
801 inp_desc->file_name= *argv;
802 inp_desc->current_include= NULL;
803 input_organisation[no_ch]= inp_desc;
810 #line 1146 "./ctie.w"
813 if(no_ch<=0||prod_chf==unknown)usage_error();
821 #line 1118 "./ctie.w"
823 printf("%s\n",banner);
824 printf("%s\n",copyright);
834 input_organisation[0]->the_file=
835 fopen(input_organisation[0]->file_name,"r");
837 if(input_organisation[0]->the_file==NULL)
838 pfatal_error("! Cannot open master file ",
839 input_organisation[0]->file_name);
841 printf("(%s)\n",input_organisation[0]->file_name);
842 input_organisation[0]->type_of_file= master;
858 input_organisation[i]->the_file=
859 fopen(input_organisation[i]->file_name,"r");
860 if(input_organisation[i]->the_file==NULL)
861 pfatal_error("! Cannot open change file ",
862 input_organisation[i]->file_name);
864 printf("(%s)\n",input_organisation[i]->file_name);
878 out_file= fopen(out_name,"w");
880 pfatal_error("! Cannot open/create output file","");
890 #line 1074 "./ctie.w"
893 input_has_ended= false;
894 while(input_has_ended==false||actual_input!=0)
899 file_index test_file;
905 register input_description*inp_desc;
906 while(actual_input> 0&&e_of_ch_module(actual_input)){
907 inp_desc= input_organisation[actual_input];
908 if(inp_desc->type_of_file==master){
910 fatal_error(-1,"! This can't happen: change file is master file","");
913 inp_desc->mode= search;
914 init_change_file(actual_input);
915 while((input_organisation[actual_input]->mode!=reading
925 if(input_has_ended&&actual_input==0)break;
930 test_file= actual_input;
931 while(test_input==none&&test_file<no_ch-1){
933 switch(input_organisation[test_file]->mode){
935 if(lines_dont_match(actual_input,test_file)==false){
936 input_organisation[test_file]->mode= test;
937 test_input= test_file;
941 if(lines_dont_match(actual_input,test_file)){
943 input_organisation[test_file]->dont_match++;
945 test_input= test_file;
964 #line 1007 "./ctie.w"
966 if(out_mode==normal){
967 if(test_input!=none){
968 fprintf(out_file,"@x\n");
978 #line 1021 "./ctie.w"
981 if(test_input==none){
982 fprintf(out_file,"@y\n");
985 if(input_organisation[actual_input]->type_of_file==master)
986 put_line(actual_input);
996 #line 1040 "./ctie.w"
999 if(input_organisation[actual_input]->type_of_file==chf){
1000 if(test_input==none)put_line(actual_input);
1003 fprintf(out_file,"@z\n\n");
1010 #line 998 "./ctie.w"
1014 if(test_input==none)put_line(actual_input);
1018 #line 924 "./ctie.w"
1021 #line 1055 "./ctie.w"
1023 get_line(actual_input,true);
1024 if(test_input!=none){
1025 get_line(test_input,true);
1026 if(e_of_ch_preamble(test_input)==true){
1027 get_line(test_input,true);
1028 input_organisation[test_input]->mode= reading;
1029 actual_input= test_input;
1036 #line 925 "./ctie.w"
1042 #line 1078 "./ctie.w"
1045 fprintf(out_file,"@z\n");
1049 #line 111 "./ctie.w"
1052 #line 1087 "./ctie.w"
1057 for(i= 1;i<no_ch;i++){
1058 if(input_organisation[i]->mode!=ignore){
1059 input_organisation[i]->loc= input_organisation[i]->buffer;
1060 err_print(i,"! Change file entry did not match");
1068 #line 112 "./ctie.w"
1078 #line 1237 "./ctie.w"
1082 string*message= CTIEHELP;
1085 fputs(*message,stdout);
1095 #line 1252 "./ctie.w"
1097 void print_version_and_exit(name,version)
1098 string name,version;
1100 printf("%s %s\n",name,version);
1102 puts("Copyright (C) 2002,2003 Julian Gilbey.");
1104 puts("There is NO warranty. This is free software. See the source");
1105 puts("code of CTIE for redistribution conditions.");