home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / c / cweb / common.ch < prev    next >
Encoding:
Text File  |  1994-12-14  |  66.4 KB  |  1,954 lines

  1.                                 -*-Web-*-
  2. This file, COMMON.CH, is part of CWEB (Version 3.3 [patch level 11]).
  3. It is a changefile for COMMON.W, Version 3.3.
  4.  
  5. Authors and Contributors:
  6. (H2B) Hans-Hermann Bode, Universität Osnabrück,
  7.   (hhbode@@dosuni1.rz.uni-osnabrueck.de or HHBODE@@DOSUNI1.BITNET).
  8.  
  9. (GG) Giuseppe Ghibò,
  10.   (ghibo@@galileo.polito.it).
  11.  
  12. (KG) Klaus Guntermann, TH Darmstadt,
  13.   (guntermann@@iti.informatik.th-darmstadt.de).
  14.  
  15. (AS) Andreas Scherer, RWTH Aachen,
  16.   (scherer@@genesis.informatik.rwth-aachen.de).
  17.  
  18. (BS) Barry Schwartz,
  19.   (trashman@@crud.mn.org).
  20.  
  21. (CS) Carsten Steger, Universität München,
  22.   (carsten.steger@@informatik.tu-muenchen.de).
  23.  
  24. (TW) Tomas Willis,
  25.   (tomas@@cae.wisc.edu).
  26.  
  27. Caveat utilitor:  Some of the source code introduced by this change file is
  28. made conditional to the use of specific compilers on specific systems.
  29. This applies to places marked with `#ifdef __MSDOS__' and `#ifdef __TURBOC__',
  30. `#ifdef _AMIGA' and `#ifdef __SASC'.
  31.  
  32. Some of the changes made in this document are marked by one or more
  33. keywords to indicate that they are somehow related to each other:
  34.  
  35.      - None: These changes are necessary for the indentification
  36.        of this port.
  37.  
  38.      - ANSI: This distribution of CWEB 3.3 not only fully supports
  39.        the writing and documentation of ANSI-C programs, but has been
  40.        transformed into a set of ANSI-C programs (in fact C++ programs)
  41.        by adding function prototypes, standard header files, explicit
  42.        casts, and other features.
  43.  
  44.      - EXTENSIONS: New flags and their effects are introduced by such
  45.        changes.  There are no new CWEB commands (yet).
  46.  
  47.      - MEMORY ALLOCATION: All internal arrays are replaced by pointers
  48.        that address dynamically allocated memory blocks.  Although there
  49.        is no external configuration file or other possibility of changing
  50.        the dimensions at runtime, this effort has the positive effect that
  51.        all source modules can be compiled in the "NEAR" data segment, thus
  52.        making the programs "pure" and enabling them to be made "resident"
  53.        on the Amiga.
  54.  
  55.      - OUTPUT: All three programs of the CWEB system write into
  56.        temporary files first, then they check if there are any
  57.        differences between the current run and possible earlier runs
  58.        and their results, before activating the output "for real".
  59.  
  60.      - SYSTEM DEPENDENCIES: Should be clear.  These changes are caused
  61.        by porting CWEB to other systems than UNIX.  Care has been taken
  62.        to make these points safe on all machines.
  63.  
  64.      - TRANSLATION: For support of the "locale.library" mechanism of the
  65.        Commodore Amiga, all internal strings of characters have been
  66.        replaced by references to an external array in "cweb.h".  The
  67.        portable part of this produces the English default, but on the
  68.        Amiga system support for other languages is given by means of
  69.        "language catalogs".
  70.  
  71. This program is distributed WITHOUT ANY WARRANTY, express or implied.
  72.  
  73. The following copyright notice extends to this changefile only, not to
  74. the masterfile COMMON.W.
  75.  
  76. Copyright (C) 1993,1994 Andreas Scherer
  77. Copyright (C) 1991,1993 Carsten Steger
  78. Copyright (C) 1991-1993 Hans-Hermann Bode
  79.  
  80. Permission is granted to make and distribute verbatim copies of this
  81. document provided that the copyright notice and this permission notice
  82. are preserved on all copies.
  83.  
  84. Permission is granted to copy and distribute modified versions of this
  85. document under the conditions for verbatim copying, provided that the
  86. entire resulting derived work is given a different name and distributed
  87. under the terms of a permission notice identical to this one.
  88.  
  89. Version history:
  90.  
  91. Version    Date        Author    Comment
  92. a1/t1    10 Oct 1991    H2B    First attempt for COMMON.W 2.0.
  93. p2    13 Feb 1992    H2B    Updated for COMMON.W 2.1, ANSI and Turbo
  94.                 changefiles merged together.
  95. p3    16 Apr 1992    H2B    Updated for COMMON.W 2.2, change option for
  96.                 |@@i| completed.
  97. p4    22 Jun 1992    H2B    Updated for COMMON.W 2.4, getting INCLUDEDIR
  98.                 from environment variable CWEBINCLUDE.
  99. p5    19 Jul 1992    H2B    string.h included, usage message extended.
  100. p5a    24 Jul 1992    KG    adaptions for other ANSI C compiler
  101. p5b    28 Jul 1992    H2B    Remaining headers converted to ANSI style.
  102. p5c    30 Jul 1992    KG    removed comments used after #endif
  103. p6    06 Sep 1992    H2B    Updated for COMMON.W 2.7.
  104. p6a     15 Mar 1993     AS      adaptions for SAS/C 6.0 compiler
  105. p6b     28 Jul 1993     AS      path delimiters are `/' or `:' for AMIGA
  106.     31 Aug 1993    AS    return codes extended to AMIGA values
  107. p6c    04 Sep 1993    AS    path searching with CWEBINCLUDE
  108. p6d    09 Oct 1993    AS    Updated for COMMON.W 2.8. (This was p7 for me)
  109. p7    06 Nov 1992    H2B    Converted to master change file, updated for
  110.                 common.w 2.8. [Not released.]
  111. p7.5    29 Nov 1992    H2B    Updated for COMMON.W 2.9beta. [Not released.]
  112. p8    04 Dec 1992    H2B    Updated for COMMON.W 2.9++ (stuff went into
  113.                 the source file). [Not released.]
  114. p8a    10 Mar 1993    H2B    Restructured for public release.
  115.                 [Not released.]
  116. p8b    15 Apr 1993    H2B    Updated for COMMON.W 3.0beta. [Not released.]
  117. p8c    21 Jun 1993    H2B    Updated for final COMMON.W 3.0.
  118. p8d    26 Oct 1993    AS    Incorporated with AMIGA version 2.8 [p7] and
  119.                 updated to version 3.0.
  120. p8e    04 Nov 1993    AS    Minor bugs fixed for UNIX and GNU-C.
  121. p9    18 Nov 1993    AS    Updated for COMMON.W 3.1
  122. p9a    30 Nov 1993    AS    Minor changes and corrections.
  123. p9b    06 Dec 1993    AS    Multilinguality implemented.
  124.     07 Dec 1993    AS    Fixed an obvious portability problem.
  125. p9c    18 Jan 1994    AS    Version information included.
  126.     25 Mar 1994    AS    Special `wrap_up' for Borland C.
  127. p9d    13 May 1994    AS    Dynamic memory allocation.
  128.     24 Jun 1994    AS    ARexx support for error-handling
  129.     02 Jul 1994    AS    Portability version.
  130. p9e    09 Aug 1994    AS    Fix a memory bug.
  131. p10    12 Aug 1994    AS    Updated for CWEB 3.2.
  132. p10a    24 Aug 1994    AS    New option flag list.
  133.     11 Sep 1994    AS    Default values of CWEBINPUTS searched last.
  134.     20 Sep 1994    AS    String argument to `-l' option.
  135.     26 Sep 1994    AS    Replace `calloc' by `malloc'.
  136.                 Fix a bug in the `language switch'.
  137. p10b    11 Oct 1994    AS    Write to check_file and compare results.
  138.     18 Oct 1994    AS    Some refinements for C++ compilation.
  139.     21 Oct 1994    AS    Use _DEV_NULL instead of the multi-way
  140.                 selection for the NULL path/device.
  141.     29 Oct 1994    AS    Several Amiga #includes removed.
  142.     12 Nov 1994    AS    Use SEPARATORS instead of the multi-way
  143.                 selection for '/', ':', '\', etc.
  144.     13 Nov 1994    AS    Take care of opened system resources and
  145.                 temporary files in case of an user abort.
  146. p11    03 Dec 1994    AS    Updated for CWEB 3.3.
  147.     13 Dec 1994    AS    There have been corrections in Stanford.
  148. ------------------------------------------------------------------------------
  149. @x l.1
  150. % This file is part of CWEB.
  151. % This program by Silvio Levy and Donald E. Knuth
  152. % is based on a program by Knuth.
  153. % It is distributed WITHOUT ANY WARRANTY, express or implied.
  154. % Version 3.3 --- December 1994 (works with later versions too)
  155.  
  156. % Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
  157. @y
  158. % This file, common.w, is part of CWEB.
  159. % This program by Silvio Levy and Donald E. Knuth
  160. % is based on a program by Knuth.
  161. % It is distributed WITHOUT ANY WARRANTY, express or implied.
  162. % Version 2.4 --- Don Knuth, June 1992
  163. % Version 2.4 [p5] --- Hans-Hermann Bode, July 1992
  164. % Version 2.4 [p5a] --- Klaus Guntermann, July 1992
  165. % Version 2.4 [p5b] --- Hans-Hermann Bode, July 1992
  166. % Version 2.4 [p5c] --- Klaus Guntermann, July 1992
  167. % Version 2.7 [p6] --- Hans-Hermann Bode, September 1992
  168. % Version 2.7 [p6a] --- Andreas Scherer, March 1993
  169. % Version 2.7 [p6b] --- Andreas Scherer, August 1993
  170. % Version 2.7 [p6c] --- Andreas Scherer, September 1993
  171. % Version 2.8 --- Don Knuth, June 1992
  172. % Version 2.8 [p7] --- Andreas Scherer, October 1993
  173. % Version 3.0 --- Don Knuth, June 1993
  174. % Version 3.0 [p8c] --- Hans-Hermann Bode, June 1993
  175. % Version 3.0 [p8d] --- Andreas Scherer, October 1993
  176. % Version 3.0 [p8e] --- Andreas Scherer, November 1993
  177. % Version 3.1 --- Don Knuth, November 1993
  178. % Version 3.1 [p9] --- Andreas Scherer, November 1993
  179. % Version 3.1 [p9a] --- Andreas Scherer, November 1993
  180. % Version 3.1 [p9b] --- Andreas Scherer, December 1993
  181. % Version 3.1 [p9c] --- Andreas Scherer, January 1994
  182. % Version 3.1 [p9d] --- Andreas Scherer, July 1994
  183. % Version 3.2 [p10] --- Andreas Scherer, August 1994
  184. % Version 3.2 [p10a] --- Andreas Scherer, September 1994
  185. % Version 3.2 [p10b] --- Andreas Scherer, October 1994
  186. % Version 3.3 --- Don Knuth, December 1994
  187. % Version 3.3 [p11] --- Andreas Scherer, December 1994
  188.  
  189. % Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
  190. % Copyright (C) 1991-1993 Hans-Hermann Bode
  191. % Copyright (C) 1991,1993 Carsten Steger
  192. % Copyright (C) 1993,1994 Andreas Scherer
  193. @z
  194. ------------------------------------------------------------------------------
  195. @x l.20
  196. \def\title{Common code for CTANGLE and CWEAVE (Version 3.3)}
  197. @y
  198. \def\title{Common code for CTANGLE and CWEAVE (Version 3.3 [p11])}
  199. @z
  200. ------------------------------------------------------------------------------
  201. @x l.25
  202.   \centerline{(Version 3.3)}
  203. @y
  204.   \centerline{(Version 3.3 [p11])}
  205. @z
  206. ------------------------------------------------------------------------------
  207. @x l.29
  208. Copyright \copyright\ 1987, 1990, 1993 Silvio Levy and Donald E. Knuth
  209. @y
  210. Copyright \copyright\ 1987, 1990, 1993 Silvio Levy and Donald E. Knuth
  211. \smallskip\noindent
  212. Copyright \copyright\ 1991--1993 Hans-Hermann Bode
  213. \smallskip\noindent
  214. Copyright \copyright\ 1991, 1993 Carsten Steger
  215. \smallskip\noindent
  216. Copyright \copyright\ 1993, 1994 Andreas Scherer
  217.  
  218. @i "amiga_types.w"
  219. @z
  220. ------------------------------------------------------------------------------
  221. Activate this, if only the changed modules should be printed.
  222. x l.43
  223. \let\maybe=\iftrue
  224. y
  225. \let\maybe=\iffalse
  226. z
  227. ------------------------------------------------------------------------------
  228. SYSTEM DEPENDENCIES
  229. @x l.58
  230. @<Include files@>@/
  231. @y
  232. @<Include files@>@/
  233. @<Macro definitions@>@/
  234. @z
  235. ------------------------------------------------------------------------------
  236. ANSI, TRANSLATION, OUTPUT
  237. @x l.89
  238. void
  239. common_init()
  240. {
  241.   @<Initialize pointers@>;
  242.   @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>;
  243.   @<Scan arguments and open output files@>;
  244. }
  245. @y
  246. void common_init(void)
  247. {
  248.   @<Set up the event trap@>;
  249.   @<Initialize pointers@>;
  250. #ifdef _AMIGA
  251.   @<Use catalog translations@>;
  252. #endif
  253.   @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>;
  254.   @<Scan arguments and open output files@>;
  255. }
  256. @z
  257. ------------------------------------------------------------------------------
  258. MEMORY ALLOCATION
  259. @x l.159
  260. char buffer[long_buf_size]; /* where each line of input goes */
  261. char *buffer_end=buffer+buf_size-2; /* end of |buffer| */
  262. char *limit=buffer; /* points to the last character in the buffer */
  263. char *loc=buffer; /* points to the next character to be read from the buffer */
  264. @y
  265. char *buffer; /* where each line of input goes */
  266. char *buffer_end; /* end of |buffer| */
  267. char *limit; /* points to the last character in the buffer */
  268. char *loc; /* points to the next character to be read from the buffer */
  269. @z
  270. ------------------------------------------------------------------------------
  271. ANSI
  272. @x l.172
  273. int input_ln(fp) /* copies a line into |buffer| or returns 0 */
  274. FILE *fp; /* what file to read from */
  275. @y
  276. static int input_ln(@t\1\1@> /* copies a line into |buffer| or returns 0 */
  277.   FILE *fp@t\2\2@>) /* what file to read from */
  278. @z
  279. ------------------------------------------------------------------------------
  280. TRANSLATION
  281. @x l.183
  282.       ungetc(c,fp); loc=buffer; err_print("! Input line too long");
  283. @y
  284.       ungetc(c,fp); loc=buffer; err_print(get_string(MSG_ERROR_CO9));
  285. @z
  286. ------------------------------------------------------------------------------
  287. SYSTEM DEPENDENCIES
  288. @x l.206
  289. @d max_file_name_length 60
  290. @y
  291. @d max_file_name_length 256
  292. @z
  293. ------------------------------------------------------------------------------
  294. MEMORY ALLOCATION
  295. @x l.215
  296. FILE *file[max_include_depth]; /* stack of non-change files */
  297. FILE *change_file; /* change file */
  298. char file_name[max_include_depth][max_file_name_length];
  299.   /* stack of non-change file names */
  300. char change_file_name[max_file_name_length]; /* name of change file */
  301. char alt_web_file_name[max_file_name_length]; /* alternate name to try */
  302. int line[max_include_depth]; /* number of current line in the stacked files */
  303. @y
  304. FILE **file; /* stack of non-change files */
  305. FILE *change_file; /* change file */
  306. char **file_name; /* stack of non-change file names */
  307. char *change_file_name; /* name of change file */
  308. char *alt_web_file_name; /* alternate name to try */
  309. int *line; /* number of current line in the stacked files */
  310. @z
  311. ------------------------------------------------------------------------------
  312. ANSI
  313. @x l.236
  314. @d lines_dont_match (change_limit-change_buffer != limit-buffer ||
  315.   strncmp(buffer, change_buffer, limit-buffer))
  316. @y
  317. @d lines_dont_match (change_limit-change_buffer != limit-buffer || @|
  318.   strncmp(buffer, change_buffer, (size_t)(limit-buffer)))
  319. @z
  320. ------------------------------------------------------------------------------
  321. MEMORY ALLOCATION
  322. @x l.240
  323. char change_buffer[buf_size]; /* next line of |change_file| */
  324. @y
  325. char *change_buffer; /* next line of |change_file| */
  326. @z
  327. ------------------------------------------------------------------------------
  328. ANSI
  329. @x l.251
  330. void
  331. prime_the_change_buffer()
  332. @y
  333. static void prime_the_change_buffer(void)
  334. @z
  335. ------------------------------------------------------------------------------
  336. TRANSLATION
  337. @x l.274
  338.     err_print("! Missing @@x in change file");
  339. @y
  340.     err_print(get_string(MSG_ERROR_CO13));
  341. @z
  342. ------------------------------------------------------------------------------
  343. TRANLSATION
  344. @x l.285
  345.     err_print("! Change file ended after @@x");
  346. @y
  347.     err_print(get_string(MSG_ERROR_CO14));
  348. @z
  349. ------------------------------------------------------------------------------
  350. ANSI
  351. @x l.293
  352.   change_limit=change_buffer-buffer+limit;
  353.   strncpy(change_buffer,buffer,limit-buffer+1);
  354. @y
  355.   change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
  356.   strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
  357. @z
  358. ------------------------------------------------------------------------------
  359. ANSI
  360. @x l.320
  361. void
  362. check_change() /* switches to |change_file| if the buffers match */
  363. @y
  364. static void check_change(void) /* switches to |change_file| if the buffers match */
  365. @z
  366. ------------------------------------------------------------------------------
  367. TRANSLATION
  368. @x l.333
  369.       err_print("! Change file ended before @@y");
  370. @y
  371.       err_print(get_string(MSG_ERROR_CO16_1));
  372. @z
  373. ------------------------------------------------------------------------------
  374. TRANSLATION
  375. @x l.347
  376.         err_print("! CWEB file ended during a change");
  377. @y
  378.         err_print(get_string(MSG_ERROR_CO16_2));
  379. @z
  380. ------------------------------------------------------------------------------
  381. TRANSLATION
  382. @x l.359
  383.   loc=buffer+2; err_print("! Where is the matching @@y?");
  384. @y
  385.   loc=buffer+2; err_print(get_string(MSG_ERROR_CO17_1));
  386. @z
  387. ------------------------------------------------------------------------------
  388. TRANSLATION
  389. @x l.366
  390.     err_print("of the preceding lines failed to match");
  391. @y
  392.     err_print(get_string(MSG_ERROR_CO17_2));
  393. @z
  394. ------------------------------------------------------------------------------
  395. ANSI
  396. @x l.378
  397. void
  398. reset_input()
  399. @y
  400. void reset_input(void)
  401. @z
  402. ------------------------------------------------------------------------------
  403. TRANSLATION
  404. @x l.396
  405.        fatal("! Cannot open input file ", web_file_name);
  406. @y
  407.        fatal(get_string(MSG_FATAL_CO19_1), web_file_name);
  408. @z
  409. ------------------------------------------------------------------------------
  410. SYSTEM DEPENDENCIES, TRANSLATION
  411. Right after the web file was opened we set up communication with the AREXX
  412. port of the SAS/C++ 6.x message browser.  If `scmsg' is not yet running we
  413. start it in `rexxonly' mode (no window will appear) and initialize the
  414. compilation run with the (full) name of the web file.
  415. @x l.401
  416. if ((change_file=fopen(change_file_name,"r"))==NULL)
  417.        fatal("! Cannot open change file ", change_file_name);
  418. @y
  419. #ifdef _AMIGA
  420. @<Set up the {\mc AREXX} communication@>;
  421. #endif
  422. if ((change_file=fopen(change_file_name,"r"))==NULL)
  423.        fatal(get_string(MSG_FATAL_CO19_2), change_file_name);
  424. @z
  425. ------------------------------------------------------------------------------
  426. ANSI
  427. @x l.418
  428. typedef unsigned short sixteen_bits;
  429. @y
  430. typedef unsigned char eight_bits;
  431. typedef unsigned short sixteen_bits;
  432. @z
  433. ------------------------------------------------------------------------------
  434. MEMORY ALLOCATION
  435. @x l.420
  436. boolean changed_section[max_sections]; /* is the section changed? */
  437. @y
  438. boolean *changed_section; /* is the section changed? */
  439. @z
  440. ------------------------------------------------------------------------------
  441. ANSI
  442. @x l.426
  443. int get_line() /* inputs the next line */
  444. @y
  445. int get_line(void) /* inputs the next line */
  446. @z
  447. ------------------------------------------------------------------------------
  448. TRANSLATION
  449. @x l.440
  450.       err_print("! Include file name not given");
  451. @y
  452.       err_print(get_string(MSG_ERROR_CO21_1));
  453. @z
  454. ------------------------------------------------------------------------------
  455. TRANSLATION
  456. @x l.445
  457.       err_print("! Too many nested includes");
  458. @y
  459.       err_print(get_string(MSG_ERROR_CO21_2));
  460. @z
  461. ------------------------------------------------------------------------------
  462. SYSTEM DEPENDENCIES, TRANSLATION
  463. We provide a multiple search path algorithm much like the C preprocessor.
  464. @x l.455
  465. @ When an \.{@@i} line is found in the |cur_file|, we must temporarily
  466. stop reading it and start reading from the named include file.  The
  467. \.{@@i} line should give a complete file name with or without
  468. double quotes.
  469. If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
  470. of the same name was defined at compile time,
  471. \.{CWEB} will look for include files in the directory thus named, if
  472. it cannot find them in the current directory.
  473. (Colon-separated paths are not supported.)
  474. The remainder of the \.{@@i} line after the file name is ignored.
  475.  
  476. @d too_long() {include_depth--;
  477.         err_print("! Include file name too long"); goto restart;}
  478.  
  479. @<Include...@>=
  480. #include <stdlib.h> /* declaration of |getenv| and |exit| */
  481. @y
  482. @ When an \.{@@i} line is found in the |cur_file|, we must temporarily
  483. stop reading it and start reading from the named include file.  The
  484. \.{@@i} line should give a complete file name with or without
  485. double quotes.  The remainder of the \.{@@i} line after the file name
  486. is ignored.  \.{CWEB} will look for include files in standard directories
  487. specified in the environment variable \.{CWEBINPUTS}. Multiple search paths
  488. can be specified by delimiting them with \.{PATH\_SEPARATOR}s.  The given
  489. file is searched for in the current directory first.  You also may include
  490. device names; these must have a \.{DEVICE\_SEPARATOR} as their rightmost
  491. character.  For other systems than the {\mc AMIGA} different settings may
  492. be needed.
  493. @^system dependencies@>
  494.  
  495. @d too_long() {include_depth--;
  496.         err_print(get_string(MSG_ERROR_CO22)); goto restart;}
  497.  
  498. @<Include...@>=
  499. #include <stdlib.h> /* declaration of |getenv| and |exit| */
  500. #include <stddef.h> /* type definition of |ptrdiff_t| */
  501. #include <signal.h> /* declaration of |signal| and |SIGINT| */
  502. @#
  503. #ifdef SEPARATORS
  504. char separators[]=SEPARATORS;
  505. #else
  506. char separators[]="://";
  507. #endif
  508. @#
  509. #define PATH_SEPARATOR   separators[0]
  510. #define DIR_SEPARATOR    separators[1]
  511. #define DEVICE_SEPARATOR separators[2]
  512. @z
  513. ------------------------------------------------------------------------------
  514. EXTENSIONS, SYSTEM DEPENDENCIES
  515. CWEB will perform a path search for `@i'nclude files along the environment
  516. variable CWEBINPUTS in case the given file can not be opened in the current
  517. directory or in the absolute path.  The single paths are delimited by
  518. PATH_SEPARATORs.  The default string defined in this change file is
  519. appended to any environment variable CWEBINPUTS, so you don't have to
  520. repeat its entries.  The current directory always is searched first.
  521. @x l.486
  522.   kk=getenv("CWEBINPUTS");
  523.   if (kk!=NULL) {
  524.     if ((l=strlen(kk))>max_file_name_length-2) too_long();
  525.     strcpy(temp_file_name,kk);
  526.   }
  527.   else {
  528. #ifdef CWEBINPUTS
  529.     if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
  530.     strcpy(temp_file_name,CWEBINPUTS);
  531. #else
  532.     l=0;
  533. #endif /* |CWEBINPUTS| */
  534.   }
  535.   if (l>0) {
  536.     if (k+l+2>=cur_file_name_end)  too_long();
  537. @.Include file name ...@>
  538.     for (; k>= cur_file_name; k--) *(k+l+1)=*k;
  539.     strcpy(cur_file_name,temp_file_name);
  540.     cur_file_name[l]='/'; /* \UNIX/ pathname separator */
  541.     if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
  542.       cur_line=0; print_where=1;
  543.       goto restart; /* success */
  544.     }
  545.   }
  546. @y
  547.   if(0==set_path(include_path,getenv("CWEBINPUTS"))) {
  548.     include_depth--; goto restart; /* internal error */
  549.   }
  550.   path_prefix = include_path;
  551.   while(path_prefix) {
  552.     for(kk=temp_file_name, p=path_prefix, l=0;
  553.       p && *p && *p!=PATH_SEPARATOR;
  554.       *kk++ = *p++, l++);
  555.     if(path_prefix && *path_prefix && *path_prefix!=PATH_SEPARATOR && @|
  556.       *--p!=DEVICE_SEPARATOR && *p!=DIR_SEPARATOR) {
  557.       *kk++ = DIR_SEPARATOR; l++;
  558.     }
  559.     if(k+l+2>=cur_file_name_end) too_long(); /* emergency break */
  560.     strcpy(kk,cur_file_name);
  561.     if(cur_file = fopen(temp_file_name,"r")) {
  562.       cur_line=0; print_where=1; goto restart; /* success */
  563.     }
  564.     if(next_path_prefix = strchr(path_prefix,PATH_SEPARATOR))
  565.       path_prefix = next_path_prefix+1;
  566.     else break; /* no more paths to search; no file found */
  567.   }
  568. @z
  569. ------------------------------------------------------------------------------
  570. TRANSLATION
  571. @x l.510
  572.   include_depth--; err_print("! Cannot open include file"); goto restart;
  573. @y
  574.   include_depth--; err_print(get_string(MSG_ERROR_CO23)); goto restart;
  575. @z
  576. ------------------------------------------------------------------------------
  577. TRANSLATION
  578. @x l.533
  579.     err_print("! Change file ended without @@z");
  580. @y
  581.     err_print(get_string(MSG_ERROR_CO25_1));
  582. @z
  583. ------------------------------------------------------------------------------
  584. TRANSLATION
  585. @x l.549
  586.         err_print("! Where is the matching @@z?");
  587. @y
  588.         err_print(get_string(MSG_ERROR_CO25_2));
  589. @z
  590. ------------------------------------------------------------------------------
  591. ANSI
  592. @x l.563
  593. void
  594. check_complete(){
  595.   if (change_limit!=change_buffer) { /* |changing| is 0 */
  596.     strncpy(buffer,change_buffer,change_limit-change_buffer+1);
  597.     limit=buffer+(int)(change_limit-change_buffer);
  598. @y
  599. void check_complete(void) {
  600.   if (change_limit!=change_buffer) { /* |changing| is 0 */
  601.     strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1));
  602.     limit=buffer+(ptrdiff_t)(change_limit-change_buffer);
  603. @z
  604. ------------------------------------------------------------------------------
  605. TRANSLATION
  606. @x l.569
  607.     err_print("! Change file entry did not match");
  608. @y
  609.     err_print(get_string(MSG_ERROR_CO26));
  610. @z
  611. ------------------------------------------------------------------------------
  612. SYSTEM DEPENDENCIES
  613. @x l.589
  614.   char *byte_start; /* beginning of the name in |byte_mem| */
  615. @y
  616.   char HUGE *byte_start; /* beginning of the name in |byte_mem| */
  617. @z
  618. ------------------------------------------------------------------------------
  619. SYSTEM DEPENDENCIES, MEMORY ALLOCATION
  620. @x l.592
  621. typedef name_info *name_pointer; /* pointer into array of |name_info|s */
  622. char byte_mem[max_bytes]; /* characters of names */
  623. char *byte_mem_end = byte_mem+max_bytes-1; /* end of |byte_mem| */
  624. name_info name_dir[max_names]; /* information about names */
  625. name_pointer name_dir_end = name_dir+max_names-1; /* end of |name_dir| */
  626. @y
  627. typedef name_info HUGE *name_pointer; /* pointer into array of |name_info|s */
  628. name_pointer name_dir; /* information about names */
  629. name_pointer name_dir_end; /* end of |name_dir| */
  630. char HUGE *byte_mem; /* characters of names */
  631. char HUGE *byte_mem_end; /* end of |byte_mem| */
  632. @z
  633. ------------------------------------------------------------------------------
  634. ANSI
  635. @x l.602
  636. @d length(c) (c+1)->byte_start-(c)->byte_start /* the length of a name */
  637. @y
  638. @d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
  639. @z
  640. ------------------------------------------------------------------------------
  641. SYSTEM DEPENDENCIES
  642. @x l.612
  643. char *byte_ptr; /* first unused position in |byte_mem| */
  644. @y
  645. char HUGE *byte_ptr; /* first unused position in |byte_mem| */
  646. @z
  647. ------------------------------------------------------------------------------
  648. MEMORY ALLOCATION, SYSTEM DEPENDENCIES, TRANSLATION
  649. @x l.614
  650. @ @<Init...@>=
  651. name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
  652. @y
  653. @ @f type int /* \.{type} becomes the pseudotype \&{type} */
  654. @#
  655. @d alloc_object(object,size,@!type)
  656.    if(!(object = (type *)malloc((size)*sizeof(type))))
  657.       fatal("",get_string(MSG_FATAL_CO85));
  658.  
  659. @<Init...@>=
  660. alloc_object(buffer,long_buf_size,char);
  661. buffer_end = buffer + buf_size - 2;
  662. limit = loc = buffer;
  663. alloc_object(file,max_include_depth,FILE *);
  664. alloc_object(file_name,max_include_depth,char *);
  665. for(phase=0; phase<max_include_depth; phase++)
  666.   alloc_object(file_name[phase],max_file_name_length,char);
  667. alloc_object(change_file_name,max_file_name_length,char);
  668. alloc_object(alt_web_file_name,max_file_name_length,char);
  669. alloc_object(line,max_include_depth,int);
  670. alloc_object(change_buffer,buf_size,char);
  671. alloc_object(changed_section,max_sections,boolean);
  672. #ifdef __TURBOC__
  673. byte_mem=(char HUGE *)allocsafe(max_bytes,sizeof(*byte_mem));
  674. name_dir=(name_pointer)allocsafe(max_names,sizeof(*name_dir));
  675. #else
  676. alloc_object(byte_mem,max_bytes,char);
  677. alloc_object(name_dir,max_names,name_info);
  678. #endif
  679. byte_mem_end = byte_mem + max_bytes - 1;
  680. name_dir_end = name_dir + max_names - 1;
  681. name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
  682. @^system dependencies@>
  683. @z
  684. ------------------------------------------------------------------------------
  685. SYSTEM DEPENDENCIES
  686. @x l.625
  687. struct name_info *link;
  688. @y
  689. struct name_info HUGE *link;
  690. @z
  691. ------------------------------------------------------------------------------
  692. MEMORY ALLOCATION
  693. @x l.639
  694. name_pointer hash[hash_size]; /* heads of hash lists */
  695. hash_pointer hash_end = hash+hash_size-1; /* end of |hash| */
  696. @y
  697. hash_pointer hash; /* heads of hash lists */
  698. hash_pointer hash_end; /* end of |hash| */
  699. @z
  700. ------------------------------------------------------------------------------
  701. ANSI
  702. @x l.643
  703. @ @<Predec...@>=
  704. extern int names_match();
  705. @y
  706. @ @<Predec...@>=
  707. extern int names_match(name_pointer,char *,int,eight_bits);@/
  708. @z
  709. ------------------------------------------------------------------------------
  710. MEMORY ALLOCATION, OUTPUT
  711. @x l.648
  712. @<Init...@>=
  713. for (h=hash; h<=hash_end; *h++=NULL) ;
  714. @y
  715. @<Init...@>=
  716. alloc_object(hash,hash_size,name_pointer);
  717. hash_end = hash + hash_size - 1;
  718. for (h=hash; h<=hash_end; *h++=NULL) ;
  719. alloc_object(C_file_name,max_file_name_length,char);
  720. alloc_object(tex_file_name,max_file_name_length,char);
  721. alloc_object(idx_file_name,max_file_name_length,char);
  722. alloc_object(scn_file_name,max_file_name_length,char);
  723. alloc_object(check_file_name,L_tmpnam,char);
  724. @z
  725. ------------------------------------------------------------------------------
  726. ANSI
  727. @x l.654
  728. name_pointer
  729. id_lookup(first,last,t) /* looks up a string in the identifier table */
  730. char *first; /* first character of string */
  731. char *last; /* last character of string plus one */
  732. char t; /* the |ilk|; used by \.{CWEAVE} only */
  733. @y
  734. name_pointer id_lookup(@t\1\1@> /* looks up a string in the identifier table */
  735.   char *first, /* first character of string */
  736.   char *last, /* last character of string plus one */
  737.   char t@t\2\2@>) /* the |ilk|; used by \.{CWEAVE} only */
  738. @z
  739. ------------------------------------------------------------------------------
  740. ANSI
  741. @x l.665
  742.   l=last-first; /* compute the length */
  743. @y
  744.   l=(int)(last-first); /* compute the length */
  745. @z
  746. ------------------------------------------------------------------------------
  747. ANSI
  748. @x l.696
  749. @<Pred...@>=
  750. void init_p();
  751. @y
  752. @<Pred...@>=
  753. extern void init_p(name_pointer,eight_bits);@/
  754. @z
  755. ------------------------------------------------------------------------------
  756. TRANSLATION
  757. @x l.700
  758.   if (byte_ptr+l>byte_mem_end) overflow("byte memory");
  759.   if (name_ptr>=name_dir_end) overflow("name");
  760. @y
  761.   if (byte_ptr+l>byte_mem_end) overflow(get_string(MSG_OVERFLOW_CO39_1));
  762.   if (name_ptr>=name_dir_end) overflow(get_string(MSG_OVERFLOW_CO39_2));
  763. @z
  764. ------------------------------------------------------------------------------
  765. SYSTEM DEPENDENCIES
  766. @x l.725
  767.   struct name_info *Rlink; /* right link in binary search tree for section
  768. @y
  769.   struct name_info HUGE *Rlink; /* right link in binary search tree for section
  770. @z
  771. ------------------------------------------------------------------------------
  772. ANSI
  773. @x l.758
  774. void
  775. print_section_name(p)
  776. name_pointer p;
  777. @y
  778. void print_section_name(name_pointer p)
  779. @z
  780. ------------------------------------------------------------------------------
  781. SYSTEM DEPENDENCIES
  782. @x l.762
  783.   char *ss, *s = first_chunk(p);
  784. @y
  785.   char HUGE *ss;
  786.   char HUGE *s = first_chunk(p);
  787. @z
  788. ------------------------------------------------------------------------------
  789. ANSI
  790. @x l.767
  791.       term_write(s,ss-s); p=q->link; q=p;
  792.     } else {
  793.       term_write(s,ss+1-s); p=name_dir; q=NULL;
  794. @y
  795.       term_write(s,(size_t)(ss-s)); p=q->link; q=p;
  796.     } else {
  797.       term_write(s,(size_t)(ss+1-s)); p=name_dir; q=NULL;
  798. @z
  799. ------------------------------------------------------------------------------
  800. ANSI
  801. @x l.777
  802. void
  803. sprint_section_name(dest,p)
  804.   char*dest;
  805.   name_pointer p;
  806. @y
  807. void sprint_section_name(char *dest,name_pointer p)
  808. @z
  809. ------------------------------------------------------------------------------
  810. SYSTEM DEPENDENCIES
  811. @x l.782
  812.   char *ss, *s = first_chunk(p);
  813. @y
  814.   char HUGE *ss;
  815.   char HUGE *s = first_chunk(p);
  816. @z
  817. ------------------------------------------------------------------------------
  818. ANSI
  819. @x l.791
  820.     strncpy(dest,s,ss-s), dest+=ss-s;
  821. @y
  822.     strncpy(dest,s,(size_t)(ss-s)), dest+=ss-s;
  823. @z
  824. ------------------------------------------------------------------------------
  825. ANSI
  826. @x l.798
  827. void
  828. print_prefix_name(p)
  829. name_pointer p;
  830. @y
  831. void print_prefix_name(name_pointer p)
  832. @z
  833. ------------------------------------------------------------------------------
  834. SYSTEM DEPENDENCIES
  835. @x l.802
  836.   char *s = first_chunk(p);
  837. @y
  838.   char HUGE *s = first_chunk(p);
  839. @z
  840. ------------------------------------------------------------------------------
  841. ANSI, SYSTEM DEPENDENCIES
  842. @x l.819
  843. int web_strcmp(j,j_len,k,k_len) /* fuller comparison than |strcmp| */
  844.   char *j, *k; /* beginning of first and second strings */
  845.   int j_len, k_len; /* length of strings */
  846. {
  847.   char *j1=j+j_len, *k1=k+k_len;
  848. @y
  849. static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */
  850.   char HUGE *j, /* beginning of first string */
  851.   int j_len, /* length of first string */
  852.   char HUGE *k, /* beginning of second string */
  853.   int k_len@t\2\2@>) /* length of second string */
  854. {
  855.   char HUGE *j1=j+j_len;
  856.   char HUGE *k1=k+k_len;
  857. @z
  858. ------------------------------------------------------------------------------
  859. ANSI
  860. @x l.845
  861. @<Prede...@>=
  862. extern void init_node();
  863. @y
  864. @<Prede...@>=
  865. extern void init_node(name_pointer);@/
  866. @z
  867. ------------------------------------------------------------------------------
  868. ANSI
  869. @x l.849
  870. name_pointer
  871. add_section_name(par,c,first,last,ispref) /* install a new node in the tree */
  872. name_pointer par; /* parent of new node */
  873. int c; /* right or left? */
  874. char *first; /* first character of section name */
  875. char *last; /* last character of section name, plus one */
  876. int ispref; /* are we adding a prefix or a full name? */
  877. @y
  878. name_pointer add_section_name(@t\1\1@> /* install a new node in the tree */
  879.   name_pointer par, /* parent of new node */
  880.   int c, /* right or left? */
  881.   char *first, /* first character of section name */
  882.   char *last, /* last character of section name, plus one */
  883.   int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
  884. @z
  885. ------------------------------------------------------------------------------
  886. ANSI, TRANSLATION
  887. @x l.858
  888.   char *s=first_chunk(p);
  889.   int name_len=last-first+ispref; /* length of section name */
  890.   if (s+name_len>byte_mem_end) overflow("byte memory");
  891.   if (name_ptr+1>=name_dir_end) overflow("name");
  892. @y
  893.   char HUGE *s=first_chunk(p);
  894.   int name_len=(int)(last-first)+ispref; /* length of section name */
  895.   if (s+name_len>byte_mem_end) overflow(get_string(MSG_OVERFLOW_CO39_1));
  896.   if (name_ptr+1>=name_dir_end) overflow(get_string(MSG_OVERFLOW_CO39_2));
  897. @z
  898. ------------------------------------------------------------------------------
  899. ANSI
  900. @x l.878
  901. void
  902. extend_section_name(p,first,last,ispref)
  903. name_pointer p; /* name to be extended */
  904. char *first; /* beginning of extension text */
  905. char *last; /* one beyond end of extension text */
  906. int ispref; /* are we adding a prefix or a full name? */
  907. @y
  908. void extend_section_name(@t\1\1@>
  909.   name_pointer p, /* name to be extended */
  910.   char *first, /* beginning of extension text */
  911.   char *last, /* one beyond end of extension text */
  912.   int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
  913. @z
  914. ------------------------------------------------------------------------------
  915. ANSI, SYSTEM DEPENDENCIES, TRANSLATION
  916. @x l.885
  917.   char *s;
  918.   name_pointer q=p+1;
  919.   int name_len=last-first+ispref;
  920.   if (name_ptr>=name_dir_end) overflow("name");
  921. @y
  922.   char HUGE *s;
  923.   name_pointer q=p+1;
  924.   int name_len=(int)(last-first)+ispref;
  925.   if (name_ptr>=name_dir_end) overflow(get_string(MSG_OVERFLOW_CO39_2));
  926. @z
  927. ------------------------------------------------------------------------------
  928. TRANSLATION
  929. @x l.893
  930.   if (s+name_len>byte_mem_end) overflow("byte memory");
  931. @y
  932.   if (s+name_len>byte_mem_end) overflow(get_string(MSG_OVERFLOW_CO39_1));
  933. @z
  934. ------------------------------------------------------------------------------
  935. ANSI
  936. @x l.906
  937. name_pointer
  938. section_lookup(first,last,ispref) /* find or install section name in tree */
  939. char *first, *last; /* first and last characters of new name */
  940. int ispref; /* is the new name a prefix or a full name? */
  941. @y
  942. name_pointer section_lookup(@t\1\1@> /* find or install section name in tree */
  943.   char *first,char *last, /* first and last characters of new name */
  944.   int ispref@t\2\2@>) /* is the new name a prefix or a full name? */
  945. @z
  946. ------------------------------------------------------------------------------
  947. ANSI
  948. @x l.917
  949.   int name_len=last-first+1;
  950. @y
  951.   int name_len=(int)(last-first)+1;
  952. @z
  953. ------------------------------------------------------------------------------
  954. TRANSLATION
  955. @x l.938
  956.       printf("\n! Ambiguous prefix: matches <");
  957. @.Ambiguous prefix ... @>
  958.       print_prefix_name(p);
  959.       printf(">\n and <");
  960. @y
  961.       printf(get_string(MSG_ERROR_CO50_1));
  962. @.Ambiguous prefix ... @>
  963.       print_prefix_name(p);
  964.       printf(get_string(MSG_ERROR_CO50_2));
  965. @z
  966. ------------------------------------------------------------------------------
  967. TRANSLATION
  968. @x l.967
  969.       printf("\n! New name is a prefix of <");
  970. @y
  971.       printf(get_string(MSG_ERROR_CO52_1));
  972. @z
  973. ------------------------------------------------------------------------------
  974. TRANSLATION
  975. @x l.979
  976.       printf("\n! New name extends <");
  977. @y
  978.       printf(get_string(MSG_ERROR_CO52_2));
  979. @z
  980. ------------------------------------------------------------------------------
  981. TRANSLATION
  982. @x l.985
  983.     printf("\n! Section name incompatible with <");
  984. @.Section name incompatible...@>
  985.     print_prefix_name(r);
  986.     printf(">,\n which abbreviates <");
  987. @y
  988.     printf(get_string(MSG_ERROR_CO52_3));
  989. @.Section name incompatible...@>
  990.     print_prefix_name(r);
  991.     printf(get_string(MSG_ERROR_CO52_4));
  992. @z
  993. ------------------------------------------------------------------------------
  994. ANSI
  995. @x l.1010
  996. @<Predec...@>=
  997. int section_name_cmp();
  998. @y
  999. @<Predec...@>=
  1000. static int section_name_cmp(char **,int,name_pointer);@/
  1001. @z
  1002. ------------------------------------------------------------------------------
  1003. ANSI
  1004. @x l.1014
  1005. int section_name_cmp(pfirst,len,r)
  1006. char **pfirst; /* pointer to beginning of comparison string */
  1007. int len; /* length of string */
  1008. name_pointer r; /* section name being compared */
  1009. @y
  1010. static int section_name_cmp(@t\1\1@>
  1011.   char **pfirst, /* pointer to beginning of comparison string */
  1012.   int len, /* length of string */
  1013.   name_pointer r@t\2\2@>) /* section name being compared */
  1014. @z
  1015. ------------------------------------------------------------------------------
  1016. SYSTEM DEPENDENCIES
  1017. @x l.1021
  1018.   char *ss, *s=first_chunk(r);
  1019. @y
  1020.   char HUGE *ss;
  1021.   char HUGE *s=first_chunk(r);
  1022. @z
  1023. ------------------------------------------------------------------------------
  1024. ANSI
  1025. @x l.1031
  1026.           *pfirst=first+(ss-s);
  1027. @y
  1028.           *pfirst=first+(ptrdiff_t)(ss-s);
  1029. @z
  1030. ------------------------------------------------------------------------------
  1031. ANSI
  1032. @x l.1038
  1033.       if (q!=name_dir) {len -= ss-s; s=q->byte_start; r=q; continue;}
  1034. @y
  1035.       if (q!=name_dir) {len -= (int)(ss-s); s=q->byte_start; r=q; continue;}
  1036. @z
  1037. ------------------------------------------------------------------------------
  1038. ANSI, SYSTEM DEPENDENCIES
  1039. @x l.1053
  1040. |equiv_or_xref| as a pointer to a |char|.
  1041.  
  1042. @<More elements of |name...@>=
  1043. char *equiv_or_xref; /* info corresponding to names */
  1044. @y
  1045. |equiv_or_xref| as a pointer to |void|.
  1046.  
  1047. @<More elements of |name...@>=
  1048. void HUGE *equiv_or_xref; /* info corresponding to names */
  1049. @z
  1050. ------------------------------------------------------------------------------
  1051. ANSI
  1052. @x l.1086
  1053. void  err_print();
  1054.  
  1055. @ @c
  1056. void
  1057. err_print(s) /* prints `\..' and location of error message */
  1058. char *s;
  1059. @y
  1060. extern void err_print(char *);@/
  1061.  
  1062. @ @c
  1063. void err_print(char *s) /* prints `\..' and location of error message */
  1064. @z
  1065. ------------------------------------------------------------------------------
  1066. SYSTEM DEPENDENCIES, TRANSLATION
  1067. @x l.1109
  1068. {if (changing && include_depth==change_depth)
  1069.   printf(". (l. %d of change file)\n", change_line);
  1070. else if (include_depth==0) printf(". (l. %d)\n", cur_line);
  1071.   else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
  1072. @y
  1073. {if (changing && include_depth==change_depth)
  1074.   @<Report an error in the change file@>@;
  1075. else if (include_depth==0)
  1076.   @<Report an error in the web file@>@;
  1077. else
  1078.   @<Report an error in an include file@>@;
  1079.  
  1080. #ifdef _AMIGA
  1081. @<Put the error message in the browser@>@;
  1082. #endif
  1083. @z
  1084. ------------------------------------------------------------------------------
  1085. ANSI
  1086. @x l.1133
  1087. @<Prede...@>=
  1088. int wrap_up();
  1089. extern void print_stats();
  1090. @y
  1091. @<Prede...@>=
  1092. extern int wrap_up(void);@/
  1093. extern void print_stats(void);@/
  1094. @z
  1095. ------------------------------------------------------------------------------
  1096. OUTPUT, SYSTEM DEPENDENCIES, TRANSLATION
  1097. @x l.1137
  1098. @ Some implementations may wish to pass the |history| value to the
  1099. operating system so that it can be used to govern whether or not other
  1100. programs are started. Here, for instance, we pass the operating system
  1101. a status of 0 if and only if only harmless messages were printed.
  1102. @^system dependencies@>
  1103.  
  1104. @c
  1105. int wrap_up() {
  1106.   putchar('\n');
  1107.   if (show_stats)
  1108.     print_stats(); /* print statistics about memory usage */
  1109.   @<Print the job |history|@>;
  1110.   if (history > harmless_message) return(1);
  1111.   else return(0);
  1112. }
  1113. @y
  1114. @ On multi-tasking systems like the {\mc AMIGA} it is very convenient to know
  1115. a little bit more about the reasons why a program failed.  The four levels
  1116. of return indicated by the |history| value are very suitable for this
  1117. purpose.  Here, for instance, we pass the operating system a status of~0
  1118. if and only if the run was a complete success.  Any warning or error
  1119. message will result in a higher return value, so {\mc AREXX} scripts can be
  1120. made sensitive to these conditions.
  1121.  
  1122. |__TURBOC__| has another shitty ``feature'' that has to be fixed.
  1123. |return|ing from several |case|s is not possible.  Either always the first
  1124. case is used, or the system is crashed completely.  Really funny.
  1125. @^system dependencies@>
  1126.  
  1127. @d RETURN_OK     0 /* No problems, success */
  1128. @d RETURN_WARN   5 /* A warning only */
  1129. @d RETURN_ERROR 10 /* Something wrong */
  1130. @d RETURN_FAIL  20 /* Complete or severe failure */
  1131.  
  1132. @c
  1133. #ifdef __TURBOC__
  1134. int wrap_up(void) {
  1135.   int return_val;
  1136.  
  1137.   putchar('\n');
  1138.   if (show_stats) print_stats(); /* print statistics about memory usage */
  1139.   @<Print the job |history|@>;
  1140.   @<Remove the temporary file if not already done@>@;
  1141.   switch(history) {
  1142.   case harmless_message: return_val=RETURN_WARN; break;
  1143.   case error_message: return_val=RETURN_ERROR; break;
  1144.   case fatal_message: return_val=RETURN_FAIL; break;
  1145.   default: return_val=RETURN_OK;
  1146.     }
  1147.   return(return_val);
  1148.   }
  1149. #else
  1150. int wrap_up(void) {
  1151.   putchar('\n');
  1152.   if (show_stats) print_stats(); /* print statistics about memory usage */
  1153.   @<Print the job |history|@>;
  1154. #ifdef _AMIGA
  1155.   @<Close the language catalog@>;
  1156. #endif
  1157.   @<Remove the temporary file if not already done@>@;
  1158.   switch(history) {
  1159.   case harmless_message: return(RETURN_WARN); break;
  1160.   case error_message: return(RETURN_ERROR); break;
  1161.   case fatal_message: return(RETURN_FAIL); break;
  1162.   default: return(RETURN_OK);
  1163.     }
  1164.   }
  1165. #endif
  1166. @z
  1167. ------------------------------------------------------------------------------
  1168. TRANSLATION
  1169. @x l.1155
  1170. case spotless: if (show_happiness) printf("(No errors were found.)\n"); break;
  1171. case harmless_message:
  1172.   printf("(Did you see the warning message above?)\n"); break;
  1173. case error_message:
  1174.   printf("(Pardon me, but I think I spotted something wrong.)\n"); break;
  1175. case fatal_message: printf("(That was a fatal error, my friend.)\n");
  1176. @y
  1177. case spotless:
  1178.   if (show_happiness) printf(get_string(MSG_HAPPINESS_CO62)); break;
  1179. case harmless_message:
  1180.   printf(get_string(MSG_WARNING_CO62)); break;
  1181. case error_message:
  1182.   printf(get_string(MSG_ERROR_CO62)); break;
  1183. case fatal_message:
  1184.   printf(get_string(MSG_FATAL_CO62));
  1185. @z
  1186. ------------------------------------------------------------------------------
  1187. ANSI
  1188. @x l.1166
  1189. @<Predec...@>=
  1190. void fatal(), overflow();
  1191. @y
  1192. @<Predec...@>=
  1193. extern void fatal(char *,char *);
  1194. extern void overflow(char *);
  1195. @z
  1196. ------------------------------------------------------------------------------
  1197. ANSI
  1198. @x l.1172
  1199. @c void
  1200. fatal(s,t)
  1201.   char *s,*t;
  1202. @y
  1203. @c void fatal(char *s,char *t)
  1204. @z
  1205. ------------------------------------------------------------------------------
  1206. ANSI
  1207. @x l.1183
  1208. @c void
  1209. overflow(t)
  1210.   char *t;
  1211. @y
  1212. @c void overflow(char *t)
  1213. @z
  1214. ------------------------------------------------------------------------------
  1215. TRANSLATION
  1216. @x l.1187
  1217.   printf("\n! Sorry, %s capacity exceeded",t); fatal("","");
  1218. @y
  1219.   printf(get_string(MSG_FATAL_CO65),t); fatal("","");
  1220. @z
  1221. ------------------------------------------------------------------------------
  1222. TRANSLATION
  1223. @x l.1196
  1224. @d confusion(s) fatal("! This can't happen: ",s)
  1225. @y
  1226. @d confusion(s) fatal(get_string(MSG_FATAL_CO66),s)
  1227. @z
  1228. ------------------------------------------------------------------------------
  1229. EXTENSIONS, SYSTEM DEPENDENCIES
  1230. C and CWEB are `international' languages, so non-English speaking users may
  1231. want to write program documentations in their native language instead of in
  1232. English.  With the \.{+lX} (or \.{-lX} as well) option CWEAVE includes TeX
  1233. macros `Xcwebmac.tex'.  This option works differently than all the others,
  1234. because it takes the rest of the command line argument and prepends it to
  1235. the string ``cwebmac'' in the first line of the TeX output, so you can call
  1236. CWEAVE with the option ``+ldeutsch'' to yield ``\input deutschcwebmac'' in
  1237. the first line.
  1238.  
  1239. The original CWEAVE indents parameter declarations in old-style function
  1240. heads.  If you don't like this, you can typeset them flush left with \.{-i}.
  1241.  
  1242. The original CWEAVE puts extra white space after variable declarations and
  1243. before the first statement in a function block.  If you don't like this,
  1244. you can use the \.{-o} option.  This feature was already mentioned in the
  1245. original documentation, but it was not implemented.
  1246.  
  1247. These changes by Andreas Scherer are based on ideas by Carsten Steger
  1248. provided in his `CWeb 2.0' port from ><> 551 and his `CWeb 2.8' port
  1249. from the electronic nets and on suggestions by Giuseppe Ghibò.  The string
  1250. argument to the `-l' option was suggested by Carsten Steger in a private
  1251. communication in 1994.  Originally this was to be the single character
  1252. following `l', but there would have been collisions between ``dansk''
  1253. and ``deutsch,'' ``espanol'' and ``english,'' and many others.
  1254. @x l.1202
  1255. or flags to be turned on (beginning with |"+"|.
  1256. The following globals are for communicating the user's desires to the rest
  1257. of the program. The various file name variables contain strings with
  1258. the names of those files. Most of the 128 flags are undefined but available
  1259. for future extensions.
  1260.  
  1261. @d show_banner flags['b'] /* should the banner line be printed? */
  1262. @d show_progress flags['p'] /* should progress reports be printed? */
  1263. @d show_stats flags['s'] /* should statistics be printed at end of run? */
  1264. @d show_happiness flags['h'] /* should lack of errors be announced? */
  1265. @y
  1266. or flags to be turned on (beginning with |"+"|).
  1267. The following globals are for communicating the user's desires to the rest
  1268. of the program. The various file name variables contain strings with
  1269. the names of those files. Most of the 256 flags are undefined but available
  1270. for future extensions.
  1271.  
  1272. @d show_banner flags['b'] /* should the banner line be printed? */
  1273. @d show_progress flags['p'] /* should progress reports be printed? */
  1274. @d show_stats flags['s'] /* should statistics be printed at end of run? */
  1275. @d show_happiness flags['h'] /* should lack of errors be announced? */
  1276. @d indent_param_decl flags['i'] /* should formal parameter declarations be indented? */
  1277. @d send_error_messages flags['m'] /* should {\mc AREXX} communication be used? */
  1278. @d order_decl_stmt flags['o'] /* should declarations and statements be separated? */
  1279. @z
  1280. ------------------------------------------------------------------------------
  1281. MEMORY ALLOCATION, OUTPUT
  1282. @x l.1216
  1283. char C_file_name[max_file_name_length]; /* name of |C_file| */
  1284. char tex_file_name[max_file_name_length]; /* name of |tex_file| */
  1285. char idx_file_name[max_file_name_length]; /* name of |idx_file| */
  1286. char scn_file_name[max_file_name_length]; /* name of |scn_file| */
  1287. boolean flags[128]; /* an option for each 7-bit code */
  1288. @y
  1289. char *C_file_name; /* name of |C_file| */
  1290. char *tex_file_name; /* name of |tex_file| */
  1291. char *idx_file_name; /* name of |idx_file| */
  1292. char *scn_file_name; /* name of |scn_file| */
  1293. char *check_file_name; /* name of |check_file| */
  1294. char *use_language; /* prefix of \.{cwebmac.tex} in \TEX/ output */
  1295. boolean flags[256]; /* an option for each 8-bit code */
  1296. @z
  1297. ------------------------------------------------------------------------------
  1298. SYSTEM DEPENDENCIES
  1299. @x l.1226
  1300. @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>=
  1301. show_banner=show_happiness=show_progress=1;
  1302. @y
  1303. @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>=
  1304. show_banner=show_happiness=show_progress=indent_param_decl=order_decl_stmt=1;
  1305. use_language="";
  1306. @^system dependencies@>
  1307. @z
  1308. ------------------------------------------------------------------------------
  1309. SYSTEM DEPENDENCIES
  1310. @x l.1238
  1311. An omitted change file argument means that |"/dev/null"| should be used,
  1312. when no changes are desired.
  1313. @y
  1314. An omitted change file argument means that |"/dev/null"| or---on non-\UNIX/
  1315. systems the contents of the compile-time variable |_DEV_NULL|---should be
  1316. used, when no changes are desired.
  1317. @z
  1318. ------------------------------------------------------------------------------
  1319. ANSI
  1320. @x l.1244
  1321. @<Pred...@>=
  1322. void scan_args();
  1323. @y
  1324. @<Pred...@>=
  1325. static void scan_args(void);@/
  1326. @z
  1327. ------------------------------------------------------------------------------
  1328. ANSI
  1329. @x l.1248
  1330. void
  1331. scan_args()
  1332. @y
  1333. static void scan_args(void)
  1334. @z
  1335. ------------------------------------------------------------------------------
  1336. SYSTEM DEPENDENCIES
  1337. @x l.1262
  1338.       while (*s) {
  1339.         if (*s=='.') dot_pos=s++;
  1340.         else if (*s=='/') dot_pos=NULL,name_pos=++s;
  1341.         else s++;
  1342.       }
  1343. @y
  1344.       while (*s) {
  1345.         if (*s=='.') dot_pos=s++;
  1346.         else if (*s==DIR_SEPARATOR || *s==DEVICE_SEPARATOR || *s=='/')
  1347.           dot_pos=NULL,name_pos=++s;
  1348.         else s++;
  1349.       }
  1350. @^system dependencies@>
  1351. @z
  1352. ------------------------------------------------------------------------------
  1353. SYSTEM DEPENDENCIES
  1354. @x l.1275
  1355.   if (found_change<=0) strcpy(change_file_name,"/dev/null");
  1356. @y
  1357. #ifdef _DEV_NULL
  1358.   if (found_change<=0) strcpy(change_file_name,_DEV_NULL);
  1359. #else
  1360.   if (found_change<=0) strcpy(change_file_name,"/dev/null");
  1361. #endif
  1362. @^system dependencies@>
  1363. @z
  1364. ------------------------------------------------------------------------------
  1365. TRANSLATION
  1366. @x l.1329
  1367.         fatal("! Output file name should end with .tex\n",*argv);
  1368. @y
  1369.         fatal(get_string(MSG_FATAL_CO73),*argv);
  1370. @z
  1371. ------------------------------------------------------------------------------
  1372. SYSTEM DEPENDENCIES, TRANSLATION
  1373. @x l.1345
  1374.   for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
  1375.     flags[*dot_pos]=flag_change;
  1376. @y
  1377.   for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
  1378.     if(*dot_pos=='l') {
  1379.        use_language=++dot_pos;
  1380.        break;
  1381.        }
  1382.     else
  1383.       flags[*dot_pos]=flag_change;
  1384. @^system dependencies@>
  1385. @z
  1386. ------------------------------------------------------------------------------
  1387. SYSTEM DEPENDENCIES, TRANSLATION
  1388. When called with no arguments CTANGLE and CWEAVE provide a list of options.
  1389. @x l.1349
  1390. @ @<Print usage error message and quit@>=
  1391. {
  1392. if (program==ctangle)
  1393.   fatal(
  1394. "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
  1395.    ,"");
  1396. @.Usage:@>
  1397. else fatal(
  1398. "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
  1399.    ,"");
  1400. }
  1401. @y
  1402. @ @<Print usage error message and quit@>=
  1403. {
  1404. #ifdef _AMIGA
  1405. if (program==ctangle)
  1406.   fatal(get_string(MSG_FATAL_CO75_1),"");
  1407. else fatal(get_string(MSG_FATAL_CO75_3),"");
  1408. #else
  1409. if (program==ctangle)
  1410.   fatal(get_string(MSG_FATAL_CO75_2),"");
  1411. else fatal(get_string(MSG_FATAL_CO75_4),"");
  1412. #endif
  1413. }
  1414. @.Usage:@>
  1415. @^system dependencies@>
  1416. @z
  1417. ------------------------------------------------------------------------------
  1418. TRANSLATION
  1419. @x l.1361
  1420. @ @<Complain about arg...@>= fatal("! Filename too long\n", *argv);
  1421. @y
  1422. @ @<Complain about arg...@>= fatal(get_string(MSG_FATAL_CO76), *argv);
  1423. @z
  1424. ------------------------------------------------------------------------------
  1425. OUTPUT
  1426. @x l.1371
  1427. FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
  1428. @y
  1429. FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
  1430. FILE *check_file; /* temporary output file */
  1431. @z
  1432. ------------------------------------------------------------------------------
  1433. TRANSLATION, OUTPUT
  1434. @x l.1374
  1435. @ @<Scan arguments and open output files@>=
  1436. scan_args();
  1437. if (program==ctangle) {
  1438.   if ((C_file=fopen(C_file_name,"w"))==NULL)
  1439.     fatal("! Cannot open output file ", C_file_name);
  1440. @.Cannot open output file@>
  1441. }
  1442. else {
  1443.   if ((tex_file=fopen(tex_file_name,"w"))==NULL)
  1444.     fatal("! Cannot open output file ", tex_file_name);
  1445. }
  1446. @y
  1447. @ @<Scan arguments and open output files@>=
  1448. scan_args();
  1449. tmpnam(check_file_name);
  1450. if(strrchr(check_file_name,DEVICE_SEPARATOR))
  1451.   check_file_name=strrchr(check_file_name,DEVICE_SEPARATOR)+1;
  1452. if (program==ctangle) {
  1453.   if ((C_file=fopen(check_file_name,"w"))==NULL)
  1454.     fatal(get_string(MSG_FATAL_CO78), check_file_name);
  1455. @.Cannot open output file@>
  1456. }
  1457. else {
  1458.   if ((tex_file=fopen(check_file_name,"w"))==NULL)
  1459.     fatal(get_string(MSG_FATAL_CO78), check_file_name);
  1460. }
  1461. @z
  1462. ------------------------------------------------------------------------------
  1463. ANSI, OUTPUT, SYSTEM DEPENDENCIES, TRANSLATION
  1464. The `standard' header files are.  Any compiler ignoring them is not.
  1465. @x l.1403
  1466. @ We predeclare several standard system functions here instead of including
  1467. their system header files, because the names of the header files are not as
  1468. standard as the names of the functions. (For example, some \CEE/ environments
  1469. have \.{<string.h>} where others have \.{<strings.h>}.)
  1470.  
  1471. @<Predecl...@>=
  1472. extern int strlen(); /* length of string */
  1473. extern int strcmp(); /* compare strings lexicographically */
  1474. extern char* strcpy(); /* copy one string to another */
  1475. extern int strncmp(); /* compare up to $n$ string characters */
  1476. extern char* strncpy(); /* copy up to $n$ string characters */
  1477.  
  1478. @** Index.
  1479. @y
  1480. @ For string handling we include the {\mc ANSI C} system header file instead
  1481. of predeclaring the standard system functions |strlen|, |strcmp|, |strcpy|,
  1482. |strncmp|, and |strncpy|.
  1483. @^system dependencies@>
  1484.  
  1485. @<Include...@>=
  1486. #include <string.h>
  1487.  
  1488. @** Path searching.  By default, \.{CTANGLE} and \.{CWEAVE} are looking
  1489. for include files along the path |CWEBINPUTS|.  By setting the environment
  1490. variable of the same name to a different search path you can suit your
  1491. personal needs.  The |default_path| defined in the Makefile always is
  1492. appended to any setting of the environment variable, so you don't have
  1493. to repeat the default entries.  The following procedure copies the value
  1494. of the |environment| variable (if any) to the variable |include_path| used
  1495. for path searching and appends the |default_path| string.
  1496.  
  1497. @c
  1498. static boolean set_path(char *default_path,char *environment)
  1499. {
  1500.   char string[max_path_length+2];
  1501.  
  1502.   if(environment) {
  1503.     if(strlen(environment)+strlen(default_path) >= max_path_length) {
  1504.       err_print("! Include path too long"); return(0);
  1505. @.Include path too long@>
  1506.     }
  1507.     else {
  1508.       sprintf(string,"%s%c%s",environment,PATH_SEPARATOR,default_path);
  1509.       strcpy(default_path,string);
  1510.     }
  1511.   }
  1512.   return(1);
  1513. }
  1514.  
  1515. @ The path search algorithm defined in section |@<Try to open...@>|
  1516. needs a few extra variables.  If no string is given in this variable,
  1517. the |define| variable |CWEBINPUTS| (if given in the Makefile) is used
  1518. instead, which holds some sensible paths.
  1519. @^system dependencies@>
  1520.  
  1521. @d max_path_length 4094
  1522.  
  1523. @<Other...@>=
  1524. char *include_path;@/
  1525. char *p, *path_prefix, *next_path_prefix;@/
  1526.  
  1527. @ @<Init...@>=
  1528. alloc_object(include_path,max_path_length+2,char);
  1529. #ifdef CWEBINPUTS
  1530. strcpy(include_path,CWEBINPUTS);
  1531. #endif
  1532.  
  1533. @** Memory allocation. Due to restrictions of most {\mc MS-DOS}-\CEE/ compilers,
  1534. large arrays will be allocated dynamically rather than statically. In the {\mc
  1535. TURBO}-\CEE/ implementation the |farcalloc| function provides a way to allocate
  1536. more than 64~KByte of data. The |allocsafe| function tries to carry out an
  1537. allocation of |nunits| blocks of size |unitsz| by calling |farcalloc| and takes
  1538. a safe method, when this fails: the program will be aborted.
  1539.  
  1540. To deal with such allocated data areas |huge| pointers will be used in this
  1541. implementation.
  1542.  
  1543. The idea of dynamical memory allocation is extended to all internal arrays
  1544. (except the |flags| field) for other operating systems as well.  Especially
  1545. on the {\mc AMIGA} this use very useful in that the programs can be
  1546. compiled in the \.{NEAR} data segment and thus can be made \\{resident}.
  1547.  
  1548. @f far int
  1549. @f huge int
  1550. @f HUGE int
  1551.  
  1552. @<Pred...@>=
  1553. #ifdef __TURBOC__
  1554. void far *allocsafe(unsigned long,unsigned long);
  1555. #endif
  1556. @^system dependencies@>
  1557.  
  1558. @ @c
  1559. #ifdef __TURBOC__
  1560. void far *allocsafe (unsigned long nunits,unsigned long unitsz)
  1561. {
  1562.   void far *p = farcalloc(nunits,unitsz);
  1563.   if (p==NULL) fatal("",get_string(MSG_FATAL_CO85));
  1564. @.Memory allocation failure@>
  1565.   return p;
  1566. }
  1567. #endif
  1568. @^system dependencies@>
  1569.  
  1570. @ @<Include...@>=
  1571. #ifdef __TURBOC__
  1572. #include <alloc.h> /* import |farcalloc| */
  1573. #include <io.h> /* import |write| */
  1574. #endif
  1575. @^system dependencies@>
  1576.  
  1577. @ @<Macro...@>=
  1578. #ifdef __TURBOC__
  1579. #define HUGE huge
  1580. #else
  1581. #define HUGE
  1582. #endif
  1583. @^system dependencies@>
  1584.  
  1585. @ In case of an user break we must take care of the dynamically allocated
  1586. and opened resources like memory segments and system libraries and catalog
  1587. files.  There is no warranty that in such cases the exit code automatically
  1588. frees these resources.  |exit| is not necessarily called after a break.
  1589. {\mc ANSI-C} provides ``interrupt handlers'' for this purpose.
  1590. |catch_break| simply calls |wrap_up| before |exit|ing the aborted program.
  1591. @^system dependencies@>
  1592.  
  1593. @<Set up the event trap@>=
  1594.   if(signal(SIGINT,&catch_break) == SIG_ERR)
  1595.     exit(EXIT_FAILURE); /* Interrupt handler could not be set up. */
  1596.  
  1597. @ The only purpose of the interrupt handler |catch_break| in case of an
  1598. user abort is to call the cleanup routine that takes care of any opened
  1599. system resources.
  1600.  
  1601. @c
  1602. void catch_break(int dummy)
  1603.    {
  1604.    history=fatal_message;
  1605.    exit(wrap_up());
  1606.    }
  1607.  
  1608. @ @<Predec...@>=
  1609. void catch_break(int);
  1610.  
  1611. @ @<Remove the temporary file...@>=
  1612.   if(C_file) fclose(C_file);
  1613.   if(tex_file) fclose(tex_file);
  1614.   if(check_file) fclose(check_file);
  1615.   if(check_file_name) /* Delete the temporary file in case of a break */
  1616.     remove(check_file_name);
  1617.  
  1618. @** Multilinguality.  The {\mc AMIGA} operating system (and maybe some
  1619. other operating systems as well), starting with version~2.1, is inherently
  1620. multilingual.  With the help of system catalogs, any decent program
  1621. interface can be made sensitive to the language the user wants to be
  1622. addressed with.  All terminal output strings were located and replaced by
  1623. references to an external array |AppStrings|.  The English defaults of
  1624. these strings can be overwritten by the entries of translated catalogs.
  1625. The following include file \.{cweb.h} contains a complete description of
  1626. all strings used in this extended \.{CWEB} system.
  1627. @^system dependencies@>
  1628.  
  1629. @<Include files@>=
  1630. #ifdef _AMIGA
  1631. #include <proto/exec.h>
  1632. #include <proto/locale.h>
  1633. @#
  1634. struct Library *LocaleBase=NULL; /* pointer to the locale library */
  1635. struct Catalog *catalog=NULL; /* pointer to the external catalog */
  1636. int i; /* global counter for list of strings */
  1637. #else /* non-{\mc AMIGA} systems don't know about \.{<exec/types.h>} */
  1638. typedef long int LONG; /* excerpt from \.{<exec/types.h>} */
  1639. typedef char * STRPTR; /* ditto, but \UNIX/ says it's signed. */
  1640. #define EXEC_TYPES_H 1 /* don't include \.{<exec/types.h>} in \.{"cweb.h"} */
  1641. #endif
  1642. @#
  1643. #define STRINGARRAY 1 /* include the string array |AppStrings| for real */
  1644. #define get_string(n) AppStrings[n].as_Str /* reference string $n$ */
  1645. @#
  1646. #include "cweb.h"
  1647.  
  1648. @ Version~2.1 or higher of the {\mc AMIGA} operating system (represented as
  1649. internal version~38) will replace the complete set of terminal output strings
  1650. by an external translation in accordance to the system default language.
  1651.  
  1652. @<Use catalog translations@>=
  1653.   if(LocaleBase=(struct Library *)OpenLibrary(
  1654.     (unsigned char *)"locale.library",38L)) {
  1655.     if(catalog=OpenCatalog(NULL,"cweb.catalog",
  1656.       OC_BuiltInLanguage,"english",TAG_DONE)) {
  1657.       for(i=MSG_ERROR_CO9; i<=MSG_STATS_CW248_6; ++i)
  1658.         AppStrings[i].as_Str=GetCatalogStr(catalog,i,AppStrings[i].as_Str);
  1659.       }
  1660.     }
  1661.  
  1662. @ It is essential to close the pointer references to the language catalog
  1663. and to the system library before shutting down the program itself.
  1664. @^system dependencies@>
  1665.  
  1666. @<Close the language catalog@>=
  1667.   if(LocaleBase) {
  1668.     CloseCatalog(catalog);
  1669.     CloseLibrary(LocaleBase);
  1670.     }
  1671.  
  1672. @** AREXX communication.  In case of an error we want to have a common
  1673. interface used by \.{CWEB} and the \CEE/ compiler in the same way.  For
  1674. the {\mc AMIGA} this is \.{SCMSG}, the message browser of the {\mc SAS/C}
  1675. development system.  This program has an {\mc AREXX} port and can be
  1676. addressed by other applications like \.{CTANGLE} and \.{CWEAVE} with
  1677. the help of the routines described in this part of the program.
  1678. (I admit to have shamelessly borrowed code from the Pas\TEX/
  1679. implementation of \.{dvips}~5.47 by Georg He{\ss}mann.)
  1680. To make use of this feature it is necessary (besides having an
  1681. {\mc AMIGA}) to include a few system dependent header files.
  1682. @^system dependencies@>
  1683.  
  1684. @<Include files@>=
  1685. #ifdef _AMIGA
  1686. #include <proto/dos.h>
  1687. #include <proto/rexxsyslib.h>
  1688. #endif
  1689.  
  1690. @ A list of declarations and variables is added.  Most of these are
  1691. globally defined because the initialization of the message port is done
  1692. outside these local routines.
  1693. @^system dependencies@>
  1694.  
  1695. @<Other...@>=
  1696. #ifdef _AMIGA
  1697. long result = RETURN_FAIL;
  1698. char msg_string[BUFSIZ];
  1699. char pth_buffer[BUFSIZ];
  1700. char cur_buffer[BUFSIZ];
  1701. @#
  1702. struct RexxMsg *rm;
  1703. struct MsgPort *rp;
  1704. @#
  1705. #define MSGPORT  "SC_SCMSG"
  1706. #define PORTNAME "CWEBPORT"
  1707. #define RXEXTENS "rexx"
  1708. #endif
  1709.  
  1710. @ This function addresses the message browser of the {\mc SAS/C} system by
  1711. means of its {\mc AREXX} communication port.
  1712. @^system dependencies@>
  1713.  
  1714. @c
  1715. #ifdef _AMIGA
  1716. static int PutRexxMsg(struct MsgPort *mp, long action,@|
  1717.   STRPTR arg0, struct RexxMsg *arg1)
  1718.   {
  1719.   if ((rm = CreateRexxMsg(mp, (unsigned char *)RXEXTENS, @|
  1720.       (unsigned char *)mp->mp_Node.ln_Name)) != NULL) {
  1721.     rm->rm_Action  = action;
  1722.     rm->rm_Args[0] = arg0;
  1723.     rm->rm_Args[1] = (STRPTR)arg1;
  1724.  
  1725.     Forbid(); /* Disable multitasking. */
  1726.     if ((rp = FindPort((unsigned char *)MSGPORT)) != NULL)
  1727.       PutMsg(rp, (struct Message *)rm);
  1728.     Permit(); /* Enable multitasking. */
  1729.  
  1730.     if (rp == NULL) /* Sorry, message browser not found. */
  1731.       DeleteRexxMsg(rm);
  1732.   }
  1733.   return(rm != NULL && rp != NULL);
  1734. }
  1735. #endif
  1736.  
  1737. @ This function is the ``interface'' between \.{CWEB} and {\mc AREXX}\null.
  1738. The first argument is a string containing a full line of text to be sent to
  1739. the browser.  The second argument returns the transmission result.
  1740. @^system dependencies@>
  1741.  
  1742. @c
  1743. #ifdef _AMIGA
  1744. int __stdargs call_rexx(char *str, long *result)
  1745. {
  1746.   char *arg;
  1747.   struct MsgPort *mp;
  1748.   struct RexxMsg *rm, *rm2;
  1749.   int ret = FALSE;
  1750.   int pend;
  1751.  
  1752.   if (!(RexxSysBase = OpenLibrary((unsigned char *)RXSNAME, 0L)))
  1753.     return(ret);
  1754.  
  1755.   Forbid(); /* Disable multitasking. */
  1756.   if (FindPort((unsigned char *)PORTNAME) == NULL)
  1757.     mp = CreatePort(PORTNAME, 0L);
  1758.   Permit(); /* Enable multitasking. */
  1759.  
  1760.   if (mp != NULL) {
  1761.     if ((arg = (char *)CreateArgstring(
  1762.         (unsigned char *)str, strlen(str))) != NULL) {
  1763.       if (PutRexxMsg(mp, RXCOMM | RXFF_STRING, arg, NULL)) {
  1764.         for (pend = 1; pend != 0; )
  1765.           if (WaitPort(mp) != NULL)
  1766.             while ((rm = (struct RexxMsg *)GetMsg(mp)) != NULL)
  1767.               if (rm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
  1768.                 ret = TRUE;
  1769.                 *result = rm->rm_Result1;
  1770.                 if ((rm2 = (struct RexxMsg *)rm->rm_Args[1]) != NULL) {
  1771.                   rm2->rm_Result1 = rm->rm_Result1;
  1772.                   rm2->rm_Result2 = 0;
  1773.                   ReplyMsg((struct Message *)rm2);
  1774.                 }
  1775.                 DeleteRexxMsg(rm);
  1776.                 pend--;
  1777.               }
  1778.               else {
  1779.                 rm->rm_Result2 = 0;
  1780.                 if (PutRexxMsg(mp, rm->rm_Action, rm->rm_Args[0], rm))
  1781.                   pend++;
  1782.                 else {
  1783.                   rm->rm_Result1 = RETURN_FAIL;
  1784.                   ReplyMsg((struct Message *)rm);
  1785.                 }
  1786.               }
  1787.       }
  1788.       DeleteArgstring((unsigned char *)arg);
  1789.     }
  1790.     DeletePort(mp);
  1791.   }
  1792.  
  1793.   CloseLibrary((struct Library *)RexxSysBase);
  1794.  
  1795.   return(ret);
  1796. }
  1797. #endif
  1798.  
  1799. @ The prototypes for these two new functions are added to the common list.
  1800. @^system dependencies@>
  1801.  
  1802. @<Predecl...@>=
  1803. #ifdef _AMIGA
  1804. static int PutRexxMsg(struct MsgPort *,long,STRPTR,struct RexxMsg *);
  1805. int __stdargs call_rexx(char *,long *);
  1806. #endif
  1807.  
  1808. @ Before we can send any signal to the message browser we have to make sure
  1809. that the receiving port is active.  Possibly a call to \.{scmsg} will
  1810. suffice.  If it is not there, any attempt to send a message will fail.
  1811.  
  1812. You can control the behaviour of \.{scmsg} via the external environment
  1813. variable \.{SCMSGOPT} which may contain any legal command line options as
  1814. described in the documentation provided by {\mc SAS}~Institute.
  1815. The display window with the error messages will not appear if you supply
  1816. \.{scmsg} with its \.{rexxonly} option.  If you want to see every message
  1817. on your screen, replace this option with \.{hidden}.  The first error
  1818. message received by \.{scmsg} will open the output window.  The very first
  1819. message for the browser initializes its database for the current web file.
  1820. Any pending entries will be destroyed before new ones are added.
  1821. @^system dependencies@>
  1822.  
  1823. @<Set up the {\mc AREXX} communication@>=
  1824. if(send_error_messages) {
  1825.   Forbid(); /* Disable multitasking. */
  1826.   if ((rp = FindPort((unsigned char *)MSGPORT)) != NULL);
  1827.     /* Check for browser port. */
  1828.   Permit(); /* Enable multitasking. */
  1829.  
  1830.   if(!rp) { /* Make sure, the browser is active. */
  1831.     strcpy(msg_string,"run <nil: >nil: scmsg ");
  1832.     strcat(msg_string,getenv("SCMSGOPT")); /* Add browser options. */
  1833.     system(msg_string);
  1834.     }
  1835.  
  1836.   if(GetCurrentDirName(cur_buffer,BUFSIZ) && @|
  1837.     AddPart(cur_buffer,web_file_name,BUFSIZ)) {
  1838.     sprintf(msg_string,"newbld \"%s\"",cur_buffer);
  1839.     call_rexx(msg_string,&result); /* Ignore the results. */
  1840.     }
  1841.   }
  1842.  
  1843. @ There are three types of \.{CWEB} errors reported to the message browser.
  1844. For completeness we give them the numbers~997 to~999.  The first one refers
  1845. to errors in the active change file.  If you click on the error line in the
  1846. browser window, your system editor will take you to the offending line in
  1847. the change file (given the communication between the browser and your
  1848. editor is properly set up).  There is a slight difficulty when entering
  1849. file names into the error message; the browser expects complete path names
  1850. and we have to add them more or less by~hand.
  1851. @^system dependencies@>
  1852.  
  1853. @<Report an error in the change file@>={
  1854.   printf(get_string(MSG_ERROR_CO59_1), change_line);
  1855. #ifdef _AMIGA
  1856.   if(send_error_messages) {
  1857.  
  1858.     if(GetCurrentDirName(cur_buffer,BUFSIZ) && @|
  1859.       AddPart(cur_buffer,web_file_name,BUFSIZ) && @|
  1860.  
  1861.       GetCurrentDirName(pth_buffer,BUFSIZ) && @|
  1862.       AddPart(pth_buffer,change_file_name,BUFSIZ))
  1863.  
  1864.       sprintf(msg_string,"newmsg \"%s\" \"%s\" %d 0 \"\" 0 Error 997 %s",@|
  1865.         cur_buffer,pth_buffer,change_line,s);
  1866.  
  1867.     else strcpy(msg_string,"\0");
  1868.     }
  1869. #endif
  1870.   }
  1871.  
  1872. @ The next type of error occurs in the web file itself, so the current file
  1873. is the same as the offending file.  We have to create the full name only once.
  1874. @^system dependencies@>
  1875.  
  1876. @<Report an error in the web file@>={
  1877.   printf(get_string(MSG_ERROR_CO59_2), cur_line);
  1878. #ifdef _AMIGA
  1879.   if(send_error_messages) {
  1880.  
  1881.     if(GetCurrentDirName(cur_buffer,BUFSIZ) && @|
  1882.       AddPart(cur_buffer,cur_file_name,BUFSIZ))
  1883.  
  1884.       sprintf(msg_string,"newmsg \"%s\" \"%s\" %d 0 \"\" 0 Error 998 %s",@|
  1885.         cur_buffer,cur_buffer,cur_line,s);
  1886.  
  1887.     else strcpy(msg_string,"\0");
  1888.     }
  1889. #endif
  1890.   }
  1891.  
  1892. @ The error with the highest number is also the most subtle type.  It
  1893. occurs inside an include file, so we have to distinguish between the web
  1894. file and the offending file.
  1895. @^system dependencies@>
  1896.  
  1897. @<Report an error in an include file@>={
  1898.   printf(get_string(MSG_ERROR_CO59_3), cur_line, cur_file_name);
  1899. #ifdef _AMIGA
  1900.   if(send_error_messages) {
  1901.  
  1902.     if(GetCurrentDirName(cur_buffer,BUFSIZ) && @|
  1903.       AddPart(cur_buffer,cur_file_name,BUFSIZ) && @|
  1904.  
  1905.       GetCurrentDirName(pth_buffer,BUFSIZ) && @|
  1906.       AddPart(pth_buffer,web_file_name,BUFSIZ))
  1907.  
  1908.       sprintf(msg_string,"newmsg \"%s\" \"%s\" %d 0 \"\" 0 Error 999 %s",@|
  1909.         pth_buffer,cur_buffer,cur_line,s);
  1910.  
  1911.     else strcpy(msg_string,"\0");
  1912.     }
  1913. #endif
  1914.   }
  1915.  
  1916. @ In the three sections above we simply created a string holding the full
  1917. entry line which is handed over to the message browser by calling our
  1918. |call_rexx| routine.  The boolean return value is ignored.
  1919. @^system dependencies@>
  1920.  
  1921. @<Put the error message in the browser@>=
  1922.   if(send_error_messages && msg_string)
  1923.     call_rexx(msg_string,&result); /* Ignore the results. */
  1924.  
  1925. @** Function declarations. Here are declarations, conforming to {\mc ANSI~C},
  1926. of all functions in this code that appear in |"common.h"| and thus should
  1927. agree with \.{CTANGLE} and \.{CWEAVE}.
  1928.  
  1929. @<Predecl...@>=
  1930. int get_line(void);@/
  1931. name_pointer add_section_name(name_pointer,int,char *,char *,int);@/
  1932. name_pointer id_lookup(char *,char *,char);@/
  1933. name_pointer section_lookup(char *,char *,int);
  1934. void check_complete(void);@/
  1935. void common_init(void);@/
  1936. void extend_section_name(name_pointer,char *,char *,int);@/
  1937. void print_prefix_name(name_pointer);@/
  1938. void print_section_name(name_pointer);@/
  1939. void reset_input(void);@/
  1940. void sprint_section_name(char *,name_pointer);
  1941.  
  1942. @ The following functions are private to |"common.w"|.
  1943.  
  1944. @<Predecl...@>=
  1945. static boolean set_path(char *,char *);@/
  1946. static int input_ln(FILE *);@/
  1947. static int web_strcmp(char HUGE *,int,char HUGE *,int);@/
  1948. static void check_change(void);@/
  1949. static void prime_the_change_buffer(void);
  1950.  
  1951. @** Index.
  1952. @z
  1953. ------------------------------------------------------------------------------
  1954.