]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/doc/chew.c
Disable R_X86_64_PLT32 generation as branch marker on Solaris/x86
[thirdparty/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
KH
1169 if (!*string)
1170 return 0;
252b5132 1171
d70910e8
KH
1172 word_start = string;
1173 if (*string == '"')
1174 {
1175 do
1176 {
1177 string++;
1178 length++;
1179 if (*string == '\\')
252b5132 1180 {
d70910e8
KH
1181 string += 2;
1182 length += 2;
252b5132 1183 }
d70910e8
KH
1184 }
1185 while (*string != '"');
252b5132 1186 }
d70910e8
KH
1187 else
1188 {
1189 while (!isspace ((unsigned char) *string))
1190 {
1191 string++;
1192 length++;
252b5132 1193
d70910e8
KH
1194 }
1195 }
252b5132 1196
e3ad91e3 1197 *word = (char *) malloc (length + 1);
252b5132 1198
d70910e8
KH
1199 dst = *word;
1200 src = word_start;
252b5132 1201
d70910e8
KH
1202 for (idx = 0; idx < length; idx++)
1203 {
1204 if (src[idx] == '\\')
1205 switch (src[idx + 1])
1206 {
1207 case 'n':
1208 *dst++ = '\n';
1209 idx++;
1210 break;
1211 case '"':
1212 case '\\':
1213 *dst++ = src[idx + 1];
1214 idx++;
1215 break;
1216 default:
1217 *dst++ = '\\';
1218 break;
1219 }
1220 else
1221 *dst++ = src[idx];
1222 }
1223 *dst++ = 0;
252b5132 1224
d70910e8
KH
1225 if (*string)
1226 return string + 1;
1227 else
1228 return 0;
252b5132 1229}
d70910e8 1230
252b5132 1231dict_type *root;
d70910e8 1232
252b5132 1233dict_type *
256d98af
KH
1234lookup_word (word)
1235 char *word;
252b5132
RH
1236{
1237 dict_type *ptr = root;
d70910e8
KH
1238 while (ptr)
1239 {
1240 if (strcmp (ptr->word, word) == 0)
1241 return ptr;
252b5132 1242 ptr = ptr->next;
252b5132
RH
1243 }
1244 if (warning)
d70910e8 1245 fprintf (stderr, "Can't find %s\n", word);
252b5132 1246 return 0;
252b5132
RH
1247}
1248
8a286b63
NC
1249static void
1250free_words (void)
1251{
1252 dict_type *ptr = root;
1253
1254 while (ptr)
1255 {
1256 dict_type *next;
1257
1258 if (ptr->word)
1259 free (ptr->word);
1260 if (ptr->code)
1261 {
1262 int i;
1263 for (i = 0; i < ptr->code_length; i ++)
1264 if (ptr->code[i] == push_text
1265 && ptr->code[i + 1])
1266 {
1267 free (ptr->code[i + 1] - 1);
1268 ++ i;
1269 }
1270 free (ptr->code);
1271 }
1272 next = ptr->next;
1273 free (ptr);
1274 ptr = next;
1275 }
1276}
1277
256d98af 1278static void
51240b8d 1279perform ()
252b5132
RH
1280{
1281 tos = stack;
252b5132 1282
d70910e8
KH
1283 while (at (ptr, idx))
1284 {
1285 /* It's worth looking through the command list. */
1286 if (iscommand (ptr, idx))
1287 {
1288 char *next;
1289 dict_type *word;
252b5132 1290
d70910e8 1291 (void) nextword (addr (ptr, idx), &next);
252b5132 1292
d70910e8 1293 word = lookup_word (next);
252b5132 1294
d70910e8
KH
1295 if (word)
1296 {
1297 exec (word);
1298 }
1299 else
1300 {
1301 if (warning)
1302 fprintf (stderr, "warning, %s is not recognised\n", next);
1303 skip_past_newline ();
1304 }
b2e951ec 1305 free (next);
252b5132 1306 }
d70910e8
KH
1307 else
1308 skip_past_newline ();
252b5132
RH
1309 }
1310}
1311
1312dict_type *
256d98af
KH
1313newentry (word)
1314 char *word;
252b5132 1315{
d3ce72d0
NC
1316 dict_type *new_d = (dict_type *) malloc (sizeof (dict_type));
1317 new_d->word = word;
1318 new_d->next = root;
1319 root = new_d;
1320 new_d->code = (stinst_type *) malloc (sizeof (stinst_type));
1321 new_d->code_length = 1;
1322 new_d->code_end = 0;
1323 return new_d;
252b5132
RH
1324}
1325
252b5132 1326unsigned int
256d98af
KH
1327add_to_definition (entry, word)
1328 dict_type *entry;
1329 stinst_type word;
252b5132 1330{
d70910e8 1331 if (entry->code_end == entry->code_length)
252b5132 1332 {
d70910e8
KH
1333 entry->code_length += 2;
1334 entry->code =
1335 (stinst_type *) realloc ((char *) (entry->code),
1336 entry->code_length * sizeof (word_type));
252b5132 1337 }
d70910e8 1338 entry->code[entry->code_end] = word;
252b5132 1339
d70910e8
KH
1340 return entry->code_end++;
1341}
252b5132
RH
1342
1343void
256d98af
KH
1344add_intrinsic (name, func)
1345 char *name;
d70910e8 1346 void (*func) ();
252b5132 1347{
8a286b63 1348 dict_type *new_d = newentry (strdup (name));
d3ce72d0
NC
1349 add_to_definition (new_d, func);
1350 add_to_definition (new_d, 0);
252b5132
RH
1351}
1352
1353void
256d98af
KH
1354add_var (name)
1355 char *name;
252b5132 1356{
d3ce72d0
NC
1357 dict_type *new_d = newentry (name);
1358 add_to_definition (new_d, push_number);
1359 add_to_definition (new_d, (stinst_type) (&(new_d->var)));
1360 add_to_definition (new_d, 0);
252b5132
RH
1361}
1362
d70910e8 1363void
256d98af
KH
1364compile (string)
1365 char *string;
252b5132 1366{
d70910e8
KH
1367 /* Add words to the dictionary. */
1368 char *word;
8a286b63 1369
d70910e8
KH
1370 string = nextword (string, &word);
1371 while (string && *string && word[0])
252b5132 1372 {
d70910e8 1373 if (strcmp (word, "var") == 0)
252b5132 1374 {
8a286b63 1375 free (word);
d70910e8 1376 string = nextword (string, &word);
d70910e8
KH
1377 add_var (word);
1378 string = nextword (string, &word);
252b5132 1379 }
d70910e8 1380 else if (word[0] == ':')
252b5132 1381 {
d70910e8 1382 dict_type *ptr;
8a286b63 1383
d70910e8 1384 /* Compile a word and add to dictionary. */
8a286b63 1385 free (word);
d70910e8 1386 string = nextword (string, &word);
d70910e8
KH
1387 ptr = newentry (word);
1388 string = nextword (string, &word);
8a286b63 1389
d70910e8 1390 while (word[0] != ';')
252b5132 1391 {
d70910e8
KH
1392 switch (word[0])
1393 {
1394 case '"':
1395 /* got a string, embed magic push string
1396 function */
1397 add_to_definition (ptr, push_text);
1398 add_to_definition (ptr, (stinst_type) (word + 1));
1399 break;
1400 case '0':
1401 case '1':
1402 case '2':
1403 case '3':
1404 case '4':
1405 case '5':
1406 case '6':
1407 case '7':
1408 case '8':
1409 case '9':
1410 /* Got a number, embedd the magic push number
1411 function */
1412 add_to_definition (ptr, push_number);
1413 add_to_definition (ptr, (stinst_type) atol (word));
8a286b63 1414 free (word);
d70910e8
KH
1415 break;
1416 default:
1417 add_to_definition (ptr, call);
1418 add_to_definition (ptr, (stinst_type) lookup_word (word));
8a286b63 1419 free (word);
d70910e8
KH
1420 }
1421
1422 string = nextword (string, &word);
252b5132 1423 }
d70910e8 1424 add_to_definition (ptr, 0);
8a286b63
NC
1425 free (word);
1426 word = NULL;
d70910e8 1427 string = nextword (string, &word);
252b5132 1428 }
d70910e8 1429 else
252b5132 1430 {
d70910e8
KH
1431 fprintf (stderr, "syntax error at %s\n", string - 1);
1432 }
252b5132 1433 }
8a286b63
NC
1434 if (word)
1435 free (word);
252b5132
RH
1436}
1437
256d98af 1438static void
51240b8d 1439bang ()
252b5132 1440{
d70910e8
KH
1441 *(long *) ((isp[0])) = isp[-1];
1442 isp -= 2;
252b5132
RH
1443 icheck_range ();
1444 pc++;
1445}
1446
9ee6f9cc
AM
1447static void
1448atsign ()
252b5132 1449{
d70910e8
KH
1450 isp[0] = *(long *) (isp[0]);
1451 pc++;
252b5132
RH
1452}
1453
9ee6f9cc
AM
1454static void
1455hello ()
252b5132 1456{
d70910e8
KH
1457 printf ("hello\n");
1458 pc++;
252b5132
RH
1459}
1460
9ee6f9cc
AM
1461static void
1462stdout_ ()
252b5132
RH
1463{
1464 isp++;
1465 icheck_range ();
1466 *isp = 1;
1467 pc++;
1468}
1469
9ee6f9cc
AM
1470static void
1471stderr_ ()
252b5132
RH
1472{
1473 isp++;
1474 icheck_range ();
1475 *isp = 2;
1476 pc++;
1477}
1478
9ee6f9cc
AM
1479static void
1480print ()
252b5132
RH
1481{
1482 if (*isp == 1)
1483 write_buffer (tos, stdout);
1484 else if (*isp == 2)
1485 write_buffer (tos, stderr);
1486 else
1487 fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
1488 isp--;
1489 tos--;
1490 icheck_range ();
1491 check_range ();
1492 pc++;
1493}
1494
256d98af
KH
1495static void
1496read_in (str, file)
d70910e8
KH
1497 string_type *str;
1498 FILE *file;
252b5132 1499{
d70910e8
KH
1500 char buff[10000];
1501 unsigned int r;
1502 do
252b5132 1503 {
d70910e8
KH
1504 r = fread (buff, 1, sizeof (buff), file);
1505 catbuf (str, buff, r);
252b5132 1506 }
d70910e8
KH
1507 while (r);
1508 buff[0] = 0;
252b5132 1509
d70910e8
KH
1510 catbuf (str, buff, 1);
1511}
252b5132 1512
256d98af 1513static void
51240b8d 1514usage ()
252b5132 1515{
d70910e8
KH
1516 fprintf (stderr, "usage: -[d|i|g] <file >file\n");
1517 exit (33);
252b5132
RH
1518}
1519
1520/* There is no reliable way to declare exit. Sometimes it returns
1521 int, and sometimes it returns void. Sometimes it changes between
1522 OS releases. Trying to get it declared correctly in the hosts file
1523 is a pointless waste of time. */
1524
1525static void
1526chew_exit ()
1527{
1528 exit (0);
1529}
1530
256d98af 1531int
d70910e8 1532main (ac, av)
256d98af
KH
1533 int ac;
1534 char *av[];
252b5132
RH
1535{
1536 unsigned int i;
1537 string_type buffer;
1538 string_type pptr;
1539
d70910e8
KH
1540 init_string (&buffer);
1541 init_string (&pptr);
1542 init_string (stack + 0);
1543 tos = stack + 1;
252b5132 1544 ptr = &pptr;
d70910e8
KH
1545
1546 add_intrinsic ("push_text", push_text);
1547 add_intrinsic ("!", bang);
1548 add_intrinsic ("@", atsign);
1549 add_intrinsic ("hello", hello);
1550 add_intrinsic ("stdout", stdout_);
1551 add_intrinsic ("stderr", stderr_);
1552 add_intrinsic ("print", print);
1553 add_intrinsic ("skip_past_newline", skip_past_newline);
1554 add_intrinsic ("catstr", icatstr);
1555 add_intrinsic ("copy_past_newline", icopy_past_newline);
1556 add_intrinsic ("dup", other_dup);
1557 add_intrinsic ("drop", drop);
1558 add_intrinsic ("idrop", idrop);
1559 add_intrinsic ("remchar", remchar);
1560 add_intrinsic ("get_stuff_in_command", get_stuff_in_command);
1561 add_intrinsic ("do_fancy_stuff", do_fancy_stuff);
1562 add_intrinsic ("bulletize", bulletize);
1563 add_intrinsic ("courierize", courierize);
252b5132
RH
1564 /* If the following line gives an error, exit() is not declared in the
1565 ../hosts/foo.h file for this host. Fix it there, not here! */
1566 /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */
d70910e8
KH
1567 add_intrinsic ("exit", chew_exit);
1568 add_intrinsic ("swap", swap);
1569 add_intrinsic ("outputdots", outputdots);
1570 add_intrinsic ("paramstuff", paramstuff);
1571 add_intrinsic ("maybecatstr", maybecatstr);
1572 add_intrinsic ("translatecomments", translatecomments);
1573 add_intrinsic ("kill_bogus_lines", kill_bogus_lines);
1574 add_intrinsic ("indent", indent);
1575 add_intrinsic ("internalmode", internalmode);
1576 add_intrinsic ("print_stack_level", print_stack_level);
1577 add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines);
1578
1579 /* Put a nl at the start. */
1580 catchar (&buffer, '\n');
1581
1582 read_in (&buffer, stdin);
1583 remove_noncomments (&buffer, ptr);
1584 for (i = 1; i < (unsigned int) ac; i++)
252b5132 1585 {
d70910e8 1586 if (av[i][0] == '-')
252b5132 1587 {
d70910e8
KH
1588 if (av[i][1] == 'f')
1589 {
1590 string_type b;
1591 FILE *f;
1592 init_string (&b);
252b5132 1593
d70910e8
KH
1594 f = fopen (av[i + 1], "r");
1595 if (!f)
1596 {
1597 fprintf (stderr, "Can't open the input file %s\n",
1598 av[i + 1]);
1599 return 33;
1600 }
1601
1602 read_in (&b, f);
1603 compile (b.ptr);
1604 perform ();
5fbe0d87 1605 delete_string (&b);
d70910e8
KH
1606 }
1607 else if (av[i][1] == 'i')
1608 {
1609 internal_wanted = 1;
1610 }
1611 else if (av[i][1] == 'w')
1612 {
1613 warning = 1;
1614 }
1615 else
1616 usage ();
1617 }
252b5132 1618 }
d70910e8 1619 write_buffer (stack + 0, stdout);
8a286b63
NC
1620 free_words ();
1621 delete_string (&pptr);
1622 delete_string (&buffer);
252b5132
RH
1623 if (tos != stack)
1624 {
709bcda1 1625 fprintf (stderr, "finishing with current stack level %ld\n",
13ce3c11 1626 (long) (tos - stack));
252b5132
RH
1627 return 1;
1628 }
1629 return 0;
1630}