home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd2.bin / bbs / dev / cweb-3.2.lha / CWeb / common.ch < prev    next >
Text File  |  1994-08-12  |  65KB  |  1,892 lines

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