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