beta-0.89.2
[luatex.git] / source / texk / web2c / cwebdir / comm-w2c.ch
blobbd6ac50e1e0a749138add1b01f72136f0297e843
1 % Kpathsea changes for CWEB by Wlodek Bzyl and Olaf Weber
2 % Copyright 2002 Wlodek Bzyl and Olaf Weber
3 % This file is in the Public Domain.
5 @x l.20
6 \def\title{Common code for CTANGLE and CWEAVE (Version 3.64)}
7 \def\topofcontents{\null\vfill
8   \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
9     {\ttitlefont CWEAVE}}
10   \vskip 15pt
11   \centerline{(Version 3.64)}
12   \vfill}
14 \def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}}
15 \def\title{Common code for CTANGLE and CWEAVE (Version 3.64k)}
16 \def\topofcontents{\null\vfill
17   \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
18     {\ttitlefont CWEAVE}}
19   \vskip 15pt
20   \centerline{(Version 3.64k)}
21   \vfill}
24 This change can not be applied when `tie' is  used
25 (TOC file can not be typeset).
27 %@x l.42
28 %\let\maybe=\iftrue
29 %@y
30 %\let\maybe=\iffalse % print only changed modules
31 %@z
33 Section 1.
35 @x l.63
36 @<Predeclaration of procedures@>@/
38 #include "cweb.h"
39 @<Predeclaration of procedures@>@/
42 Section 2. 
43 We use the definition from `kpathsea/types.h':
45   typedef enum { false = 0, true = 1 } boolean;
47 Note that this definition also occurs in common.h.
48 @x l.74
49 typedef short boolean;
54 Section 4.
56 @x l.91
57 common_init()
59 common_init (void)
62 @x l.93
63   @<Initialize pointers@>;
65   @<Initialize pointers@>;
66   @<Set up |PROGNAME| feature and initialize the search path mechanism@>;
69 Section 5.
71 @x l.103
72 #include <ctype.h>
74 #define CWEB
75 #include "cpascal.h"
76 #include <ctype.h>
79 Section 7.
81 @x l.153
82 @d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */
84 @d buf_size 1000 /* for \.{CWEAVE} and \.{CTANGLE} */
87 @x l.156
88 @d xisspace(c) (isspace(c)&&((unsigned char)c<0200))
89 @d xisupper(c) (isupper(c)&&((unsigned char)c<0200))
91 @d xisspace(c) (isspace((unsigned char)c)&&((unsigned char)c<0200))
92 @d xisupper(c) (isupper((unsigned char)c)&&((unsigned char)c<0200))
95 Section 9.
97 @x l.173
98 int input_ln(fp) /* copies a line into |buffer| or returns 0 */
99 FILE *fp; /* what file to read from */
101 int input_ln (FILE *fp) /* copies a line into |buffer| or returns 0 */
104 @x l.181
105     if ((*(k++) = c) != ' ') limit = k;
107     if ((*(k++) = c) != ' ' && c!='\r') limit = k;
110 Section 10.
112 @x l.207 - max_file_name_length is way too small.
113 @d max_file_name_length 60
115 @d max_file_name_length 1024
118 @x l.221 - no alt_web_file_name needed.
119 char alt_web_file_name[max_file_name_length]; /* alternate name to try */
123 Section 12.
125 @x l.252
126 void
127 prime_the_change_buffer()
129 static void
130 prime_the_change_buffer (void)
133 @x l.271
134   if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
136   if (xisupper(buffer[1])) buffer[1]=tolower((unsigned char)buffer[1]);
139 Section 16.
141 @x l.321
142 void
143 check_change() /* switches to |change_file| if the buffers match */
145 static void
146 check_change (void) /* switches to |change_file| if the buffers match */
149 @x l.340
150       char xyz_code=xisupper(buffer[1])? tolower(buffer[1]): buffer[1];
152       char xyz_code=xisupper(buffer[1])? tolower((unsigned char)buffer[1]): buffer[1];
155 Section 18.
157 @x l.380
158 reset_input()
160 reset_input (void)
163 Section 19.
165 @x l.394
166 if ((web_file=fopen(web_file_name,"r"))==NULL) {
167   strcpy(web_file_name,alt_web_file_name);
168   if ((web_file=fopen(web_file_name,"r"))==NULL)
169        fatal("! Cannot open input file ", web_file_name);
172 if ((found_filename=kpse_find_cweb(web_file_name))==NULL ||
173     (web_file=fopen(found_filename,"r"))==NULL) {
174   fatal("! Cannot open input file ", web_file_name);
175 } else if (strlen(found_filename) < max_file_name_length) {
176   strcpy(web_file_name, found_filename);
177   free(found_filename);
181 @x l.402
182 if ((change_file=fopen(change_file_name,"r"))==NULL)
183        fatal("! Cannot open change file ", change_file_name);
185 if ((found_filename=kpse_find_cweb(change_file_name))==NULL ||
186     (change_file=fopen(found_filename,"r"))==NULL) {
187   fatal("! Cannot open change file ", change_file_name);
188 } else if (strlen(found_filename) < max_file_name_length) {
189   strcpy(change_file_name, found_filename);
190   free(found_filename);
194 @x l.415
195 @d max_sections 2000 /* number of identifiers, strings, section names;
197 @d max_sections 10239 /* number of identifiers, strings, section names;
200 Section 21.
202 @x l.427
203 int get_line() /* inputs the next line */
205 int get_line (void) /* inputs the next line */
208 Section 22.
210 @x l.472
211 #include <stdlib.h> /* declaration of |getenv| and |exit| */
213 #include <kpathsea/kpathsea.h> /* include every \Kpathsea/ header */
214 #include <stdlib.h> /* declaration of |getenv| and |exit| */
215 #include "help.h"
217 @ The \.{ctangle} and \.{cweave} programs from the original \.{CWEB}
218 package use the compile-time default directory or the value of the
219 environment variable \.{CWEBINPUTS} as an alternative place to be
220 searched for files, if they could not be found in the current
221 directory.
223 This version uses the \Kpathsea/ mechanism for searching files. 
224 The directories to be searched for come from three sources:
226  (a)~a user-set environment variable \.{CWEBINPUTS}
227     (overriden by \.{CWEBINPUTS\_cweb});\par
228  (b)~a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
229     e.g. \.{CWEBINPUTS=.:$TEXMF/texmf/cweb//}
230     or \.{CWEBINPUTS.cweb=.:$TEXMF/texmf/cweb//};\hangindent=2\parindent\par
231  (c)~compile-time default directories \.{.:$TEXMF/texmf/cweb//}
232     (specified in \.{texmf.in}).
235 @d kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)
237 @ The simple file searching is replaced by `path searching' mechanism
238 that \Kpathsea/ library provides.
240 We set |kpse_program_name| to a |"cweb"|.  This means if the
241 variable |CWEBINPUTS.cweb| is present in \.{texmf.cnf} (or |CWEBINPUTS_cweb|
242 in the environment) its value will be used as the search path for
243 filenames.  This allows different flavors of \.{CWEB} to have
244 different search paths.
246 FIXME: Not sure this is the best way to go about this.
248 @<Set up |PROGNAME| feature and initialize the search path mechanism@>=
249 kpse_set_program_name(argv[0], "cweb"); 
253 Section 23.
255 @x l.475
256   char temp_file_name[max_file_name_length];
257   char *cur_file_name_end=cur_file_name+max_file_name_length-1;
258   char *k=cur_file_name, *kk;
259   int l; /* length of file name */
261   char *cur_file_name_end=cur_file_name+max_file_name_length-1;
262   char *k=cur_file_name;
265 @x l.489
266   if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
268   if ((found_filename=kpse_find_cweb(cur_file_name))!=NULL &&
269       (cur_file=fopen(found_filename,"r"))!=NULL) {
270     /* Copy name for #line directives. */
271     if (strlen(found_filename) < max_file_name_length) {
272       strcpy(cur_file_name, found_filename);
273       free(found_filename);
274     }
277 Replaced by Kpathsea `kpse_find_file'
279 @x l.493
280   kk=getenv("CWEBINPUTS");
281   if (kk!=NULL) {
282     if ((l=strlen(kk))>max_file_name_length-2) too_long();
283     strcpy(temp_file_name,kk);
284   }
285   else {
286 #ifdef CWEBINPUTS
287     if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
288     strcpy(temp_file_name,CWEBINPUTS);
289 #else
290     l=0;
291 #endif /* |CWEBINPUTS| */
292   }
293   if (l>0) {
294     if (k+l+2>=cur_file_name_end)  too_long();
295 @.Include file name ...@>
296     for (; k>= cur_file_name; k--) *(k+l+1)=*k;
297     strcpy(cur_file_name,temp_file_name);
298     cur_file_name[l]='/'; /* \UNIX/ pathname separator */
299     if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
300       cur_line=0; print_where=1;
301       goto restart; /* success */
302     }
303   }
307 Section 26.
309 @x l.553
310       if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
312       if (xisupper(buffer[1])) buffer[1]=tolower((unsigned char)buffer[1]);
315 @x l.571
316 check_complete(){
318 check_complete (void) {
321 @x l.589
322 @d max_bytes 90000 /* the number of bytes in identifiers,
324 @d max_bytes 1000000 /* the number of bytes in identifiers,
327 @x l.591
328 @d max_names 4000 /* number of identifiers, strings, section names;
330 @d max_names 10239 /* number of identifiers, strings, section names;
333 @x l.642
334 @d hash_size 353 /* should be prime */
336 @d hash_size 8501 /* should be prime */
339 Section 33.
341 @x l.650
342 @ @<Predec...@>=
343 extern int names_match();
345 @ @<External functions@>=
346 extern int names_match (name_pointer, const char*, int, char);
349 Section 35.
351 @x l.661
352 id_lookup(first,last,t) /* looks up a string in the identifier table */
353 char *first; /* first character of string */
354 char *last; /* last character of string plus one */
355 char t; /* the |ilk|; used by \.{CWEAVE} only */
357 /* looks up a string in the identifier table */
358 id_lookup (const char *first, const char *last, char t)
361 @x l.667
362   char *i=first; /* position in |buffer| */
364   const char *i=first; /* position in |buffer| */
367 @x l.668 - rename local var, not to shadow global
368   int h; /* hash code */
370   int h; /* hash code */
373 Section 36.
375 @x l.684 - use renamed local var
376 h=(unsigned char)*i;
377 while (++i<last) h=(h+h+(int)((unsigned char)*i)) % hash_size;
379 h=(unsigned char)*i;
380 while (++i<last) h=(h+h+(int)((unsigned char)*i)) % hash_size;
383 Section 37.
385 @x l.692 - use renamed local var
386 p=hash[h];
388 p=hash[h];
391 @x l.696 - use renamed local var
392   p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
394   p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
397 Section 38.
399 @x l.703
400 @<Pred...@>=
401 void init_p();
403 @<External functions@>=
404 extern void init_p (name_pointer p, char t);
407 Section 42.
409 @x l.766
410 print_section_name(p)
411 name_pointer p;
413 print_section_name (name_pointer p)
416 Section 43.
418 @x l.785
419 sprint_section_name(dest,p)
420   char*dest;
421   name_pointer p;
423 sprint_section_name (char *dest, name_pointer p)
426 Section 44.
428 @x l.805
429 void
430 print_prefix_name(p)
431 name_pointer p;
433 static void
434 print_prefix_name (name_pointer p)
437 Section 45.
439 @x l.826
440 int web_strcmp(j,j_len,k,k_len) /* fuller comparison than |strcmp| */
441   char *j, *k; /* beginning of first and second strings */
442   int j_len, k_len; /* length of strings */
444 /* fuller comparison than |strcmp| */
445 static int
446 web_strcmp (char *j, int j_len, char *k, int k_len)
449 @x l.830 -- rename local vars, not to shadow math function
450   char *j1=j+j_len, *k1=k+k_len;
451   while (k<k1 && j<j1 && *j==*k) k++, j++;
452   if (k==k1) if (j==j1) return equal;
453     else return extension;
454   else if (j==j1) return prefix;
456   char *j1=j+j_len, *k1=k+k_len;
457   while (k<k1 && j<j1 && *j==*k) k++, j++;
458   if (k==k1) if (j==j1) return equal;
459     else return extension;
460   else if (j==j1) return prefix;
463 Section 46.
465 @x l.852
466 @<Prede...@>=
467 extern void init_node();
469 @<External functions@>=
470 extern void init_node (name_pointer node);
473 Section 47.
475 @x l.856
476 name_pointer
477 add_section_name(par,c,first,last,ispref) /* install a new node in the tree */
478 name_pointer par; /* parent of new node */
479 int c; /* right or left? */
480 char *first; /* first character of section name */
481 char *last; /* last character of section name, plus one */
482 int ispref; /* are we adding a prefix or a full name? */
484 static name_pointer
485 add_section_name (name_pointer par, int c, char *first, char *last,
486                   int ispref)  /* install a new node in the tree */
489 Section 48.
491 @x l.885
492 void
493 extend_section_name(p,first,last,ispref)
494 name_pointer p; /* name to be extended */
495 char *first; /* beginning of extension text */
496 char *last; /* one beyond end of extension text */
497 int ispref; /* are we adding a prefix or a full name? */
499 static void
500 extend_section_name (name_pointer p, char *first, char *last, int ispref)
503 Section 49.
505 @x l.914
506 section_lookup(first,last,ispref) /* find or install section name in tree */
507 char *first, *last; /* first and last characters of new name */
508 int ispref; /* is the new name a prefix or a full name? */
510 /* find or install section name in tree */
511 section_lookup (char *first, char *last, int ispref)
514 Section 53.
516 @x l.1018
517 int section_name_cmp();
519 static int section_name_cmp (char**, int, name_pointer);
522 Section 54.
524 @x l.1021
525 int section_name_cmp(pfirst,len,r)
526 char **pfirst; /* pointer to beginning of comparison string */
527 int len; /* length of string */
528 name_pointer r; /* section name being compared */
530 static int
531 section_name_cmp (char **pfirst, int len, name_pointer r)
534 Section 57.
536 @x l.1092
537 @<Predecl...@>=
538 void  err_print();
540 @<External functions@>=
541 extern void  err_print (const char*);
544 Section 58.
546 @x l.1098
547 err_print(s) /* prints `\..' and location of error message */
548 char *s;
550 err_print (const char *s) /* prints `\..' and location of error message */
553 Section 60.
555 @x l.1140
556 @<Prede...@>=
557 int wrap_up();
558 extern void print_stats();
560 @<External functions@>=
561 extern int wrap_up (void);
562 extern void print_stats (void);
565 Section 61.
567 @x l.1151
568 int wrap_up() {
570 int wrap_up (void) {
573 Section 63.
575 @x l.1173
576 @<Predec...@>=
577 void fatal(), overflow();
579 @<External functions@>=
580 extern void fatal (const char*, const char*);
581 extern void overflow (const char*);
584 Section 64.
586 @x l.1180
587 fatal(s,t)
588   char *s,*t;
590 fatal (const char *s, const char *t)
593 Section 65.
595 @x l.1191
596 overflow(t)
597   char *t;
599 overflow (const char *t)
602 Section 67.
604 @x l.1212
605 the names of those files. Most of the 128 flags are undefined but available
606 for future extensions.
608 the names of those files. Most of the 128 flags are undefined but available
609 for future extensions.
611 We use `kpathsea' library functions to find literate sources and
612 NLS configuration files. When the files you expect are not
613 being found, the thing to do is to enable `kpathsea' runtime
614 debugging by assigning to |kpathsea_debug| variable a small number
615 via `\.{-d}' option. The meaning of number is shown below. To set
616 more than one debugging options sum the corresponding numbers.
617 $$\halign{\hskip5em\tt\hfil#&&\qquad\tt#\cr
618  1&report `\.{stat}' calls\cr
619  2&report lookups in all hash tables\cr
620  4&report file openings and closings\cr
621  8&report path information\cr
622 16&report directory list\cr
623 32&report on each file search\cr
624 64&report values of variables being looked up\cr}$$
625 Debugging output is always written to |stderr|, and begins with the string
626 `\.{kdebug:}'.
629 @x l.1218
630 @d show_happiness flags['h'] /* should lack of errors be announced? */
632 @d show_happiness flags['h'] /* should lack of errors be announced? */
633 @d show_kpathsea_debug flags['d']
634   /* should results of file searching be shown? */
637 @x l.1234
638 show_banner=show_happiness=show_progress=1;
640 show_banner=show_happiness=show_progress=1;
643 Section 69.
645 @x l.1252
646 void scan_args();
648 static void scan_args (void);
652 Section 70.
654 @x l.1255
655 void
656 scan_args()
658 static void
659 scan_args (void)
663 Section 71.
665 @x l.1282 - use a define for /dev/null
666   if (found_change<=0) strcpy(change_file_name,"/dev/null");
668   if (found_change<=0) strcpy(change_file_name,DEV_NULL);
671 @x l.1302 - no alt_web_file_name
672   sprintf(alt_web_file_name,"%s.web",*argv);
677 Section 74.
679 @x l.1344
680 @ @<Handle flag...@>=
683 @ @<Handle flag...@>=
685   if (strcmp("-help",*argv)==0 || strcmp("--help",*argv)==0)
686     @<Display help message and exit@>;
687   if (strcmp("-version",*argv)==0 || strcmp("--version",*argv)==0)
688     @<Display version information and exit@>;
691 @x l.1347
692   else flag_change=1;
694   else flag_change=1;
695   if (*(*argv+1)=='d')
696     if (sscanf(*argv+2,"%u",&kpathsea_debug)!=1) @<Print usage error...@>;
699 @x l.1349
700     flags[*dot_pos]=flag_change;
702     flags[(unsigned char)*dot_pos]=flag_change;
705 Section 75.
707 @x l.1354
708 if (program==ctangle)
709   fatal(
710 "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
711    ,"");
712 @.Usage:@>
713 else fatal(
714 "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
715    ,"");
717 if (program==ctangle) {
718   fprintf(stderr, "ctangle: Need one to three file arguments.\n");
719   usage("ctangle");
720 } else {
721   fprintf(stderr, "cweave: Need one to three file arguments.\n");
722   usage("cweave");
726 Section 77.
728 @x l.1375
729 FILE *active_file; /* currently active file for \.{CWEAVE} output */
731 FILE *active_file; /* currently active file for \.{CWEAVE} output */
732 char *found_filename; /* filename found by |kpse_find_file| */
735 Section 78.
737 @x l.1380 Use binary mode for output files
738   if ((C_file=fopen(C_file_name,"w"))==NULL)
740   if ((C_file=fopen(C_file_name,"wb"))==NULL)
743 @x l.1386 Use binary mode for output files
744   if ((tex_file=fopen(tex_file_name,"w"))==NULL)
746   if ((tex_file=fopen(tex_file_name,"wb"))==NULL)
750 Section 81. (reused)
752 @x l.1403
753 @ We predeclare several standard system functions here instead of including
754 their system header files, because the names of the header files are not as
755 standard as the names of the functions. (For example, some \CEE/ environments
756 have \.{<string.h>} where others have \.{<strings.h>}.)
758 @<Predecl...@>=
759 extern int strlen(); /* length of string */
760 extern int strcmp(); /* compare strings lexicographically */
761 extern char* strcpy(); /* copy one string to another */
762 extern int strncmp(); /* compare up to $n$ string characters */
763 extern char* strncpy(); /* copy up to $n$ string characters */
765 @ We declare some more prototypes for exported function in cases where this
766 could not be done easily without changing section numbers.
768 @<External functions@>=
769 extern void common_init (void);
770 extern int input_ln (FILE *fp);
771 extern void reset_input (void);
772 extern int get_line (void);
773 extern void check_complete (void);
774 extern name_pointer id_lookup (const char *first, const char *last, char t);
775 extern void print_section_name (name_pointer p);
776 extern void sprint_section_name (char *dest, name_pointer p);
777 extern name_pointer section_lookup (char *first, char *last, int ispref);
781 @** Index.
783 @** External functions.  In order to allow for type checking we create a
784 header file \.{cweb.h} containing the declaration of all functions defined
785 in \.{common.w} and used in \.{ctangle.w} and \.{cweave.w} or vice versa.
787 @(cweb.h@>=
788 @=/* Prototypes for functions, either@>
789 @= * declared in common.w and used in ctangle.w and cweave.w, or@>
790 @= * used in common.w and declared in ctangle.w and cweave.w.  */@>
791 @<External functions@>@;
792 extern const char *versionstring;
794 @** System dependent changes.
796 @ Modules for dealing with help messages and version info.
798 @<Display help message and exit@>=
799 usagehelp(program==ctangle ? CTANGLEHELP : CWEAVEHELP, NULL);
800 @.--help@>
802 @ Will have to change these if the version numbers change (ouch).
804 @d ctangle_banner "This is CTANGLE, Version 3.64"
805 @d cweave_banner "This is CWEAVE, Version 3.64"
807 @<Display version information and exit@>=
808 printversionandexit((program==ctangle ? ctangle_banner : cweave_banner),
809   "Silvio Levy and Donald E. Knuth", NULL, NULL);
810 @.--version@>
812 @** Index.