1% Changes to adapt CTIE to web2c.
2% Copyright 2002,2003 Julian Gilbey
3% All rights reserved.
4%
5% This file is distributed WITHOUT ANY WARRANTY, express or implied.
6%
7% Permission is granted to make and distribute verbatim copies of this
8% file provided that the copyright notice and this permission notice
9% are preserved on all copies.
10%
11% Permission is granted to copy and distribute modified versions of this
12% file under the conditions for verbatim copying, provided that the
13% entire resulting derived work is distributed under the terms of a
14% permission notice identical to this one.
15%
16% This file is based heavily on tie.ch by Olaf Weber to adapt tie.w to
17% the web2c system and on comm-w2c.ch from the Web2C 7.4.5 distribution
18% by Wlodek Bzyl and Olaf Weber.
19
20@x l.19 Add macro definitions
21\def\title{The CTIE processor}
22@y
23\def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}}
24
25\def\title{The CTIE processor}
26@z
27
28@x l.102
29main(argc, argv)
30        int argc; string *argv;
31@y
32int main (int argc, string *argv)
33@z
34
35@x l.105 Set up kpathsea stuff
36    @<Initialise parameters@>;
37@y
38    @<Set up |PROGNAME| feature and initialize the search path mechanism@>;
39    @<Initialise parameters@>;
40@z
41
42These are defined by kpathsea; we replace this by the path-searching
43initialisation code taken almost verbatim from comm-w2c.ch.
44@x l.116
45@ We include the additional types |boolean| and |string|.  \.{CTIE}
46replaces the complex \.{TIE} character set handling (based on that of
47the original \.{WEB} system) with the standard \.{CWEB} behaviour, and
48so uses the |char| type for input and output.
49
50@d false 0
51@d true 1
52
53@<Global types@>=
54typedef int boolean;
55typedef char* string;
56@y
57@ The \.{ctie} program from the original \.{CTIE} package uses the
58compile-time default directory or the value of the environment
59variable \.{CWEBINPUTS} as an alternative place to be searched for
60files, if they could not be found in the current directory.
61
62This version uses the \Kpathsea/ mechanism for searching files.
63The directories to be searched for come from three sources:
64
65 (a)~a user-set environment variable \.{CWEBINPUTS}
66    (overriden by \.{CWEBINPUTS\_ctie});\par
67 (b)~a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
68    e.g. \.{CWEBINPUTS=.:$TEXMF/texmf/cweb//}
69    or \.{CWEBINPUTS.ctie=.:$TEXMF/texmf/cweb//};\hangindent=2\parindent\par
70 (c)~compile-time default directories \.{.:$TEXMF/texmf/cweb//}
71    (specified in \.{texmf.in}).
72
73@d kpse_find_cweb(name) kpse_find_file(name, kpse_cweb_format, true)
74
75@ The simple file searching is replaced by the `path searching'
76mechanism that the \Kpathsea/ library provides.
77
78We set |kpse_program_name| to |"ctie"|.  This means if the variable
79|CWEBINPUTS.ctie| is present in \.{texmf.cnf} (or |CWEBINPUTS_ctie| in
80the environment) its value will be used as the search path for
81filenames.  This allows different flavors of \.{CTIE} to have
82different search paths.
83
84@<Set up |PROGNAME| feature and initialize the search path mechanism@>=
85kpse_set_program_name(argv[0], "ctie");
86
87@ We include the additional types |boolean| and |string|.  \.{CTIE}
88replaces the complex \.{TIE} character set handling (based on that of
89the original \.{WEB} system) with the standard \.{CWEB} behaviour, and
90so uses the |char| type for input and output.
91
92The |kpathsea| library (version 3.4.5) defines the |true|, |false|,
93|boolean| and |string| types in \.{kpathsea/types.h}, so we do not
94actually need to define them here.
95@z
96
97@x l.129 The kpathsea include files find the right header file for these.
98@ We predeclare some standard string-handling functions here instead of
99including their system header files, because the names of the header files
100are not as standard as the names of the functions.  (There's confusion
101between \.{<string.h>} and \.{<strings.h>}.)
102
103@<Predecl...@>=
104extern int strlen(); /* length of string */
105extern char* strcpy(); /* copy one string to another */
106extern int strncmp(); /* compare up to $n$ string characters */
107extern char* strncpy(); /* copy up to $n$ string characters */
108extern char *strerror();
109@y
110@ We don't need to predeclare any string handling functions here, as
111the \.{kpathsea} headers do the right thing.
112@z
113
114@x l.149
115@d xisupper(c) (isupper(c)&&((unsigned char)c<0200))
116@y
117@d xisupper(c) (isupper((unsigned char)c)&&((unsigned char)c<0200))
118@z
119
120@x l.173 The kpathsea include files must be first.
121#include <stdio.h>
122@y
123#include <kpathsea/kpathsea.h>
124#include <stdio.h>
125@z
126
127@x l.176 And this.
128@ And we need dynamic memory allocation.
129This should cause no trouble in any \CEE/ program.
130@^system dependencies@>
131
132@<Global \&{\#include}s@>=
133#ifdef __STDC__
134#include <stdlib.h>
135#else
136#include <malloc.h>
137#endif
138@y
139@ And we need dynamic memory allocation.
140This should cause no trouble in any \CEE/ program.
141The \.{kpathsea} include files handle the definition of |malloc()|,
142too.
143@^system dependencies@>
144@z
145
146@x l.284 way too short!
147@d max_file_name_length 60
148@y
149@d max_file_name_length 1024
150@z
151
152@x l.329
153boolean get_line(i, do_includes)
154        file_index i; boolean do_includes;
155@y
156static boolean
157get_line (file_index i, boolean do_includes)
158@z
159
160Handle input lines with CRLF
161
162@x l.376
163        if ((*(k++) = c) != ' ') inp_desc->limit = k;
164@y
165        if ((*(k++) = c) != ' ' && c != '\r') inp_desc->limit = k;
166@z
167
168@x l.436
169        if ((*(k++) = c) != ' ') inp_desc->limit = k;
170@y
171        if ((*(k++) = c) != ' ' && c != '\r') inp_desc->limit = k;
172@z
173
174The next piece is simplified using the kpathsea kpse_find_file
175function.
176
177@x l.497
178If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
179of the same name was defined at compile time,
180\.{CWEB} will look for include files in the directory thus named, if
181it cannot find them in the current directory.
182(Colon-separated paths are not supported.)
183@y
184We use the \Kpathsea/ library (in particular, the \.{CWEBINPUTS}
185variable) to search for this file.
186@z
187
188@x l.510 Don't need the same variables any longer
189    char temp_file_name[max_file_name_length];
190    char *file_name_end;
191    char *k, *kk;
192    int l; /* length of file name */
193@y
194    char *file_name_end;
195    string fullname;
196    char *k;
197@z
198
199@x l.534 Replace with kpse_find_file
200    if ((new_inc->the_file=fopen(new_inc->file_name, "r"))!=NULL) {
201@y
202    fullname=kpse_find_cweb(new_inc->file_name);
203    if (fullname)
204        new_inc->the_file=fopen(fullname, "r");
205    if (fullname!=NULL && new_inc->the_file!=NULL) {
206        free(fullname);
207@z
208
209@x l.539 And this part is replaced by kpse_find_file
210    kk=getenv("CWEBINPUTS");
211    if (kk!=NULL) {
212        if ((l=strlen(kk))>max_file_name_length-2) too_long();
213        strcpy(temp_file_name, kk);
214    }
215    else {
216#ifdef CWEBINPUTS
217        if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
218        strcpy(temp_file_name, CWEBINPUTS);
219#else
220        l=0;
221#endif /* |CWEBINPUTS| */
222    }
223    if (l>0) {
224        if (k+l+2>=file_name_end)  too_long();
225        for (; k>= new_inc->file_name; k--) *(k+l+1)=*k;
226        strcpy(new_inc->file_name, temp_file_name);
227        new_inc->file_name[l]='/'; /* \UNIX/ pathname separator */
228        if ((new_inc->the_file=fopen(new_inc->file_name, "r"))!=NULL) {
229            new_inc->parent=inp_desc->current_include; /* link it in */
230            inp_desc->current_include=new_inc;
231            goto restart; /* success */
232        }
233    }
234@y
235@z
236
237@x l.565 slightly more useful error message
238    err_print(i, "! Cannot open include file");
239@y
240    if (fullname) {
241        free(fullname);
242        err_print(i, "! Cannot open include file");
243    } else
244        err_print(i, "! Cannot find include file");
245@z
246
247
248@x l.585
249void err_print();
250@y
251void err_print (file_index, const char *);
252@z
253
254@x l.590
255void err_print(i, s) /* prints `\..' and location of error message */
256file_index i; char *s;
257@y
258void err_print (file_index i, const char *s)
259/* prints `\..' and location of error message */
260@z
261
262@x l.664
263int wrap_up()
264@y
265int wrap_up (void)
266@z
267
268@x l.674
269int wrap_up();
270@y
271int wrap_up (void);
272@z
273
274@x l.697
275void pfatal_error();
276@y
277void pfatal_error (const char *, const char *);
278@z
279
280@x l.700
281void pfatal_error(s, t)
282char *s, *t;
283@y
284void pfatal_error (const char *s, const char *t)
285@z
286
287@x l.731 Use binary mode for output files
288    out_file=fopen(out_name, "w");
289@y
290    out_file=fopen(out_name, "wb");
291@z
292
293@x l.747 Use the kpathsea library to do this
294@ For the master file we start by reading its first line into the
295buffer, if we could open it.
296
297@<Get the master file started@>=
298{
299    input_organisation[0]->the_file=
300        fopen(input_organisation[0]->file_name, "r");
301
302    if (input_organisation[0]->the_file==NULL)
303        pfatal_error("! Cannot open master file ",
304            input_organisation[0]->file_name);
305@.Cannot open master file@>
306@y
307@ For the master file we start by reading its first line into the
308buffer, if we could open it.  We use the \.{kpathsea} library to find
309the file.
310
311@<Get the master file started@>=
312{
313    string fullname;
314
315    fullname = kpse_find_cweb(input_organisation[0]->file_name);
316    if (fullname)
317        input_organisation[0]->the_file = fopen(fullname, "r");
318
319    if (fullname==NULL || input_organisation[0]->the_file==NULL) {
320        if (fullname) {
321            pfatal_error("! Cannot open master file ",
322                input_organisation[0]->file_name);
323        } else {
324            fatal_error(-1, "! Cannot find master file ",
325                input_organisation[0]->file_name);
326        }
327    }
328    else free(fullname);
329@.Cannot open master file@>
330@.Cannot find master file@>
331@z
332
333@x l.768 And this
334@<Prepare the change files@>=
335{
336    file_index i;
337
338    i=1;
339    while (i<no_ch) {
340        input_organisation[i]->the_file=
341            fopen(input_organisation[i]->file_name, "r");
342        if (input_organisation[i]->the_file==NULL)
343            pfatal_error("! Cannot open change file ",
344                input_organisation[i]->file_name);
345@.Cannot open change file@>
346@y
347@<Prepare the change files@>=
348{
349    file_index i;
350    string fullname;
351
352    i=1;
353    while (i<no_ch) {
354        fullname = kpse_find_cweb(input_organisation[i]->file_name);
355        if (fullname)
356            input_organisation[i]->the_file = fopen(fullname, "r");
357
358        if (fullname==NULL || input_organisation[i]->the_file==NULL) {
359            if (fullname) {
360                pfatal_error("! Cannot open change file ",
361                    input_organisation[i]->file_name);
362            } else {
363                fatal_error(-1, "! Cannot find change file ",
364                    input_organisation[i]->file_name);
365            }
366        }
367        else free(fullname);
368@.Cannot open change file@>
369@.Cannot find change file@>
370@z
371
372@x l.792
373boolean lines_dont_match(i, j)
374        file_index i, j;
375@y
376static boolean
377lines_dont_match (file_index i, file_index j)
378@z
379
380@x l.809
381void init_change_file(i)
382        file_index i;
383@y
384static void
385init_change_file (file_index i)
386@z
387
388@x l.833
389    if (xisupper(ccode)) ccode=tolower(ccode);
390@y
391    if (xisupper(ccode)) ccode=tolower((unsigned char)ccode);
392@z
393
394@x l.858
395void put_line(j)
396       file_index j;
397@y
398static void
399put_line (file_index j)
400@z
401
402@x l.873
403boolean e_of_ch_module(i)
404        file_index i;
405@y
406static boolean
407e_of_ch_module (file_index i)
408@z
409
410@x l.894
411boolean e_of_ch_preamble(i)
412        file_index i;
413@y
414static boolean
415e_of_ch_preamble (file_index i)
416@z
417
418@x l.1106
419void usage_error()
420{
421    @<Print the banners@>;
422    fprintf(stderr, "Usage: ctie -[mc] outfile master changefile(s)\n");
423@y
424static void
425usage_error (void)
426{
427    @<Print the banners@>;
428    fprintf(stderr, "Usage: ctie -m|-c outfile master changefile(s)\n");
429@z
430
431@x l.1119 Add Web2C version to banner string
432printf("%s\n", banner); /* print a ``banner line'' */
433@y
434{
435    printf("%s (%s)\n", banner, kpathsea_version_string); /* print a ``banner line'' */
436}
437@z
438
439@x l.1218
440string CTIEHELP[] = {
441    "Usage: ctie -[mc] outfile master changefile(s)",
442@y
443const_string CTIEHELP[] = {
444    "Usage: ctie -m|-c outfile master changefile(s)",
445@z
446
447@x l.1233
448void usage_help();
449void print_version_and_exit();
450@y
451static void usage_help (void);
452static void print_version_and_exit (const_string, const_string);
453@z
454
455@x l.1238
456void usage_help()
457{
458    string *message=CTIEHELP;
459@y
460static void
461usage_help (void)
462{
463    const_string *message=CTIEHELP;
464@z
465
466@x l.1253
467void print_version_and_exit(name, version)
468        string name, version;
469{
470    printf ("%s %s\n", name, version);
471
472    puts ("Copyright (C) 2002,2003 Julian Gilbey.");
473
474    puts ("There is NO warranty.  This is free software.  See the source");
475    puts ("code of CTIE for redistribution conditions.");
476
477    exit (0);
478}
479@y
480static void
481print_version_and_exit (const_string name, const_string version)
482{
483    printf ("%s %s\n", name, version);
484    puts (kpathsea_version_string);
485
486    puts ("Copyright (C) 2002,2003 Julian Gilbey.");
487    puts ("Kpathsea is copyright (C) 1999 Free Software Foundation, Inc.");
488
489    puts ("There is NO warranty.  This is free software.");
490    puts ("Redistribution of this software is covered by the terms of");
491    puts ("both the CTIE copyright and the GNU General Public Licence.");
492    puts ("For more information about these matters, see the files");
493    puts ("named COPYING and the CTIE source.");
494    puts ("Primary authors of CTIE: Julian Gilbey.");
495    puts ("Kpathsea written by Karl Berry and others.\n");
496
497    exit (0);
498}
499@z
500
501@x l.1267
502@* System-dependent changes.
503This section should be replaced, if necessary, by
504changes to the program that are necessary to make \.{CTIE}
505work at a particular installation.  It is usually best to
506design your change file so that all changes to previous
507modules preserve the module numbering; then everybody's
508version will be consistent with the printed program.  More
509extensive changes, which introduce new modules, can be
510inserted here; then only the index itself will get a new
511module number.
512@^system dependencies@>
513@y
514@* System-dependent changes.
515There are no additional changes.
516@z
517