Move free_all_objfiles to program_space
[deliverable/binutils-gdb.git] / bfd / doc / chew.c
CommitLineData
252b5132 1/* chew
82704155 2 Copyright (C) 1990-2019 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by steve chamberlain @cygnus
4
cd123cb7 5 This file is part of BFD, the Binary File Descriptor library.
252b5132 6
cd123cb7
NC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
252b5132 11
cd123cb7
NC
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
252b5132 16
cd123cb7
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132
RH
21
22/* Yet another way of extracting documentation from source.
23 No, I haven't finished it yet, but I hope you people like it better
24 than the old way
d70910e8 25
252b5132
RH
26 sac
27
28 Basically, this is a sort of string forth, maybe we should call it
29 struth?
30
31 You define new words thus:
32 : <newword> <oldwords> ;
33
34*/
35
36/* Primitives provided by the program:
37
38 Two stacks are provided, a string stack and an integer stack.
39
40 Internal state variables:
41 internal_wanted - indicates whether `-i' was passed
42 internal_mode - user-settable
43
44 Commands:
45 push_text
46 ! - pop top of integer stack for address, pop next for value; store
47 @ - treat value on integer stack as the address of an integer; push
48 that integer on the integer stack after popping the "address"
49 hello - print "hello\n" to stdout
50 stdout - put stdout marker on TOS
51 stderr - put stderr marker on TOS
52 print - print TOS-1 on TOS (eg: "hello\n" stdout print)
53 skip_past_newline
54 catstr - fn icatstr
55 copy_past_newline - append input, up to and including newline into TOS
56 dup - fn other_dup
57 drop - discard TOS
58 idrop - ditto
59 remchar - delete last character from TOS
60 get_stuff_in_command
61 do_fancy_stuff - translate <<foo>> to @code{foo} in TOS
62 bulletize - if "o" lines found, prepend @itemize @bullet to TOS
63 and @item to each "o" line; append @end itemize
64 courierize - put @example around . and | lines, translate {* *} { }
65 exit - fn chew_exit
66 swap
67 outputdots - strip out lines without leading dots
68 paramstuff - convert full declaration into "PARAMS" form if not already
69 maybecatstr - do catstr if internal_mode == internal_wanted, discard
70 value in any case
71 translatecomments - turn {* and *} into comment delimiters
72 kill_bogus_lines - get rid of extra newlines
73 indent
74 internalmode - pop from integer stack, set `internalmode' to that value
75 print_stack_level - print current stack depth to stderr
76 strip_trailing_newlines - go ahead, guess...
77 [quoted string] - push string onto string stack
78 [word starting with digit] - push atol(str) onto integer stack
79
80 A command must be all upper-case, and alone on a line.
81
82 Foo. */
83
f742faa6 84#include "ansidecl.h"
252b5132
RH
85#include <assert.h>
86#include <stdio.h>
87#include <ctype.h>
d4ad1cbf 88#include <stdlib.h>
99356e90 89#include <string.h>
252b5132
RH
90
91#define DEF_SIZE 5000
92#define STACK 50
93
94int internal_wanted;
95int internal_mode;
96
97int warning;
98
d70910e8 99/* Here is a string type ... */
252b5132 100
d70910e8 101typedef struct buffer
252b5132
RH
102{
103 char *ptr;
104 unsigned long write_idx;
105 unsigned long size;
106} string_type;
107
252b5132
RH
108#ifdef __STDC__
109static void init_string_with_size (string_type *, unsigned int);
110static void init_string (string_type *);
111static int find (string_type *, char *);
112static void write_buffer (string_type *, FILE *);
113static void delete_string (string_type *);
114static char *addr (string_type *, unsigned int);
115static char at (string_type *, unsigned int);
116static void catchar (string_type *, int);
117static void overwrite_string (string_type *, string_type *);
118static void catbuf (string_type *, char *, unsigned int);
119static void cattext (string_type *, char *);
120static void catstr (string_type *, string_type *);
5375ec41 121static void die (char *);
252b5132
RH
122#endif
123
256d98af
KH
124static void
125init_string_with_size (buffer, size)
126 string_type *buffer;
127 unsigned int size;
252b5132 128{
d70910e8
KH
129 buffer->write_idx = 0;
130 buffer->size = size;
e3ad91e3 131 buffer->ptr = (char *) malloc (size);
252b5132
RH
132}
133
256d98af
KH
134static void
135init_string (buffer)
136 string_type *buffer;
252b5132 137{
d70910e8 138 init_string_with_size (buffer, DEF_SIZE);
252b5132
RH
139}
140
256d98af
KH
141static int
142find (str, what)
143 string_type *str;
144 char *what;
252b5132 145{
d70910e8
KH
146 unsigned int i;
147 char *p;
148 p = what;
149 for (i = 0; i < str->write_idx && *p; i++)
252b5132 150 {
d70910e8
KH
151 if (*p == str->ptr[i])
152 p++;
153 else
154 p = what;
252b5132 155 }
d70910e8 156 return (*p == 0);
252b5132
RH
157}
158
256d98af
KH
159static void
160write_buffer (buffer, f)
161 string_type *buffer;
162 FILE *f;
252b5132 163{
5375ec41
AM
164 if (buffer->write_idx != 0
165 && fwrite (buffer->ptr, buffer->write_idx, 1, f) != 1)
166 die ("cannot write output");
252b5132
RH
167}
168
256d98af
KH
169static void
170delete_string (buffer)
171 string_type *buffer;
252b5132 172{
8a286b63
NC
173 if (buffer->ptr)
174 free (buffer->ptr);
175 buffer->ptr = NULL;
252b5132
RH
176}
177
256d98af
KH
178static char *
179addr (buffer, idx)
180 string_type *buffer;
181 unsigned int idx;
252b5132 182{
d70910e8 183 return buffer->ptr + idx;
252b5132
RH
184}
185
256d98af
KH
186static char
187at (buffer, pos)
188 string_type *buffer;
189 unsigned int pos;
252b5132 190{
d70910e8 191 if (pos >= buffer->write_idx)
252b5132
RH
192 return 0;
193 return buffer->ptr[pos];
194}
195
256d98af
KH
196static void
197catchar (buffer, ch)
198 string_type *buffer;
199 int ch;
252b5132 200{
d70910e8 201 if (buffer->write_idx == buffer->size)
252b5132 202 {
d70910e8 203 buffer->size *= 2;
e3ad91e3 204 buffer->ptr = (char *) realloc (buffer->ptr, buffer->size);
252b5132
RH
205 }
206
d70910e8 207 buffer->ptr[buffer->write_idx++] = ch;
252b5132
RH
208}
209
256d98af
KH
210static void
211overwrite_string (dst, src)
212 string_type *dst;
213 string_type *src;
252b5132 214{
d70910e8
KH
215 free (dst->ptr);
216 dst->size = src->size;
217 dst->write_idx = src->write_idx;
218 dst->ptr = src->ptr;
252b5132
RH
219}
220
256d98af
KH
221static void
222catbuf (buffer, buf, len)
223 string_type *buffer;
224 char *buf;
225 unsigned int len;
252b5132
RH
226{
227 if (buffer->write_idx + len >= buffer->size)
228 {
229 while (buffer->write_idx + len >= buffer->size)
230 buffer->size *= 2;
e3ad91e3 231 buffer->ptr = (char *) realloc (buffer->ptr, buffer->size);
252b5132
RH
232 }
233 memcpy (buffer->ptr + buffer->write_idx, buf, len);
234 buffer->write_idx += len;
235}
236
256d98af
KH
237static void
238cattext (buffer, string)
239 string_type *buffer;
240 char *string;
252b5132
RH
241{
242 catbuf (buffer, string, (unsigned int) strlen (string));
243}
244
256d98af
KH
245static void
246catstr (dst, src)
247 string_type *dst;
248 string_type *src;
252b5132
RH
249{
250 catbuf (dst, src->ptr, src->write_idx);
251}
252
d70910e8 253static unsigned int
256d98af
KH
254skip_white_and_stars (src, idx)
255 string_type *src;
256 unsigned int idx;
252b5132
RH
257{
258 char c;
d70910e8 259 while ((c = at (src, idx)),
252b5132
RH
260 isspace ((unsigned char) c)
261 || (c == '*'
262 /* Don't skip past end-of-comment or star as first
263 character on its line. */
d70910e8
KH
264 && at (src, idx +1) != '/'
265 && at (src, idx -1) != '\n'))
252b5132
RH
266 idx++;
267 return idx;
268}
269
aaffae57
DE
270static unsigned int
271skip_past_newline_1 (ptr, idx)
272 string_type *ptr;
273 unsigned int idx;
274{
275 while (at (ptr, idx)
276 && at (ptr, idx) != '\n')
277 idx++;
278 if (at (ptr, idx) == '\n')
279 return idx + 1;
280 return idx;
281}
282
252b5132
RH
283/***********************************************************************/
284
252b5132
RH
285string_type stack[STACK];
286string_type *tos;
287
288unsigned int idx = 0; /* Pos in input buffer */
289string_type *ptr; /* and the buffer */
290typedef void (*stinst_type)();
291stinst_type *pc;
292stinst_type sstack[STACK];
293stinst_type *ssp = &sstack[0];
294long istack[STACK];
295long *isp = &istack[0];
296
297typedef int *word_type;
298
252b5132
RH
299struct dict_struct
300{
d70910e8
KH
301 char *word;
302 struct dict_struct *next;
303 stinst_type *code;
304 int code_length;
305 int code_end;
306 int var;
252b5132 307};
d70910e8 308
252b5132 309typedef struct dict_struct dict_type;
d70910e8 310
252b5132
RH
311static void
312die (msg)
313 char *msg;
314{
315 fprintf (stderr, "%s\n", msg);
316 exit (1);
317}
318
319static void
320check_range ()
321{
322 if (tos < stack)
323 die ("underflow in string stack");
324 if (tos >= stack + STACK)
325 die ("overflow in string stack");
326}
327
328static void
329icheck_range ()
330{
331 if (isp < istack)
332 die ("underflow in integer stack");
333 if (isp >= istack + STACK)
334 die ("overflow in integer stack");
335}
336
337#ifdef __STDC__
338static void exec (dict_type *);
339static void call (void);
340static void remchar (void), strip_trailing_newlines (void), push_number (void);
341static void push_text (void);
342static void remove_noncomments (string_type *, string_type *);
343static void print_stack_level (void);
344static void paramstuff (void), translatecomments (void);
345static void outputdots (void), courierize (void), bulletize (void);
346static void do_fancy_stuff (void);
347static int iscommand (string_type *, unsigned int);
348static int copy_past_newline (string_type *, unsigned int, string_type *);
349static void icopy_past_newline (void), kill_bogus_lines (void), indent (void);
350static void get_stuff_in_command (void), swap (void), other_dup (void);
351static void drop (void), idrop (void);
352static void icatstr (void), skip_past_newline (void), internalmode (void);
353static void maybecatstr (void);
354static char *nextword (char *, char **);
355dict_type *lookup_word (char *);
356static void perform (void);
357dict_type *newentry (char *);
358unsigned int add_to_definition (dict_type *, stinst_type);
359void add_intrinsic (char *, void (*)());
360void add_var (char *);
361void compile (char *);
362static void bang (void);
363static void atsign (void);
364static void hello (void);
365static void stdout_ (void);
366static void stderr_ (void);
367static void print (void);
368static void read_in (string_type *, FILE *);
369static void usage (void);
370static void chew_exit (void);
371#endif
372
256d98af
KH
373static void
374exec (word)
375 dict_type *word;
252b5132
RH
376{
377 pc = word->code;
d70910e8
KH
378 while (*pc)
379 (*pc) ();
252b5132 380}
d70910e8 381
9ee6f9cc
AM
382static void
383call ()
d70910e8
KH
384{
385 stinst_type *oldpc = pc;
386 dict_type *e;
387 e = (dict_type *) (pc[1]);
388 exec (e);
389 pc = oldpc + 2;
252b5132
RH
390}
391
9ee6f9cc
AM
392static void
393remchar ()
252b5132
RH
394{
395 if (tos->write_idx)
d70910e8 396 tos->write_idx--;
252b5132
RH
397 pc++;
398}
399
400static void
401strip_trailing_newlines ()
402{
403 while ((isspace ((unsigned char) at (tos, tos->write_idx - 1))
404 || at (tos, tos->write_idx - 1) == '\n')
405 && tos->write_idx > 0)
406 tos->write_idx--;
407 pc++;
408}
409
9ee6f9cc
AM
410static void
411push_number ()
252b5132 412{
d70910e8
KH
413 isp++;
414 icheck_range ();
415 pc++;
416 *isp = (long) (*pc);
417 pc++;
252b5132
RH
418}
419
9ee6f9cc
AM
420static void
421push_text ()
252b5132 422{
d70910e8
KH
423 tos++;
424 check_range ();
425 init_string (tos);
426 pc++;
427 cattext (tos, *((char **) pc));
428 pc++;
252b5132
RH
429}
430
252b5132
RH
431/* This function removes everything not inside comments starting on
432 the first char of the line from the string, also when copying
433 comments, removes blank space and leading *'s.
434 Blank lines are turned into one blank line. */
435
d70910e8
KH
436static void
437remove_noncomments (src, dst)
256d98af
KH
438 string_type *src;
439 string_type *dst;
252b5132 440{
d70910e8
KH
441 unsigned int idx = 0;
442
443 while (at (src, idx))
252b5132 444 {
d70910e8
KH
445 /* Now see if we have a comment at the start of the line. */
446 if (at (src, idx) == '\n'
447 && at (src, idx + 1) == '/'
448 && at (src, idx + 2) == '*')
252b5132 449 {
d70910e8
KH
450 idx += 3;
451
452 idx = skip_white_and_stars (src, idx);
453
454 /* Remove leading dot */
455 if (at (src, idx) == '.')
456 idx++;
457
458 /* Copy to the end of the line, or till the end of the
459 comment. */
460 while (at (src, idx))
252b5132 461 {
d70910e8 462 if (at (src, idx) == '\n')
252b5132 463 {
d70910e8
KH
464 /* end of line, echo and scrape of leading blanks */
465 if (at (src, idx + 1) == '\n')
466 catchar (dst, '\n');
467 catchar (dst, '\n');
468 idx++;
469 idx = skip_white_and_stars (src, idx);
252b5132 470 }
d70910e8 471 else if (at (src, idx) == '*' && at (src, idx + 1) == '/')
252b5132 472 {
d70910e8
KH
473 idx += 2;
474 cattext (dst, "\nENDDD\n");
475 break;
252b5132 476 }
d70910e8 477 else
252b5132 478 {
d70910e8
KH
479 catchar (dst, at (src, idx));
480 idx++;
252b5132
RH
481 }
482 }
483 }
d70910e8
KH
484 else
485 idx++;
252b5132
RH
486 }
487}
488
489static void
490print_stack_level ()
491{
13ce3c11
AM
492 fprintf (stderr, "current string stack depth = %ld, ",
493 (long) (tos - stack));
494 fprintf (stderr, "current integer stack depth = %ld\n",
495 (long) (isp - istack));
252b5132
RH
496 pc++;
497}
498
499/* turn:
500 foobar name(stuff);
501 into:
502 foobar
503 name PARAMS ((stuff));
504 and a blank line.
505 */
506
507static void
51240b8d 508paramstuff ()
252b5132 509{
d70910e8
KH
510 unsigned int openp;
511 unsigned int fname;
512 unsigned int idx;
10bfd974 513 unsigned int len;
d70910e8
KH
514 string_type out;
515 init_string (&out);
252b5132 516
c58b9523
AM
517#define NO_PARAMS 1
518
d70910e8 519 /* Make sure that it's not already param'd or proto'd. */
c58b9523
AM
520 if (NO_PARAMS
521 || find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "("))
252b5132 522 {
d70910e8
KH
523 catstr (&out, tos);
524 }
525 else
526 {
527 /* Find the open paren. */
528 for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++)
529 ;
530
531 fname = openp;
532 /* Step back to the fname. */
533 fname--;
534 while (fname && isspace ((unsigned char) at (tos, fname)))
535 fname--;
536 while (fname
537 && !isspace ((unsigned char) at (tos,fname))
538 && at (tos,fname) != '*')
252b5132 539 fname--;
d70910e8
KH
540
541 fname++;
542
10bfd974
KH
543 /* Output type, omitting trailing whitespace character(s), if
544 any. */
545 for (len = fname; 0 < len; len--)
252b5132 546 {
10bfd974 547 if (!isspace ((unsigned char) at (tos, len - 1)))
05c6581e 548 break;
252b5132 549 }
10bfd974
KH
550 for (idx = 0; idx < len; idx++)
551 catchar (&out, at (tos, idx));
252b5132 552
d70910e8
KH
553 cattext (&out, "\n"); /* Insert a newline between type and fnname */
554
10bfd974
KH
555 /* Output function name, omitting trailing whitespace
556 character(s), if any. */
557 for (len = openp; 0 < len; len--)
252b5132 558 {
10bfd974
KH
559 if (!isspace ((unsigned char) at (tos, len - 1)))
560 break;
252b5132 561 }
10bfd974
KH
562 for (idx = fname; idx < len; idx++)
563 catchar (&out, at (tos, idx));
252b5132 564
d70910e8 565 cattext (&out, " PARAMS (");
252b5132 566
10bfd974
KH
567 for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++)
568 catchar (&out, at (tos, idx));
569
d70910e8 570 cattext (&out, ");\n\n");
252b5132 571 }
d70910e8
KH
572 overwrite_string (tos, &out);
573 pc++;
252b5132 574
d70910e8 575}
252b5132
RH
576
577/* turn {*
578 and *} into comments */
579
9ee6f9cc
AM
580static void
581translatecomments ()
252b5132 582{
d70910e8
KH
583 unsigned int idx = 0;
584 string_type out;
585 init_string (&out);
586
587 while (at (tos, idx))
252b5132 588 {
d70910e8 589 if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
252b5132 590 {
d70910e8
KH
591 cattext (&out, "/*");
592 idx += 2;
252b5132 593 }
d70910e8 594 else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
252b5132 595 {
d70910e8
KH
596 cattext (&out, "*/");
597 idx += 2;
252b5132 598 }
d70910e8 599 else
252b5132 600 {
d70910e8
KH
601 catchar (&out, at (tos, idx));
602 idx++;
252b5132
RH
603 }
604 }
605
d70910e8 606 overwrite_string (tos, &out);
252b5132 607
d70910e8 608 pc++;
252b5132
RH
609}
610
252b5132
RH
611/* Mod tos so that only lines with leading dots remain */
612static void
51240b8d 613outputdots ()
252b5132 614{
d70910e8
KH
615 unsigned int idx = 0;
616 string_type out;
617 init_string (&out);
618
619 while (at (tos, idx))
252b5132 620 {
aaffae57
DE
621 /* Every iteration begins at the start of a line. */
622 if (at (tos, idx) == '.')
252b5132
RH
623 {
624 char c;
aaffae57
DE
625
626 idx++;
d70910e8
KH
627
628 while ((c = at (tos, idx)) && c != '\n')
252b5132 629 {
d70910e8 630 if (c == '{' && at (tos, idx + 1) == '*')
252b5132 631 {
d70910e8
KH
632 cattext (&out, "/*");
633 idx += 2;
252b5132 634 }
d70910e8 635 else if (c == '*' && at (tos, idx + 1) == '}')
252b5132 636 {
d70910e8
KH
637 cattext (&out, "*/");
638 idx += 2;
252b5132
RH
639 }
640 else
641 {
d70910e8
KH
642 catchar (&out, c);
643 idx++;
252b5132
RH
644 }
645 }
aaffae57
DE
646 if (c == '\n')
647 idx++;
d70910e8 648 catchar (&out, '\n');
252b5132 649 }
d70910e8 650 else
252b5132 651 {
aaffae57 652 idx = skip_past_newline_1 (tos, idx);
252b5132 653 }
d70910e8 654 }
252b5132 655
d70910e8
KH
656 overwrite_string (tos, &out);
657 pc++;
252b5132
RH
658}
659
660/* Find lines starting with . and | and put example around them on tos */
9ee6f9cc
AM
661static void
662courierize ()
d70910e8
KH
663{
664 string_type out;
665 unsigned int idx = 0;
666 int command = 0;
667
668 init_string (&out);
669
670 while (at (tos, idx))
252b5132 671 {
d70910e8
KH
672 if (at (tos, idx) == '\n'
673 && (at (tos, idx +1 ) == '.'
674 || at (tos, idx + 1) == '|'))
252b5132 675 {
d70910e8
KH
676 cattext (&out, "\n@example\n");
677 do
252b5132 678 {
d70910e8
KH
679 idx += 2;
680
681 while (at (tos, idx) && at (tos, idx) != '\n')
252b5132 682 {
ba994a14
AM
683 if (command > 1)
684 {
685 /* We are inside {} parameters of some command;
686 Just pass through until matching brace. */
687 if (at (tos, idx) == '{')
688 ++command;
689 else if (at (tos, idx) == '}')
690 --command;
691 }
692 else if (command != 0)
693 {
694 if (at (tos, idx) == '{')
695 ++command;
696 else if (!islower ((unsigned char) at (tos, idx)))
697 --command;
698 }
699 else if (at (tos, idx) == '@'
700 && islower ((unsigned char) at (tos, idx + 1)))
701 {
702 ++command;
703 }
704 else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
252b5132 705 {
d70910e8
KH
706 cattext (&out, "/*");
707 idx += 2;
ba994a14 708 continue;
252b5132 709 }
d70910e8 710 else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
252b5132 711 {
d70910e8
KH
712 cattext (&out, "*/");
713 idx += 2;
ba994a14 714 continue;
252b5132 715 }
ba994a14
AM
716 else if (at (tos, idx) == '{'
717 || at (tos, idx) == '}')
252b5132 718 {
ba994a14 719 catchar (&out, '@');
252b5132 720 }
d70910e8 721
ba994a14
AM
722 catchar (&out, at (tos, idx));
723 idx++;
252b5132 724 }
d70910e8
KH
725 catchar (&out, '\n');
726 }
727 while (at (tos, idx) == '\n'
728 && ((at (tos, idx + 1) == '.')
729 || (at (tos, idx + 1) == '|')))
730 ;
731 cattext (&out, "@end example");
252b5132 732 }
d70910e8
KH
733 else
734 {
735 catchar (&out, at (tos, idx));
736 idx++;
252b5132 737 }
d70910e8 738 }
252b5132 739
d70910e8
KH
740 overwrite_string (tos, &out);
741 pc++;
252b5132
RH
742}
743
744/* Finds any lines starting with "o ", if there are any, then turns
745 on @itemize @bullet, and @items each of them. Then ends with @end
746 itemize, inplace at TOS*/
747
9ee6f9cc
AM
748static void
749bulletize ()
252b5132 750{
d70910e8
KH
751 unsigned int idx = 0;
752 int on = 0;
753 string_type out;
754 init_string (&out);
755
756 while (at (tos, idx))
757 {
758 if (at (tos, idx) == '@'
759 && at (tos, idx + 1) == '*')
252b5132 760 {
d70910e8
KH
761 cattext (&out, "*");
762 idx += 2;
252b5132 763 }
d70910e8
KH
764 else if (at (tos, idx) == '\n'
765 && at (tos, idx + 1) == 'o'
766 && isspace ((unsigned char) at (tos, idx + 2)))
767 {
768 if (!on)
252b5132 769 {
d70910e8
KH
770 cattext (&out, "\n@itemize @bullet\n");
771 on = 1;
772
252b5132 773 }
d70910e8
KH
774 cattext (&out, "\n@item\n");
775 idx += 3;
776 }
777 else
778 {
779 catchar (&out, at (tos, idx));
780 if (on && at (tos, idx) == '\n'
781 && at (tos, idx + 1) == '\n'
782 && at (tos, idx + 2) != 'o')
252b5132 783 {
d70910e8
KH
784 cattext (&out, "@end itemize");
785 on = 0;
252b5132 786 }
d70910e8
KH
787 idx++;
788
252b5132 789 }
d70910e8
KH
790 }
791 if (on)
252b5132 792 {
d70910e8
KH
793 cattext (&out, "@end itemize\n");
794 }
252b5132 795
d70910e8
KH
796 delete_string (tos);
797 *tos = out;
798 pc++;
252b5132
RH
799}
800
801/* Turn <<foo>> into @code{foo} in place at TOS*/
252b5132 802
9ee6f9cc
AM
803static void
804do_fancy_stuff ()
252b5132 805{
d70910e8
KH
806 unsigned int idx = 0;
807 string_type out;
808 init_string (&out);
809 while (at (tos, idx))
252b5132 810 {
d70910e8
KH
811 if (at (tos, idx) == '<'
812 && at (tos, idx + 1) == '<'
813 && !isspace ((unsigned char) at (tos, idx + 2)))
252b5132 814 {
d70910e8
KH
815 /* This qualifies as a << startup. */
816 idx += 2;
817 cattext (&out, "@code{");
818 while (at (tos, idx)
819 && at (tos, idx) != '>' )
252b5132 820 {
d70910e8
KH
821 catchar (&out, at (tos, idx));
822 idx++;
823
252b5132 824 }
d70910e8
KH
825 cattext (&out, "}");
826 idx += 2;
252b5132 827 }
d70910e8 828 else
252b5132 829 {
d70910e8
KH
830 catchar (&out, at (tos, idx));
831 idx++;
252b5132
RH
832 }
833 }
d70910e8
KH
834 delete_string (tos);
835 *tos = out;
836 pc++;
837
252b5132 838}
d70910e8
KH
839
840/* A command is all upper case,and alone on a line. */
841
842static int
256d98af
KH
843iscommand (ptr, idx)
844 string_type *ptr;
845 unsigned int idx;
252b5132 846{
d70910e8
KH
847 unsigned int len = 0;
848 while (at (ptr, idx))
849 {
850 if (isupper ((unsigned char) at (ptr, idx))
851 || at (ptr, idx) == ' ' || at (ptr, idx) == '_')
852 {
853 len++;
854 idx++;
252b5132 855 }
d70910e8
KH
856 else if (at (ptr, idx) == '\n')
857 {
858 if (len > 3)
859 return 1;
860 return 0;
861 }
862 else
863 return 0;
864 }
865 return 0;
252b5132
RH
866}
867
252b5132 868static int
256d98af
KH
869copy_past_newline (ptr, idx, dst)
870 string_type *ptr;
871 unsigned int idx;
872 string_type *dst;
252b5132 873{
d70910e8 874 int column = 0;
252b5132 875
d70910e8 876 while (at (ptr, idx) && at (ptr, idx) != '\n')
252b5132 877 {
d70910e8
KH
878 if (at (ptr, idx) == '\t')
879 {
880 /* Expand tabs. Neither makeinfo nor TeX can cope well with
881 them. */
882 do
883 catchar (dst, ' ');
884 while (++column & 7);
885 }
886 else
887 {
888 catchar (dst, at (ptr, idx));
889 column++;
890 }
891 idx++;
892
893 }
894 catchar (dst, at (ptr, idx));
895 idx++;
896 return idx;
252b5132
RH
897
898}
899
9ee6f9cc
AM
900static void
901icopy_past_newline ()
252b5132 902{
d70910e8
KH
903 tos++;
904 check_range ();
905 init_string (tos);
906 idx = copy_past_newline (ptr, idx, tos);
907 pc++;
252b5132
RH
908}
909
910/* indent
d70910e8 911 Take the string at the top of the stack, do some prettying. */
252b5132 912
9ee6f9cc
AM
913static void
914kill_bogus_lines ()
252b5132 915{
d70910e8
KH
916 int sl;
917
918 int idx = 0;
919 int c;
920 int dot = 0;
921
922 string_type out;
923 init_string (&out);
924 /* Drop leading nl. */
925 while (at (tos, idx) == '\n')
252b5132 926 {
d70910e8 927 idx++;
252b5132 928 }
d70910e8
KH
929 c = idx;
930
931 /* If the first char is a '.' prepend a newline so that it is
932 recognized properly later. */
933 if (at (tos, idx) == '.')
934 catchar (&out, '\n');
935
936 /* Find the last char. */
937 while (at (tos, idx))
252b5132 938 {
d70910e8 939 idx++;
252b5132 940 }
d70910e8
KH
941
942 /* Find the last non white before the nl. */
943 idx--;
944
945 while (idx && isspace ((unsigned char) at (tos, idx)))
252b5132 946 idx--;
d70910e8 947 idx++;
252b5132 948
d70910e8
KH
949 /* Copy buffer upto last char, but blank lines before and after
950 dots don't count. */
951 sl = 1;
952
953 while (c < idx)
252b5132 954 {
d70910e8
KH
955 if (at (tos, c) == '\n'
956 && at (tos, c + 1) == '\n'
957 && at (tos, c + 2) == '.')
252b5132 958 {
d70910e8
KH
959 /* Ignore two newlines before a dot. */
960 c++;
252b5132 961 }
d70910e8 962 else if (at (tos, c) == '.' && sl)
252b5132 963 {
d70910e8
KH
964 /* remember that this line started with a dot. */
965 dot = 2;
252b5132 966 }
d70910e8
KH
967 else if (at (tos, c) == '\n'
968 && at (tos, c + 1) == '\n'
969 && dot)
252b5132 970 {
d70910e8
KH
971 c++;
972 /* Ignore two newlines when last line was dot. */
252b5132
RH
973 }
974
d70910e8
KH
975 catchar (&out, at (tos, c));
976 if (at (tos, c) == '\n')
252b5132 977 {
d70910e8
KH
978 sl = 1;
979
980 if (dot == 2)
981 dot = 1;
982 else
983 dot = 0;
252b5132 984 }
d70910e8
KH
985 else
986 sl = 0;
987
988 c++;
252b5132
RH
989
990 }
d70910e8
KH
991
992 /* Append nl. */
993 catchar (&out, '\n');
994 pc++;
995 delete_string (tos);
996 *tos = out;
997
252b5132
RH
998}
999
9ee6f9cc
AM
1000static void
1001indent ()
252b5132 1002{
d70910e8
KH
1003 string_type out;
1004 int tab = 0;
1005 int idx = 0;
1006 int ol = 0;
1007 init_string (&out);
1008 while (at (tos, idx))
1009 {
1010 switch (at (tos, idx))
1011 {
1012 case '\n':
1013 cattext (&out, "\n");
1014 idx++;
1015 if (tab && at (tos, idx))
252b5132 1016 {
d70910e8 1017 cattext (&out, " ");
252b5132 1018 }
d70910e8
KH
1019 ol = 0;
1020 break;
1021 case '(':
1022 tab++;
1023 if (ol == 0)
1024 cattext (&out, " ");
1025 idx++;
1026 cattext (&out, "(");
1027 ol = 1;
1028 break;
1029 case ')':
1030 tab--;
1031 cattext (&out, ")");
1032 idx++;
1033 ol = 1;
1034
1035 break;
1036 default:
1037 catchar (&out, at (tos, idx));
1038 ol = 1;
1039
1040 idx++;
1041 break;
1042 }
1043 }
252b5132 1044
d70910e8
KH
1045 pc++;
1046 delete_string (tos);
1047 *tos = out;
252b5132
RH
1048
1049}
1050
9ee6f9cc
AM
1051static void
1052get_stuff_in_command ()
252b5132 1053{
d70910e8
KH
1054 tos++;
1055 check_range ();
1056 init_string (tos);
252b5132 1057
d70910e8
KH
1058 while (at (ptr, idx))
1059 {
1060 if (iscommand (ptr, idx))
1061 break;
1062 idx = copy_past_newline (ptr, idx, tos);
1063 }
1064 pc++;
252b5132
RH
1065}
1066
9ee6f9cc
AM
1067static void
1068swap ()
252b5132 1069{
d70910e8
KH
1070 string_type t;
1071
1072 t = tos[0];
1073 tos[0] = tos[-1];
1074 tos[-1] = t;
1075 pc++;
252b5132
RH
1076}
1077
9ee6f9cc
AM
1078static void
1079other_dup ()
252b5132 1080{
d70910e8
KH
1081 tos++;
1082 check_range ();
1083 init_string (tos);
1084 catstr (tos, tos - 1);
1085 pc++;
252b5132
RH
1086}
1087
9ee6f9cc
AM
1088static void
1089drop ()
252b5132
RH
1090{
1091 tos--;
1092 check_range ();
8a286b63 1093 delete_string (tos + 1);
252b5132
RH
1094 pc++;
1095}
1096
9ee6f9cc
AM
1097static void
1098idrop ()
252b5132
RH
1099{
1100 isp--;
1101 icheck_range ();
1102 pc++;
1103}
1104
9ee6f9cc
AM
1105static void
1106icatstr ()
252b5132 1107{
d70910e8
KH
1108 tos--;
1109 check_range ();
1110 catstr (tos, tos + 1);
1111 delete_string (tos + 1);
1112 pc++;
252b5132
RH
1113}
1114
9ee6f9cc
AM
1115static void
1116skip_past_newline ()
252b5132 1117{
aaffae57 1118 idx = skip_past_newline_1 (ptr, idx);
d70910e8 1119 pc++;
252b5132
RH
1120}
1121
9ee6f9cc
AM
1122static void
1123internalmode ()
252b5132 1124{
d70910e8
KH
1125 internal_mode = *(isp);
1126 isp--;
1127 icheck_range ();
1128 pc++;
252b5132
RH
1129}
1130
9ee6f9cc
AM
1131static void
1132maybecatstr ()
252b5132 1133{
d70910e8 1134 if (internal_wanted == internal_mode)
252b5132 1135 {
d70910e8 1136 catstr (tos - 1, tos);
252b5132 1137 }
d70910e8
KH
1138 delete_string (tos);
1139 tos--;
1140 check_range ();
1141 pc++;
252b5132
RH
1142}
1143
1144char *
256d98af
KH
1145nextword (string, word)
1146 char *string;
1147 char **word;
252b5132 1148{
d70910e8
KH
1149 char *word_start;
1150 int idx;
1151 char *dst;
1152 char *src;
1153
1154 int length = 0;
1155
1156 while (isspace ((unsigned char) *string) || *string == '-')
1157 {
1158 if (*string == '-')
252b5132 1159 {
d70910e8 1160 while (*string && *string != '\n')
252b5132 1161 string++;
d70910e8
KH
1162
1163 }
1164 else
1165 {
1166 string++;
252b5132
RH
1167 }
1168 }
d70910e8 1169 if (!*string)
3a70f7e8
T
1170 {
1171 *word = NULL;
1172 return NULL;
1173 }
252b5132 1174
d70910e8
KH
1175 word_start = string;
1176 if (*string == '"')
1177 {
1178 do
1179 {
1180 string++;
1181 length++;
1182 if (*string == '\\')
252b5132 1183 {
d70910e8
KH
1184 string += 2;
1185 length += 2;
252b5132 1186 }
d70910e8
KH
1187 }
1188 while (*string != '"');
252b5132 1189 }
d70910e8
KH
1190 else
1191 {
1192 while (!isspace ((unsigned char) *string))
1193 {
1194 string++;
1195 length++;
252b5132 1196
d70910e8
KH
1197 }
1198 }
252b5132 1199
e3ad91e3 1200 *word = (char *) malloc (length + 1);
252b5132 1201
d70910e8
KH
1202 dst = *word;
1203 src = word_start;
252b5132 1204
d70910e8
KH
1205 for (idx = 0; idx < length; idx++)
1206 {
1207 if (src[idx] == '\\')
1208 switch (src[idx + 1])
1209 {
1210 case 'n':
1211 *dst++ = '\n';
1212 idx++;
1213 break;
1214 case '"':
1215 case '\\':
1216 *dst++ = src[idx + 1];
1217 idx++;
1218 break;
1219 default:
1220 *dst++ = '\\';
1221 break;
1222 }
1223 else
1224 *dst++ = src[idx];
1225 }
1226 *dst++ = 0;
252b5132 1227
d70910e8
KH
1228 if (*string)
1229 return string + 1;
1230 else
3a70f7e8 1231 return NULL;
252b5132 1232}
d70910e8 1233
252b5132 1234dict_type *root;
d70910e8 1235
252b5132 1236dict_type *
256d98af
KH
1237lookup_word (word)
1238 char *word;
252b5132
RH
1239{
1240 dict_type *ptr = root;
d70910e8
KH
1241 while (ptr)
1242 {
1243 if (strcmp (ptr->word, word) == 0)
1244 return ptr;
252b5132 1245 ptr = ptr->next;
252b5132
RH
1246 }
1247 if (warning)
d70910e8 1248 fprintf (stderr, "Can't find %s\n", word);
3a70f7e8 1249 return NULL;
252b5132
RH
1250}
1251
8a286b63
NC
1252static void
1253free_words (void)
1254{
1255 dict_type *ptr = root;
1256
1257 while (ptr)
1258 {
1259 dict_type *next;
1260
1261 if (ptr->word)
1262 free (ptr->word);
1263 if (ptr->code)
1264 {
1265 int i;
b05971a6 1266 for (i = 0; i < ptr->code_end - 1; i ++)
8a286b63
NC
1267 if (ptr->code[i] == push_text
1268 && ptr->code[i + 1])
1269 {
b05971a6 1270 free ((char *) ptr->code[i + 1] - 1);
8a286b63
NC
1271 ++ i;
1272 }
1273 free (ptr->code);
1274 }
1275 next = ptr->next;
1276 free (ptr);
1277 ptr = next;
1278 }
1279}
1280
256d98af 1281static void
3a70f7e8 1282perform (void)
252b5132
RH
1283{
1284 tos = stack;
252b5132 1285
d70910e8
KH
1286 while (at (ptr, idx))
1287 {
1288 /* It's worth looking through the command list. */
1289 if (iscommand (ptr, idx))
1290 {
1291 char *next;
1292 dict_type *word;
252b5132 1293
d70910e8 1294 (void) nextword (addr (ptr, idx), &next);
252b5132 1295
d70910e8 1296 word = lookup_word (next);
252b5132 1297
d70910e8
KH
1298 if (word)
1299 {
1300 exec (word);
1301 }
1302 else
1303 {
1304 if (warning)
1305 fprintf (stderr, "warning, %s is not recognised\n", next);
1306 skip_past_newline ();
1307 }
b2e951ec 1308 free (next);
252b5132 1309 }
d70910e8
KH
1310 else
1311 skip_past_newline ();
252b5132
RH
1312 }
1313}
1314
1315dict_type *
256d98af
KH
1316newentry (word)
1317 char *word;
252b5132 1318{
d3ce72d0
NC
1319 dict_type *new_d = (dict_type *) malloc (sizeof (dict_type));
1320 new_d->word = word;
1321 new_d->next = root;
1322 root = new_d;
1323 new_d->code = (stinst_type *) malloc (sizeof (stinst_type));
1324 new_d->code_length = 1;
1325 new_d->code_end = 0;
1326 return new_d;
252b5132
RH
1327}
1328
252b5132 1329unsigned int
256d98af
KH
1330add_to_definition (entry, word)
1331 dict_type *entry;
1332 stinst_type word;
252b5132 1333{
d70910e8 1334 if (entry->code_end == entry->code_length)
252b5132 1335 {
d70910e8
KH
1336 entry->code_length += 2;
1337 entry->code =
1338 (stinst_type *) realloc ((char *) (entry->code),
3a70f7e8 1339 entry->code_length * sizeof (stinst_type));
252b5132 1340 }
d70910e8 1341 entry->code[entry->code_end] = word;
252b5132 1342
d70910e8
KH
1343 return entry->code_end++;
1344}
252b5132
RH
1345
1346void
256d98af
KH
1347add_intrinsic (name, func)
1348 char *name;
d70910e8 1349 void (*func) ();
252b5132 1350{
8a286b63 1351 dict_type *new_d = newentry (strdup (name));
d3ce72d0
NC
1352 add_to_definition (new_d, func);
1353 add_to_definition (new_d, 0);
252b5132
RH
1354}
1355
1356void
256d98af
KH
1357add_var (name)
1358 char *name;
252b5132 1359{
d3ce72d0
NC
1360 dict_type *new_d = newentry (name);
1361 add_to_definition (new_d, push_number);
1362 add_to_definition (new_d, (stinst_type) (&(new_d->var)));
1363 add_to_definition (new_d, 0);
252b5132
RH
1364}
1365
d70910e8 1366void
256d98af
KH
1367compile (string)
1368 char *string;
252b5132 1369{
d70910e8
KH
1370 /* Add words to the dictionary. */
1371 char *word;
8a286b63 1372
d70910e8
KH
1373 string = nextword (string, &word);
1374 while (string && *string && word[0])
252b5132 1375 {
d70910e8 1376 if (strcmp (word, "var") == 0)
252b5132 1377 {
8a286b63 1378 free (word);
d70910e8 1379 string = nextword (string, &word);
3a70f7e8
T
1380 if (!string)
1381 continue;
d70910e8
KH
1382 add_var (word);
1383 string = nextword (string, &word);
252b5132 1384 }
d70910e8 1385 else if (word[0] == ':')
252b5132 1386 {
d70910e8 1387 dict_type *ptr;
8a286b63 1388
d70910e8 1389 /* Compile a word and add to dictionary. */
8a286b63 1390 free (word);
d70910e8 1391 string = nextword (string, &word);
3a70f7e8
T
1392 if (!string)
1393 continue;
d70910e8
KH
1394 ptr = newentry (word);
1395 string = nextword (string, &word);
3a70f7e8
T
1396 if (!string)
1397 {
1398 free (ptr->code);
1399 free (ptr);
1400 continue;
1401 }
8a286b63 1402
d70910e8 1403 while (word[0] != ';')
252b5132 1404 {
d70910e8
KH
1405 switch (word[0])
1406 {
1407 case '"':
1408 /* got a string, embed magic push string
1409 function */
1410 add_to_definition (ptr, push_text);
1411 add_to_definition (ptr, (stinst_type) (word + 1));
1412 break;
1413 case '0':
1414 case '1':
1415 case '2':
1416 case '3':
1417 case '4':
1418 case '5':
1419 case '6':
1420 case '7':
1421 case '8':
1422 case '9':
1423 /* Got a number, embedd the magic push number
1424 function */
1425 add_to_definition (ptr, push_number);
1426 add_to_definition (ptr, (stinst_type) atol (word));
8a286b63 1427 free (word);
d70910e8
KH
1428 break;
1429 default:
1430 add_to_definition (ptr, call);
1431 add_to_definition (ptr, (stinst_type) lookup_word (word));
8a286b63 1432 free (word);
d70910e8
KH
1433 }
1434
1435 string = nextword (string, &word);
252b5132 1436 }
d70910e8 1437 add_to_definition (ptr, 0);
8a286b63 1438 free (word);
d70910e8 1439 string = nextword (string, &word);
252b5132 1440 }
d70910e8 1441 else
252b5132 1442 {
d70910e8
KH
1443 fprintf (stderr, "syntax error at %s\n", string - 1);
1444 }
252b5132 1445 }
8a286b63
NC
1446 if (word)
1447 free (word);
252b5132
RH
1448}
1449
256d98af 1450static void
51240b8d 1451bang ()
252b5132 1452{
d70910e8
KH
1453 *(long *) ((isp[0])) = isp[-1];
1454 isp -= 2;
252b5132
RH
1455 icheck_range ();
1456 pc++;
1457}
1458
9ee6f9cc
AM
1459static void
1460atsign ()
252b5132 1461{
d70910e8
KH
1462 isp[0] = *(long *) (isp[0]);
1463 pc++;
252b5132
RH
1464}
1465
9ee6f9cc
AM
1466static void
1467hello ()
252b5132 1468{
d70910e8
KH
1469 printf ("hello\n");
1470 pc++;
252b5132
RH
1471}
1472
9ee6f9cc
AM
1473static void
1474stdout_ ()
252b5132
RH
1475{
1476 isp++;
1477 icheck_range ();
1478 *isp = 1;
1479 pc++;
1480}
1481
9ee6f9cc
AM
1482static void
1483stderr_ ()
252b5132
RH
1484{
1485 isp++;
1486 icheck_range ();
1487 *isp = 2;
1488 pc++;
1489}
1490
9ee6f9cc
AM
1491static void
1492print ()
252b5132
RH
1493{
1494 if (*isp == 1)
1495 write_buffer (tos, stdout);
1496 else if (*isp == 2)
1497 write_buffer (tos, stderr);
1498 else
1499 fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
1500 isp--;
1501 tos--;
1502 icheck_range ();
1503 check_range ();
1504 pc++;
1505}
1506
256d98af
KH
1507static void
1508read_in (str, file)
d70910e8
KH
1509 string_type *str;
1510 FILE *file;
252b5132 1511{
d70910e8
KH
1512 char buff[10000];
1513 unsigned int r;
1514 do
252b5132 1515 {
d70910e8
KH
1516 r = fread (buff, 1, sizeof (buff), file);
1517 catbuf (str, buff, r);
252b5132 1518 }
d70910e8
KH
1519 while (r);
1520 buff[0] = 0;
252b5132 1521
d70910e8
KH
1522 catbuf (str, buff, 1);
1523}
252b5132 1524
256d98af 1525static void
51240b8d 1526usage ()
252b5132 1527{
d70910e8
KH
1528 fprintf (stderr, "usage: -[d|i|g] <file >file\n");
1529 exit (33);
252b5132
RH
1530}
1531
1532/* There is no reliable way to declare exit. Sometimes it returns
1533 int, and sometimes it returns void. Sometimes it changes between
1534 OS releases. Trying to get it declared correctly in the hosts file
1535 is a pointless waste of time. */
1536
1537static void
1538chew_exit ()
1539{
1540 exit (0);
1541}
1542
256d98af 1543int
d70910e8 1544main (ac, av)
256d98af
KH
1545 int ac;
1546 char *av[];
252b5132
RH
1547{
1548 unsigned int i;
1549 string_type buffer;
1550 string_type pptr;
1551
d70910e8
KH
1552 init_string (&buffer);
1553 init_string (&pptr);
1554 init_string (stack + 0);
1555 tos = stack + 1;
252b5132 1556 ptr = &pptr;
d70910e8
KH
1557
1558 add_intrinsic ("push_text", push_text);
1559 add_intrinsic ("!", bang);
1560 add_intrinsic ("@", atsign);
1561 add_intrinsic ("hello", hello);
1562 add_intrinsic ("stdout", stdout_);
1563 add_intrinsic ("stderr", stderr_);
1564 add_intrinsic ("print", print);
1565 add_intrinsic ("skip_past_newline", skip_past_newline);
1566 add_intrinsic ("catstr", icatstr);
1567 add_intrinsic ("copy_past_newline", icopy_past_newline);
1568 add_intrinsic ("dup", other_dup);
1569 add_intrinsic ("drop", drop);
1570 add_intrinsic ("idrop", idrop);
1571 add_intrinsic ("remchar", remchar);
1572 add_intrinsic ("get_stuff_in_command", get_stuff_in_command);
1573 add_intrinsic ("do_fancy_stuff", do_fancy_stuff);
1574 add_intrinsic ("bulletize", bulletize);
1575 add_intrinsic ("courierize", courierize);
252b5132
RH
1576 /* If the following line gives an error, exit() is not declared in the
1577 ../hosts/foo.h file for this host. Fix it there, not here! */
1578 /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */
d70910e8
KH
1579 add_intrinsic ("exit", chew_exit);
1580 add_intrinsic ("swap", swap);
1581 add_intrinsic ("outputdots", outputdots);
1582 add_intrinsic ("paramstuff", paramstuff);
1583 add_intrinsic ("maybecatstr", maybecatstr);
1584 add_intrinsic ("translatecomments", translatecomments);
1585 add_intrinsic ("kill_bogus_lines", kill_bogus_lines);
1586 add_intrinsic ("indent", indent);
1587 add_intrinsic ("internalmode", internalmode);
1588 add_intrinsic ("print_stack_level", print_stack_level);
1589 add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines);
1590
1591 /* Put a nl at the start. */
1592 catchar (&buffer, '\n');
1593
1594 read_in (&buffer, stdin);
1595 remove_noncomments (&buffer, ptr);
1596 for (i = 1; i < (unsigned int) ac; i++)
252b5132 1597 {
d70910e8 1598 if (av[i][0] == '-')
252b5132 1599 {
d70910e8
KH
1600 if (av[i][1] == 'f')
1601 {
1602 string_type b;
1603 FILE *f;
1604 init_string (&b);
252b5132 1605
d70910e8
KH
1606 f = fopen (av[i + 1], "r");
1607 if (!f)
1608 {
1609 fprintf (stderr, "Can't open the input file %s\n",
1610 av[i + 1]);
1611 return 33;
1612 }
1613
1614 read_in (&b, f);
1615 compile (b.ptr);
1616 perform ();
5fbe0d87 1617 delete_string (&b);
d70910e8
KH
1618 }
1619 else if (av[i][1] == 'i')
1620 {
1621 internal_wanted = 1;
1622 }
1623 else if (av[i][1] == 'w')
1624 {
1625 warning = 1;
1626 }
1627 else
1628 usage ();
1629 }
252b5132 1630 }
d70910e8 1631 write_buffer (stack + 0, stdout);
8a286b63
NC
1632 free_words ();
1633 delete_string (&pptr);
1634 delete_string (&buffer);
252b5132
RH
1635 if (tos != stack)
1636 {
709bcda1 1637 fprintf (stderr, "finishing with current stack level %ld\n",
13ce3c11 1638 (long) (tos - stack));
252b5132
RH
1639 return 1;
1640 }
1641 return 0;
1642}
This page took 2.19121 seconds and 4 git commands to generate.