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.");