13d8817e4Smiod /* chew
23d8817e4Smiod Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001,
33d8817e4Smiod 2002, 2003, 2005
43d8817e4Smiod Free Software Foundation, Inc.
53d8817e4Smiod Contributed by steve chamberlain @cygnus
63d8817e4Smiod
73d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
83d8817e4Smiod
93d8817e4Smiod This program is free software; you can redistribute it and/or modify
103d8817e4Smiod it under the terms of the GNU General Public License as published by
113d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
123d8817e4Smiod (at your option) any later version.
133d8817e4Smiod
143d8817e4Smiod This program is distributed in the hope that it will be useful,
153d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
163d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173d8817e4Smiod GNU General Public License for more details.
183d8817e4Smiod
193d8817e4Smiod You should have received a copy of the GNU General Public License
203d8817e4Smiod along with this program; if not, write to the Free Software
213d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
223d8817e4Smiod
233d8817e4Smiod /* Yet another way of extracting documentation from source.
243d8817e4Smiod No, I haven't finished it yet, but I hope you people like it better
253d8817e4Smiod than the old way
263d8817e4Smiod
273d8817e4Smiod sac
283d8817e4Smiod
293d8817e4Smiod Basically, this is a sort of string forth, maybe we should call it
303d8817e4Smiod struth?
313d8817e4Smiod
323d8817e4Smiod You define new words thus:
333d8817e4Smiod : <newword> <oldwords> ;
343d8817e4Smiod
353d8817e4Smiod */
363d8817e4Smiod
373d8817e4Smiod /* Primitives provided by the program:
383d8817e4Smiod
393d8817e4Smiod Two stacks are provided, a string stack and an integer stack.
403d8817e4Smiod
413d8817e4Smiod Internal state variables:
423d8817e4Smiod internal_wanted - indicates whether `-i' was passed
433d8817e4Smiod internal_mode - user-settable
443d8817e4Smiod
453d8817e4Smiod Commands:
463d8817e4Smiod push_text
473d8817e4Smiod ! - pop top of integer stack for address, pop next for value; store
483d8817e4Smiod @ - treat value on integer stack as the address of an integer; push
493d8817e4Smiod that integer on the integer stack after popping the "address"
503d8817e4Smiod hello - print "hello\n" to stdout
513d8817e4Smiod stdout - put stdout marker on TOS
523d8817e4Smiod stderr - put stderr marker on TOS
533d8817e4Smiod print - print TOS-1 on TOS (eg: "hello\n" stdout print)
543d8817e4Smiod skip_past_newline
553d8817e4Smiod catstr - fn icatstr
563d8817e4Smiod copy_past_newline - append input, up to and including newline into TOS
573d8817e4Smiod dup - fn other_dup
583d8817e4Smiod drop - discard TOS
593d8817e4Smiod idrop - ditto
603d8817e4Smiod remchar - delete last character from TOS
613d8817e4Smiod get_stuff_in_command
623d8817e4Smiod do_fancy_stuff - translate <<foo>> to @code{foo} in TOS
633d8817e4Smiod bulletize - if "o" lines found, prepend @itemize @bullet to TOS
643d8817e4Smiod and @item to each "o" line; append @end itemize
653d8817e4Smiod courierize - put @example around . and | lines, translate {* *} { }
663d8817e4Smiod exit - fn chew_exit
673d8817e4Smiod swap
683d8817e4Smiod outputdots - strip out lines without leading dots
693d8817e4Smiod paramstuff - convert full declaration into "PARAMS" form if not already
703d8817e4Smiod maybecatstr - do catstr if internal_mode == internal_wanted, discard
713d8817e4Smiod value in any case
723d8817e4Smiod translatecomments - turn {* and *} into comment delimiters
733d8817e4Smiod kill_bogus_lines - get rid of extra newlines
743d8817e4Smiod indent
753d8817e4Smiod internalmode - pop from integer stack, set `internalmode' to that value
763d8817e4Smiod print_stack_level - print current stack depth to stderr
773d8817e4Smiod strip_trailing_newlines - go ahead, guess...
783d8817e4Smiod [quoted string] - push string onto string stack
793d8817e4Smiod [word starting with digit] - push atol(str) onto integer stack
803d8817e4Smiod
813d8817e4Smiod A command must be all upper-case, and alone on a line.
823d8817e4Smiod
833d8817e4Smiod Foo. */
843d8817e4Smiod
853d8817e4Smiod #include "ansidecl.h"
863d8817e4Smiod #include <assert.h>
873d8817e4Smiod #include <stdio.h>
883d8817e4Smiod #include <ctype.h>
893d8817e4Smiod #include <stdlib.h>
903d8817e4Smiod #include <string.h>
913d8817e4Smiod
923d8817e4Smiod #define DEF_SIZE 5000
933d8817e4Smiod #define STACK 50
943d8817e4Smiod
953d8817e4Smiod int internal_wanted;
963d8817e4Smiod int internal_mode;
973d8817e4Smiod
983d8817e4Smiod int warning;
993d8817e4Smiod
1003d8817e4Smiod /* Here is a string type ... */
1013d8817e4Smiod
1023d8817e4Smiod typedef struct buffer
1033d8817e4Smiod {
1043d8817e4Smiod char *ptr;
1053d8817e4Smiod unsigned long write_idx;
1063d8817e4Smiod unsigned long size;
1073d8817e4Smiod } string_type;
1083d8817e4Smiod
1093d8817e4Smiod #ifdef __STDC__
1103d8817e4Smiod static void init_string_with_size (string_type *, unsigned int);
1113d8817e4Smiod static void init_string (string_type *);
1123d8817e4Smiod static int find (string_type *, char *);
1133d8817e4Smiod static void write_buffer (string_type *, FILE *);
1143d8817e4Smiod static void delete_string (string_type *);
1153d8817e4Smiod static char *addr (string_type *, unsigned int);
1163d8817e4Smiod static char at (string_type *, unsigned int);
1173d8817e4Smiod static void catchar (string_type *, int);
1183d8817e4Smiod static void overwrite_string (string_type *, string_type *);
1193d8817e4Smiod static void catbuf (string_type *, char *, unsigned int);
1203d8817e4Smiod static void cattext (string_type *, char *);
1213d8817e4Smiod static void catstr (string_type *, string_type *);
1223d8817e4Smiod #endif
1233d8817e4Smiod
1243d8817e4Smiod static void
init_string_with_size(buffer,size)1253d8817e4Smiod init_string_with_size (buffer, size)
1263d8817e4Smiod string_type *buffer;
1273d8817e4Smiod unsigned int size;
1283d8817e4Smiod {
1293d8817e4Smiod buffer->write_idx = 0;
1303d8817e4Smiod buffer->size = size;
1313d8817e4Smiod buffer->ptr = malloc (size);
1323d8817e4Smiod }
1333d8817e4Smiod
1343d8817e4Smiod static void
init_string(buffer)1353d8817e4Smiod init_string (buffer)
1363d8817e4Smiod string_type *buffer;
1373d8817e4Smiod {
1383d8817e4Smiod init_string_with_size (buffer, DEF_SIZE);
1393d8817e4Smiod }
1403d8817e4Smiod
1413d8817e4Smiod static int
find(str,what)1423d8817e4Smiod find (str, what)
1433d8817e4Smiod string_type *str;
1443d8817e4Smiod char *what;
1453d8817e4Smiod {
1463d8817e4Smiod unsigned int i;
1473d8817e4Smiod char *p;
1483d8817e4Smiod p = what;
1493d8817e4Smiod for (i = 0; i < str->write_idx && *p; i++)
1503d8817e4Smiod {
1513d8817e4Smiod if (*p == str->ptr[i])
1523d8817e4Smiod p++;
1533d8817e4Smiod else
1543d8817e4Smiod p = what;
1553d8817e4Smiod }
1563d8817e4Smiod return (*p == 0);
1573d8817e4Smiod }
1583d8817e4Smiod
1593d8817e4Smiod static void
write_buffer(buffer,f)1603d8817e4Smiod write_buffer (buffer, f)
1613d8817e4Smiod string_type *buffer;
1623d8817e4Smiod FILE *f;
1633d8817e4Smiod {
1643d8817e4Smiod fwrite (buffer->ptr, buffer->write_idx, 1, f);
1653d8817e4Smiod }
1663d8817e4Smiod
1673d8817e4Smiod static void
delete_string(buffer)1683d8817e4Smiod delete_string (buffer)
1693d8817e4Smiod string_type *buffer;
1703d8817e4Smiod {
1713d8817e4Smiod free (buffer->ptr);
1723d8817e4Smiod }
1733d8817e4Smiod
1743d8817e4Smiod static char *
addr(buffer,idx)1753d8817e4Smiod addr (buffer, idx)
1763d8817e4Smiod string_type *buffer;
1773d8817e4Smiod unsigned int idx;
1783d8817e4Smiod {
1793d8817e4Smiod return buffer->ptr + idx;
1803d8817e4Smiod }
1813d8817e4Smiod
1823d8817e4Smiod static char
at(buffer,pos)1833d8817e4Smiod at (buffer, pos)
1843d8817e4Smiod string_type *buffer;
1853d8817e4Smiod unsigned int pos;
1863d8817e4Smiod {
1873d8817e4Smiod if (pos >= buffer->write_idx)
1883d8817e4Smiod return 0;
1893d8817e4Smiod return buffer->ptr[pos];
1903d8817e4Smiod }
1913d8817e4Smiod
1923d8817e4Smiod static void
catchar(buffer,ch)1933d8817e4Smiod catchar (buffer, ch)
1943d8817e4Smiod string_type *buffer;
1953d8817e4Smiod int ch;
1963d8817e4Smiod {
1973d8817e4Smiod if (buffer->write_idx == buffer->size)
1983d8817e4Smiod {
1993d8817e4Smiod buffer->size *= 2;
2003d8817e4Smiod buffer->ptr = realloc (buffer->ptr, buffer->size);
2013d8817e4Smiod }
2023d8817e4Smiod
2033d8817e4Smiod buffer->ptr[buffer->write_idx++] = ch;
2043d8817e4Smiod }
2053d8817e4Smiod
2063d8817e4Smiod static void
overwrite_string(dst,src)2073d8817e4Smiod overwrite_string (dst, src)
2083d8817e4Smiod string_type *dst;
2093d8817e4Smiod string_type *src;
2103d8817e4Smiod {
2113d8817e4Smiod free (dst->ptr);
2123d8817e4Smiod dst->size = src->size;
2133d8817e4Smiod dst->write_idx = src->write_idx;
2143d8817e4Smiod dst->ptr = src->ptr;
2153d8817e4Smiod }
2163d8817e4Smiod
2173d8817e4Smiod static void
catbuf(buffer,buf,len)2183d8817e4Smiod catbuf (buffer, buf, len)
2193d8817e4Smiod string_type *buffer;
2203d8817e4Smiod char *buf;
2213d8817e4Smiod unsigned int len;
2223d8817e4Smiod {
2233d8817e4Smiod if (buffer->write_idx + len >= buffer->size)
2243d8817e4Smiod {
2253d8817e4Smiod while (buffer->write_idx + len >= buffer->size)
2263d8817e4Smiod buffer->size *= 2;
2273d8817e4Smiod buffer->ptr = realloc (buffer->ptr, buffer->size);
2283d8817e4Smiod }
2293d8817e4Smiod memcpy (buffer->ptr + buffer->write_idx, buf, len);
2303d8817e4Smiod buffer->write_idx += len;
2313d8817e4Smiod }
2323d8817e4Smiod
2333d8817e4Smiod static void
cattext(buffer,string)2343d8817e4Smiod cattext (buffer, string)
2353d8817e4Smiod string_type *buffer;
2363d8817e4Smiod char *string;
2373d8817e4Smiod {
2383d8817e4Smiod catbuf (buffer, string, (unsigned int) strlen (string));
2393d8817e4Smiod }
2403d8817e4Smiod
2413d8817e4Smiod static void
catstr(dst,src)2423d8817e4Smiod catstr (dst, src)
2433d8817e4Smiod string_type *dst;
2443d8817e4Smiod string_type *src;
2453d8817e4Smiod {
2463d8817e4Smiod catbuf (dst, src->ptr, src->write_idx);
2473d8817e4Smiod }
2483d8817e4Smiod
2493d8817e4Smiod static unsigned int
skip_white_and_stars(src,idx)2503d8817e4Smiod skip_white_and_stars (src, idx)
2513d8817e4Smiod string_type *src;
2523d8817e4Smiod unsigned int idx;
2533d8817e4Smiod {
2543d8817e4Smiod char c;
2553d8817e4Smiod while ((c = at (src, idx)),
2563d8817e4Smiod isspace ((unsigned char) c)
2573d8817e4Smiod || (c == '*'
2583d8817e4Smiod /* Don't skip past end-of-comment or star as first
2593d8817e4Smiod character on its line. */
2603d8817e4Smiod && at (src, idx +1) != '/'
2613d8817e4Smiod && at (src, idx -1) != '\n'))
2623d8817e4Smiod idx++;
2633d8817e4Smiod return idx;
2643d8817e4Smiod }
2653d8817e4Smiod
2663d8817e4Smiod /***********************************************************************/
2673d8817e4Smiod
2683d8817e4Smiod string_type stack[STACK];
2693d8817e4Smiod string_type *tos;
2703d8817e4Smiod
2713d8817e4Smiod unsigned int idx = 0; /* Pos in input buffer */
2723d8817e4Smiod string_type *ptr; /* and the buffer */
2733d8817e4Smiod typedef void (*stinst_type)();
2743d8817e4Smiod stinst_type *pc;
2753d8817e4Smiod stinst_type sstack[STACK];
2763d8817e4Smiod stinst_type *ssp = &sstack[0];
2773d8817e4Smiod long istack[STACK];
2783d8817e4Smiod long *isp = &istack[0];
2793d8817e4Smiod
2803d8817e4Smiod typedef int *word_type;
2813d8817e4Smiod
2823d8817e4Smiod struct dict_struct
2833d8817e4Smiod {
2843d8817e4Smiod char *word;
2853d8817e4Smiod struct dict_struct *next;
2863d8817e4Smiod stinst_type *code;
2873d8817e4Smiod int code_length;
2883d8817e4Smiod int code_end;
2893d8817e4Smiod int var;
2903d8817e4Smiod };
2913d8817e4Smiod
2923d8817e4Smiod typedef struct dict_struct dict_type;
2933d8817e4Smiod
2943d8817e4Smiod static void
die(msg)2953d8817e4Smiod die (msg)
2963d8817e4Smiod char *msg;
2973d8817e4Smiod {
2983d8817e4Smiod fprintf (stderr, "%s\n", msg);
2993d8817e4Smiod exit (1);
3003d8817e4Smiod }
3013d8817e4Smiod
3023d8817e4Smiod static void
check_range()3033d8817e4Smiod check_range ()
3043d8817e4Smiod {
3053d8817e4Smiod if (tos < stack)
3063d8817e4Smiod die ("underflow in string stack");
3073d8817e4Smiod if (tos >= stack + STACK)
3083d8817e4Smiod die ("overflow in string stack");
3093d8817e4Smiod }
3103d8817e4Smiod
3113d8817e4Smiod static void
icheck_range()3123d8817e4Smiod icheck_range ()
3133d8817e4Smiod {
3143d8817e4Smiod if (isp < istack)
3153d8817e4Smiod die ("underflow in integer stack");
3163d8817e4Smiod if (isp >= istack + STACK)
3173d8817e4Smiod die ("overflow in integer stack");
3183d8817e4Smiod }
3193d8817e4Smiod
3203d8817e4Smiod #ifdef __STDC__
3213d8817e4Smiod static void exec (dict_type *);
3223d8817e4Smiod static void call (void);
3233d8817e4Smiod static void remchar (void), strip_trailing_newlines (void), push_number (void);
3243d8817e4Smiod static void push_text (void);
3253d8817e4Smiod static void remove_noncomments (string_type *, string_type *);
3263d8817e4Smiod static void print_stack_level (void);
3273d8817e4Smiod static void paramstuff (void), translatecomments (void);
3283d8817e4Smiod static void outputdots (void), courierize (void), bulletize (void);
3293d8817e4Smiod static void do_fancy_stuff (void);
3303d8817e4Smiod static int iscommand (string_type *, unsigned int);
3313d8817e4Smiod static int copy_past_newline (string_type *, unsigned int, string_type *);
3323d8817e4Smiod static void icopy_past_newline (void), kill_bogus_lines (void), indent (void);
3333d8817e4Smiod static void get_stuff_in_command (void), swap (void), other_dup (void);
3343d8817e4Smiod static void drop (void), idrop (void);
3353d8817e4Smiod static void icatstr (void), skip_past_newline (void), internalmode (void);
3363d8817e4Smiod static void maybecatstr (void);
3373d8817e4Smiod static char *nextword (char *, char **);
3383d8817e4Smiod dict_type *lookup_word (char *);
3393d8817e4Smiod static void perform (void);
3403d8817e4Smiod dict_type *newentry (char *);
3413d8817e4Smiod unsigned int add_to_definition (dict_type *, stinst_type);
3423d8817e4Smiod void add_intrinsic (char *, void (*)());
3433d8817e4Smiod void add_var (char *);
3443d8817e4Smiod void compile (char *);
3453d8817e4Smiod static void bang (void);
3463d8817e4Smiod static void atsign (void);
3473d8817e4Smiod static void hello (void);
3483d8817e4Smiod static void stdout_ (void);
3493d8817e4Smiod static void stderr_ (void);
3503d8817e4Smiod static void print (void);
3513d8817e4Smiod static void read_in (string_type *, FILE *);
3523d8817e4Smiod static void usage (void);
3533d8817e4Smiod static void chew_exit (void);
3543d8817e4Smiod #endif
3553d8817e4Smiod
3563d8817e4Smiod static void
exec(word)3573d8817e4Smiod exec (word)
3583d8817e4Smiod dict_type *word;
3593d8817e4Smiod {
3603d8817e4Smiod pc = word->code;
3613d8817e4Smiod while (*pc)
3623d8817e4Smiod (*pc) ();
3633d8817e4Smiod }
3643d8817e4Smiod
3653d8817e4Smiod static void
call()3663d8817e4Smiod call ()
3673d8817e4Smiod {
3683d8817e4Smiod stinst_type *oldpc = pc;
3693d8817e4Smiod dict_type *e;
3703d8817e4Smiod e = (dict_type *) (pc[1]);
3713d8817e4Smiod exec (e);
3723d8817e4Smiod pc = oldpc + 2;
3733d8817e4Smiod }
3743d8817e4Smiod
3753d8817e4Smiod static void
remchar()3763d8817e4Smiod remchar ()
3773d8817e4Smiod {
3783d8817e4Smiod if (tos->write_idx)
3793d8817e4Smiod tos->write_idx--;
3803d8817e4Smiod pc++;
3813d8817e4Smiod }
3823d8817e4Smiod
3833d8817e4Smiod static void
strip_trailing_newlines()3843d8817e4Smiod strip_trailing_newlines ()
3853d8817e4Smiod {
3863d8817e4Smiod while ((isspace ((unsigned char) at (tos, tos->write_idx - 1))
3873d8817e4Smiod || at (tos, tos->write_idx - 1) == '\n')
3883d8817e4Smiod && tos->write_idx > 0)
3893d8817e4Smiod tos->write_idx--;
3903d8817e4Smiod pc++;
3913d8817e4Smiod }
3923d8817e4Smiod
3933d8817e4Smiod static void
push_number()3943d8817e4Smiod push_number ()
3953d8817e4Smiod {
3963d8817e4Smiod isp++;
3973d8817e4Smiod icheck_range ();
3983d8817e4Smiod pc++;
3993d8817e4Smiod *isp = (long) (*pc);
4003d8817e4Smiod pc++;
4013d8817e4Smiod }
4023d8817e4Smiod
4033d8817e4Smiod static void
push_text()4043d8817e4Smiod push_text ()
4053d8817e4Smiod {
4063d8817e4Smiod tos++;
4073d8817e4Smiod check_range ();
4083d8817e4Smiod init_string (tos);
4093d8817e4Smiod pc++;
4103d8817e4Smiod cattext (tos, *((char **) pc));
4113d8817e4Smiod pc++;
4123d8817e4Smiod }
4133d8817e4Smiod
4143d8817e4Smiod /* This function removes everything not inside comments starting on
4153d8817e4Smiod the first char of the line from the string, also when copying
4163d8817e4Smiod comments, removes blank space and leading *'s.
4173d8817e4Smiod Blank lines are turned into one blank line. */
4183d8817e4Smiod
4193d8817e4Smiod static void
remove_noncomments(src,dst)4203d8817e4Smiod remove_noncomments (src, dst)
4213d8817e4Smiod string_type *src;
4223d8817e4Smiod string_type *dst;
4233d8817e4Smiod {
4243d8817e4Smiod unsigned int idx = 0;
4253d8817e4Smiod
4263d8817e4Smiod while (at (src, idx))
4273d8817e4Smiod {
4283d8817e4Smiod /* Now see if we have a comment at the start of the line. */
4293d8817e4Smiod if (at (src, idx) == '\n'
4303d8817e4Smiod && at (src, idx + 1) == '/'
4313d8817e4Smiod && at (src, idx + 2) == '*')
4323d8817e4Smiod {
4333d8817e4Smiod idx += 3;
4343d8817e4Smiod
4353d8817e4Smiod idx = skip_white_and_stars (src, idx);
4363d8817e4Smiod
4373d8817e4Smiod /* Remove leading dot */
4383d8817e4Smiod if (at (src, idx) == '.')
4393d8817e4Smiod idx++;
4403d8817e4Smiod
4413d8817e4Smiod /* Copy to the end of the line, or till the end of the
4423d8817e4Smiod comment. */
4433d8817e4Smiod while (at (src, idx))
4443d8817e4Smiod {
4453d8817e4Smiod if (at (src, idx) == '\n')
4463d8817e4Smiod {
4473d8817e4Smiod /* end of line, echo and scrape of leading blanks */
4483d8817e4Smiod if (at (src, idx + 1) == '\n')
4493d8817e4Smiod catchar (dst, '\n');
4503d8817e4Smiod catchar (dst, '\n');
4513d8817e4Smiod idx++;
4523d8817e4Smiod idx = skip_white_and_stars (src, idx);
4533d8817e4Smiod }
4543d8817e4Smiod else if (at (src, idx) == '*' && at (src, idx + 1) == '/')
4553d8817e4Smiod {
4563d8817e4Smiod idx += 2;
4573d8817e4Smiod cattext (dst, "\nENDDD\n");
4583d8817e4Smiod break;
4593d8817e4Smiod }
4603d8817e4Smiod else
4613d8817e4Smiod {
4623d8817e4Smiod catchar (dst, at (src, idx));
4633d8817e4Smiod idx++;
4643d8817e4Smiod }
4653d8817e4Smiod }
4663d8817e4Smiod }
4673d8817e4Smiod else
4683d8817e4Smiod idx++;
4693d8817e4Smiod }
4703d8817e4Smiod }
4713d8817e4Smiod
4723d8817e4Smiod static void
print_stack_level()4733d8817e4Smiod print_stack_level ()
4743d8817e4Smiod {
475*738f17d1Sderaadt fprintf (stderr, "current string stack depth = %ld, ", tos - stack);
476*738f17d1Sderaadt fprintf (stderr, "current integer stack depth = %ld\n", isp - istack);
4773d8817e4Smiod pc++;
4783d8817e4Smiod }
4793d8817e4Smiod
4803d8817e4Smiod /* turn:
4813d8817e4Smiod foobar name(stuff);
4823d8817e4Smiod into:
4833d8817e4Smiod foobar
4843d8817e4Smiod name PARAMS ((stuff));
4853d8817e4Smiod and a blank line.
4863d8817e4Smiod */
4873d8817e4Smiod
4883d8817e4Smiod static void
paramstuff()4893d8817e4Smiod paramstuff ()
4903d8817e4Smiod {
4913d8817e4Smiod unsigned int openp;
4923d8817e4Smiod unsigned int fname;
4933d8817e4Smiod unsigned int idx;
4943d8817e4Smiod unsigned int len;
4953d8817e4Smiod string_type out;
4963d8817e4Smiod init_string (&out);
4973d8817e4Smiod
4983d8817e4Smiod #define NO_PARAMS 1
4993d8817e4Smiod
5003d8817e4Smiod /* Make sure that it's not already param'd or proto'd. */
5013d8817e4Smiod if (NO_PARAMS
5023d8817e4Smiod || find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "("))
5033d8817e4Smiod {
5043d8817e4Smiod catstr (&out, tos);
5053d8817e4Smiod }
5063d8817e4Smiod else
5073d8817e4Smiod {
5083d8817e4Smiod /* Find the open paren. */
5093d8817e4Smiod for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++)
5103d8817e4Smiod ;
5113d8817e4Smiod
5123d8817e4Smiod fname = openp;
5133d8817e4Smiod /* Step back to the fname. */
5143d8817e4Smiod fname--;
5153d8817e4Smiod while (fname && isspace ((unsigned char) at (tos, fname)))
5163d8817e4Smiod fname--;
5173d8817e4Smiod while (fname
5183d8817e4Smiod && !isspace ((unsigned char) at (tos,fname))
5193d8817e4Smiod && at (tos,fname) != '*')
5203d8817e4Smiod fname--;
5213d8817e4Smiod
5223d8817e4Smiod fname++;
5233d8817e4Smiod
5243d8817e4Smiod /* Output type, omitting trailing whitespace character(s), if
5253d8817e4Smiod any. */
5263d8817e4Smiod for (len = fname; 0 < len; len--)
5273d8817e4Smiod {
5283d8817e4Smiod if (!isspace ((unsigned char) at (tos, len - 1)))
5293d8817e4Smiod break;
5303d8817e4Smiod }
5313d8817e4Smiod for (idx = 0; idx < len; idx++)
5323d8817e4Smiod catchar (&out, at (tos, idx));
5333d8817e4Smiod
5343d8817e4Smiod cattext (&out, "\n"); /* Insert a newline between type and fnname */
5353d8817e4Smiod
5363d8817e4Smiod /* Output function name, omitting trailing whitespace
5373d8817e4Smiod character(s), if any. */
5383d8817e4Smiod for (len = openp; 0 < len; len--)
5393d8817e4Smiod {
5403d8817e4Smiod if (!isspace ((unsigned char) at (tos, len - 1)))
5413d8817e4Smiod break;
5423d8817e4Smiod }
5433d8817e4Smiod for (idx = fname; idx < len; idx++)
5443d8817e4Smiod catchar (&out, at (tos, idx));
5453d8817e4Smiod
5463d8817e4Smiod cattext (&out, " PARAMS (");
5473d8817e4Smiod
5483d8817e4Smiod for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++)
5493d8817e4Smiod catchar (&out, at (tos, idx));
5503d8817e4Smiod
5513d8817e4Smiod cattext (&out, ");\n\n");
5523d8817e4Smiod }
5533d8817e4Smiod overwrite_string (tos, &out);
5543d8817e4Smiod pc++;
5553d8817e4Smiod
5563d8817e4Smiod }
5573d8817e4Smiod
5583d8817e4Smiod /* turn {*
5593d8817e4Smiod and *} into comments */
5603d8817e4Smiod
5613d8817e4Smiod static void
translatecomments()5623d8817e4Smiod translatecomments ()
5633d8817e4Smiod {
5643d8817e4Smiod unsigned int idx = 0;
5653d8817e4Smiod string_type out;
5663d8817e4Smiod init_string (&out);
5673d8817e4Smiod
5683d8817e4Smiod while (at (tos, idx))
5693d8817e4Smiod {
5703d8817e4Smiod if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
5713d8817e4Smiod {
5723d8817e4Smiod cattext (&out, "/*");
5733d8817e4Smiod idx += 2;
5743d8817e4Smiod }
5753d8817e4Smiod else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
5763d8817e4Smiod {
5773d8817e4Smiod cattext (&out, "*/");
5783d8817e4Smiod idx += 2;
5793d8817e4Smiod }
5803d8817e4Smiod else
5813d8817e4Smiod {
5823d8817e4Smiod catchar (&out, at (tos, idx));
5833d8817e4Smiod idx++;
5843d8817e4Smiod }
5853d8817e4Smiod }
5863d8817e4Smiod
5873d8817e4Smiod overwrite_string (tos, &out);
5883d8817e4Smiod
5893d8817e4Smiod pc++;
5903d8817e4Smiod }
5913d8817e4Smiod
5923d8817e4Smiod /* Mod tos so that only lines with leading dots remain */
5933d8817e4Smiod static void
outputdots()5943d8817e4Smiod outputdots ()
5953d8817e4Smiod {
5963d8817e4Smiod unsigned int idx = 0;
5973d8817e4Smiod string_type out;
5983d8817e4Smiod init_string (&out);
5993d8817e4Smiod
6003d8817e4Smiod while (at (tos, idx))
6013d8817e4Smiod {
6023d8817e4Smiod if (at (tos, idx) == '\n' && at (tos, idx + 1) == '.')
6033d8817e4Smiod {
6043d8817e4Smiod char c;
6053d8817e4Smiod idx += 2;
6063d8817e4Smiod
6073d8817e4Smiod while ((c = at (tos, idx)) && c != '\n')
6083d8817e4Smiod {
6093d8817e4Smiod if (c == '{' && at (tos, idx + 1) == '*')
6103d8817e4Smiod {
6113d8817e4Smiod cattext (&out, "/*");
6123d8817e4Smiod idx += 2;
6133d8817e4Smiod }
6143d8817e4Smiod else if (c == '*' && at (tos, idx + 1) == '}')
6153d8817e4Smiod {
6163d8817e4Smiod cattext (&out, "*/");
6173d8817e4Smiod idx += 2;
6183d8817e4Smiod }
6193d8817e4Smiod else
6203d8817e4Smiod {
6213d8817e4Smiod catchar (&out, c);
6223d8817e4Smiod idx++;
6233d8817e4Smiod }
6243d8817e4Smiod }
6253d8817e4Smiod catchar (&out, '\n');
6263d8817e4Smiod }
6273d8817e4Smiod else
6283d8817e4Smiod {
6293d8817e4Smiod idx++;
6303d8817e4Smiod }
6313d8817e4Smiod }
6323d8817e4Smiod
6333d8817e4Smiod overwrite_string (tos, &out);
6343d8817e4Smiod pc++;
6353d8817e4Smiod }
6363d8817e4Smiod
6373d8817e4Smiod /* Find lines starting with . and | and put example around them on tos */
6383d8817e4Smiod static void
courierize()6393d8817e4Smiod courierize ()
6403d8817e4Smiod {
6413d8817e4Smiod string_type out;
6423d8817e4Smiod unsigned int idx = 0;
6433d8817e4Smiod int command = 0;
6443d8817e4Smiod
6453d8817e4Smiod init_string (&out);
6463d8817e4Smiod
6473d8817e4Smiod while (at (tos, idx))
6483d8817e4Smiod {
6493d8817e4Smiod if (at (tos, idx) == '\n'
6503d8817e4Smiod && (at (tos, idx +1 ) == '.'
6513d8817e4Smiod || at (tos, idx + 1) == '|'))
6523d8817e4Smiod {
6533d8817e4Smiod cattext (&out, "\n@example\n");
6543d8817e4Smiod do
6553d8817e4Smiod {
6563d8817e4Smiod idx += 2;
6573d8817e4Smiod
6583d8817e4Smiod while (at (tos, idx) && at (tos, idx) != '\n')
6593d8817e4Smiod {
6603d8817e4Smiod if (command > 1)
6613d8817e4Smiod {
6623d8817e4Smiod /* We are inside {} parameters of some command;
6633d8817e4Smiod Just pass through until matching brace. */
6643d8817e4Smiod if (at (tos, idx) == '{')
6653d8817e4Smiod ++command;
6663d8817e4Smiod else if (at (tos, idx) == '}')
6673d8817e4Smiod --command;
6683d8817e4Smiod }
6693d8817e4Smiod else if (command != 0)
6703d8817e4Smiod {
6713d8817e4Smiod if (at (tos, idx) == '{')
6723d8817e4Smiod ++command;
6733d8817e4Smiod else if (!islower ((unsigned char) at (tos, idx)))
6743d8817e4Smiod --command;
6753d8817e4Smiod }
6763d8817e4Smiod else if (at (tos, idx) == '@'
6773d8817e4Smiod && islower ((unsigned char) at (tos, idx + 1)))
6783d8817e4Smiod {
6793d8817e4Smiod ++command;
6803d8817e4Smiod }
6813d8817e4Smiod else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
6823d8817e4Smiod {
6833d8817e4Smiod cattext (&out, "/*");
6843d8817e4Smiod idx += 2;
6853d8817e4Smiod continue;
6863d8817e4Smiod }
6873d8817e4Smiod else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
6883d8817e4Smiod {
6893d8817e4Smiod cattext (&out, "*/");
6903d8817e4Smiod idx += 2;
6913d8817e4Smiod continue;
6923d8817e4Smiod }
6933d8817e4Smiod else if (at (tos, idx) == '{'
6943d8817e4Smiod || at (tos, idx) == '}')
6953d8817e4Smiod {
6963d8817e4Smiod catchar (&out, '@');
6973d8817e4Smiod }
6983d8817e4Smiod
6993d8817e4Smiod catchar (&out, at (tos, idx));
7003d8817e4Smiod idx++;
7013d8817e4Smiod }
7023d8817e4Smiod catchar (&out, '\n');
7033d8817e4Smiod }
7043d8817e4Smiod while (at (tos, idx) == '\n'
7053d8817e4Smiod && ((at (tos, idx + 1) == '.')
7063d8817e4Smiod || (at (tos, idx + 1) == '|')))
7073d8817e4Smiod ;
7083d8817e4Smiod cattext (&out, "@end example");
7093d8817e4Smiod }
7103d8817e4Smiod else
7113d8817e4Smiod {
7123d8817e4Smiod catchar (&out, at (tos, idx));
7133d8817e4Smiod idx++;
7143d8817e4Smiod }
7153d8817e4Smiod }
7163d8817e4Smiod
7173d8817e4Smiod overwrite_string (tos, &out);
7183d8817e4Smiod pc++;
7193d8817e4Smiod }
7203d8817e4Smiod
7213d8817e4Smiod /* Finds any lines starting with "o ", if there are any, then turns
7223d8817e4Smiod on @itemize @bullet, and @items each of them. Then ends with @end
7233d8817e4Smiod itemize, inplace at TOS*/
7243d8817e4Smiod
7253d8817e4Smiod static void
bulletize()7263d8817e4Smiod bulletize ()
7273d8817e4Smiod {
7283d8817e4Smiod unsigned int idx = 0;
7293d8817e4Smiod int on = 0;
7303d8817e4Smiod string_type out;
7313d8817e4Smiod init_string (&out);
7323d8817e4Smiod
7333d8817e4Smiod while (at (tos, idx))
7343d8817e4Smiod {
7353d8817e4Smiod if (at (tos, idx) == '@'
7363d8817e4Smiod && at (tos, idx + 1) == '*')
7373d8817e4Smiod {
7383d8817e4Smiod cattext (&out, "*");
7393d8817e4Smiod idx += 2;
7403d8817e4Smiod }
7413d8817e4Smiod else if (at (tos, idx) == '\n'
7423d8817e4Smiod && at (tos, idx + 1) == 'o'
7433d8817e4Smiod && isspace ((unsigned char) at (tos, idx + 2)))
7443d8817e4Smiod {
7453d8817e4Smiod if (!on)
7463d8817e4Smiod {
7473d8817e4Smiod cattext (&out, "\n@itemize @bullet\n");
7483d8817e4Smiod on = 1;
7493d8817e4Smiod
7503d8817e4Smiod }
7513d8817e4Smiod cattext (&out, "\n@item\n");
7523d8817e4Smiod idx += 3;
7533d8817e4Smiod }
7543d8817e4Smiod else
7553d8817e4Smiod {
7563d8817e4Smiod catchar (&out, at (tos, idx));
7573d8817e4Smiod if (on && at (tos, idx) == '\n'
7583d8817e4Smiod && at (tos, idx + 1) == '\n'
7593d8817e4Smiod && at (tos, idx + 2) != 'o')
7603d8817e4Smiod {
7613d8817e4Smiod cattext (&out, "@end itemize");
7623d8817e4Smiod on = 0;
7633d8817e4Smiod }
7643d8817e4Smiod idx++;
7653d8817e4Smiod
7663d8817e4Smiod }
7673d8817e4Smiod }
7683d8817e4Smiod if (on)
7693d8817e4Smiod {
7703d8817e4Smiod cattext (&out, "@end itemize\n");
7713d8817e4Smiod }
7723d8817e4Smiod
7733d8817e4Smiod delete_string (tos);
7743d8817e4Smiod *tos = out;
7753d8817e4Smiod pc++;
7763d8817e4Smiod }
7773d8817e4Smiod
7783d8817e4Smiod /* Turn <<foo>> into @code{foo} in place at TOS*/
7793d8817e4Smiod
7803d8817e4Smiod static void
do_fancy_stuff()7813d8817e4Smiod do_fancy_stuff ()
7823d8817e4Smiod {
7833d8817e4Smiod unsigned int idx = 0;
7843d8817e4Smiod string_type out;
7853d8817e4Smiod init_string (&out);
7863d8817e4Smiod while (at (tos, idx))
7873d8817e4Smiod {
7883d8817e4Smiod if (at (tos, idx) == '<'
7893d8817e4Smiod && at (tos, idx + 1) == '<'
7903d8817e4Smiod && !isspace ((unsigned char) at (tos, idx + 2)))
7913d8817e4Smiod {
7923d8817e4Smiod /* This qualifies as a << startup. */
7933d8817e4Smiod idx += 2;
7943d8817e4Smiod cattext (&out, "@code{");
7953d8817e4Smiod while (at (tos, idx)
7963d8817e4Smiod && at (tos, idx) != '>' )
7973d8817e4Smiod {
7983d8817e4Smiod catchar (&out, at (tos, idx));
7993d8817e4Smiod idx++;
8003d8817e4Smiod
8013d8817e4Smiod }
8023d8817e4Smiod cattext (&out, "}");
8033d8817e4Smiod idx += 2;
8043d8817e4Smiod }
8053d8817e4Smiod else
8063d8817e4Smiod {
8073d8817e4Smiod catchar (&out, at (tos, idx));
8083d8817e4Smiod idx++;
8093d8817e4Smiod }
8103d8817e4Smiod }
8113d8817e4Smiod delete_string (tos);
8123d8817e4Smiod *tos = out;
8133d8817e4Smiod pc++;
8143d8817e4Smiod
8153d8817e4Smiod }
8163d8817e4Smiod
8173d8817e4Smiod /* A command is all upper case,and alone on a line. */
8183d8817e4Smiod
8193d8817e4Smiod static int
iscommand(ptr,idx)8203d8817e4Smiod iscommand (ptr, idx)
8213d8817e4Smiod string_type *ptr;
8223d8817e4Smiod unsigned int idx;
8233d8817e4Smiod {
8243d8817e4Smiod unsigned int len = 0;
8253d8817e4Smiod while (at (ptr, idx))
8263d8817e4Smiod {
8273d8817e4Smiod if (isupper ((unsigned char) at (ptr, idx))
8283d8817e4Smiod || at (ptr, idx) == ' ' || at (ptr, idx) == '_')
8293d8817e4Smiod {
8303d8817e4Smiod len++;
8313d8817e4Smiod idx++;
8323d8817e4Smiod }
8333d8817e4Smiod else if (at (ptr, idx) == '\n')
8343d8817e4Smiod {
8353d8817e4Smiod if (len > 3)
8363d8817e4Smiod return 1;
8373d8817e4Smiod return 0;
8383d8817e4Smiod }
8393d8817e4Smiod else
8403d8817e4Smiod return 0;
8413d8817e4Smiod }
8423d8817e4Smiod return 0;
8433d8817e4Smiod }
8443d8817e4Smiod
8453d8817e4Smiod static int
copy_past_newline(ptr,idx,dst)8463d8817e4Smiod copy_past_newline (ptr, idx, dst)
8473d8817e4Smiod string_type *ptr;
8483d8817e4Smiod unsigned int idx;
8493d8817e4Smiod string_type *dst;
8503d8817e4Smiod {
8513d8817e4Smiod int column = 0;
8523d8817e4Smiod
8533d8817e4Smiod while (at (ptr, idx) && at (ptr, idx) != '\n')
8543d8817e4Smiod {
8553d8817e4Smiod if (at (ptr, idx) == '\t')
8563d8817e4Smiod {
8573d8817e4Smiod /* Expand tabs. Neither makeinfo nor TeX can cope well with
8583d8817e4Smiod them. */
8593d8817e4Smiod do
8603d8817e4Smiod catchar (dst, ' ');
8613d8817e4Smiod while (++column & 7);
8623d8817e4Smiod }
8633d8817e4Smiod else
8643d8817e4Smiod {
8653d8817e4Smiod catchar (dst, at (ptr, idx));
8663d8817e4Smiod column++;
8673d8817e4Smiod }
8683d8817e4Smiod idx++;
8693d8817e4Smiod
8703d8817e4Smiod }
8713d8817e4Smiod catchar (dst, at (ptr, idx));
8723d8817e4Smiod idx++;
8733d8817e4Smiod return idx;
8743d8817e4Smiod
8753d8817e4Smiod }
8763d8817e4Smiod
8773d8817e4Smiod static void
icopy_past_newline()8783d8817e4Smiod icopy_past_newline ()
8793d8817e4Smiod {
8803d8817e4Smiod tos++;
8813d8817e4Smiod check_range ();
8823d8817e4Smiod init_string (tos);
8833d8817e4Smiod idx = copy_past_newline (ptr, idx, tos);
8843d8817e4Smiod pc++;
8853d8817e4Smiod }
8863d8817e4Smiod
8873d8817e4Smiod /* indent
8883d8817e4Smiod Take the string at the top of the stack, do some prettying. */
8893d8817e4Smiod
8903d8817e4Smiod static void
kill_bogus_lines()8913d8817e4Smiod kill_bogus_lines ()
8923d8817e4Smiod {
8933d8817e4Smiod int sl;
8943d8817e4Smiod
8953d8817e4Smiod int idx = 0;
8963d8817e4Smiod int c;
8973d8817e4Smiod int dot = 0;
8983d8817e4Smiod
8993d8817e4Smiod string_type out;
9003d8817e4Smiod init_string (&out);
9013d8817e4Smiod /* Drop leading nl. */
9023d8817e4Smiod while (at (tos, idx) == '\n')
9033d8817e4Smiod {
9043d8817e4Smiod idx++;
9053d8817e4Smiod }
9063d8817e4Smiod c = idx;
9073d8817e4Smiod
9083d8817e4Smiod /* If the first char is a '.' prepend a newline so that it is
9093d8817e4Smiod recognized properly later. */
9103d8817e4Smiod if (at (tos, idx) == '.')
9113d8817e4Smiod catchar (&out, '\n');
9123d8817e4Smiod
9133d8817e4Smiod /* Find the last char. */
9143d8817e4Smiod while (at (tos, idx))
9153d8817e4Smiod {
9163d8817e4Smiod idx++;
9173d8817e4Smiod }
9183d8817e4Smiod
9193d8817e4Smiod /* Find the last non white before the nl. */
9203d8817e4Smiod idx--;
9213d8817e4Smiod
9223d8817e4Smiod while (idx && isspace ((unsigned char) at (tos, idx)))
9233d8817e4Smiod idx--;
9243d8817e4Smiod idx++;
9253d8817e4Smiod
9263d8817e4Smiod /* Copy buffer upto last char, but blank lines before and after
9273d8817e4Smiod dots don't count. */
9283d8817e4Smiod sl = 1;
9293d8817e4Smiod
9303d8817e4Smiod while (c < idx)
9313d8817e4Smiod {
9323d8817e4Smiod if (at (tos, c) == '\n'
9333d8817e4Smiod && at (tos, c + 1) == '\n'
9343d8817e4Smiod && at (tos, c + 2) == '.')
9353d8817e4Smiod {
9363d8817e4Smiod /* Ignore two newlines before a dot. */
9373d8817e4Smiod c++;
9383d8817e4Smiod }
9393d8817e4Smiod else if (at (tos, c) == '.' && sl)
9403d8817e4Smiod {
9413d8817e4Smiod /* remember that this line started with a dot. */
9423d8817e4Smiod dot = 2;
9433d8817e4Smiod }
9443d8817e4Smiod else if (at (tos, c) == '\n'
9453d8817e4Smiod && at (tos, c + 1) == '\n'
9463d8817e4Smiod && dot)
9473d8817e4Smiod {
9483d8817e4Smiod c++;
9493d8817e4Smiod /* Ignore two newlines when last line was dot. */
9503d8817e4Smiod }
9513d8817e4Smiod
9523d8817e4Smiod catchar (&out, at (tos, c));
9533d8817e4Smiod if (at (tos, c) == '\n')
9543d8817e4Smiod {
9553d8817e4Smiod sl = 1;
9563d8817e4Smiod
9573d8817e4Smiod if (dot == 2)
9583d8817e4Smiod dot = 1;
9593d8817e4Smiod else
9603d8817e4Smiod dot = 0;
9613d8817e4Smiod }
9623d8817e4Smiod else
9633d8817e4Smiod sl = 0;
9643d8817e4Smiod
9653d8817e4Smiod c++;
9663d8817e4Smiod
9673d8817e4Smiod }
9683d8817e4Smiod
9693d8817e4Smiod /* Append nl. */
9703d8817e4Smiod catchar (&out, '\n');
9713d8817e4Smiod pc++;
9723d8817e4Smiod delete_string (tos);
9733d8817e4Smiod *tos = out;
9743d8817e4Smiod
9753d8817e4Smiod }
9763d8817e4Smiod
9773d8817e4Smiod static void
indent()9783d8817e4Smiod indent ()
9793d8817e4Smiod {
9803d8817e4Smiod string_type out;
9813d8817e4Smiod int tab = 0;
9823d8817e4Smiod int idx = 0;
9833d8817e4Smiod int ol = 0;
9843d8817e4Smiod init_string (&out);
9853d8817e4Smiod while (at (tos, idx))
9863d8817e4Smiod {
9873d8817e4Smiod switch (at (tos, idx))
9883d8817e4Smiod {
9893d8817e4Smiod case '\n':
9903d8817e4Smiod cattext (&out, "\n");
9913d8817e4Smiod idx++;
9923d8817e4Smiod if (tab && at (tos, idx))
9933d8817e4Smiod {
9943d8817e4Smiod cattext (&out, " ");
9953d8817e4Smiod }
9963d8817e4Smiod ol = 0;
9973d8817e4Smiod break;
9983d8817e4Smiod case '(':
9993d8817e4Smiod tab++;
10003d8817e4Smiod if (ol == 0)
10013d8817e4Smiod cattext (&out, " ");
10023d8817e4Smiod idx++;
10033d8817e4Smiod cattext (&out, "(");
10043d8817e4Smiod ol = 1;
10053d8817e4Smiod break;
10063d8817e4Smiod case ')':
10073d8817e4Smiod tab--;
10083d8817e4Smiod cattext (&out, ")");
10093d8817e4Smiod idx++;
10103d8817e4Smiod ol = 1;
10113d8817e4Smiod
10123d8817e4Smiod break;
10133d8817e4Smiod default:
10143d8817e4Smiod catchar (&out, at (tos, idx));
10153d8817e4Smiod ol = 1;
10163d8817e4Smiod
10173d8817e4Smiod idx++;
10183d8817e4Smiod break;
10193d8817e4Smiod }
10203d8817e4Smiod }
10213d8817e4Smiod
10223d8817e4Smiod pc++;
10233d8817e4Smiod delete_string (tos);
10243d8817e4Smiod *tos = out;
10253d8817e4Smiod
10263d8817e4Smiod }
10273d8817e4Smiod
10283d8817e4Smiod static void
get_stuff_in_command()10293d8817e4Smiod get_stuff_in_command ()
10303d8817e4Smiod {
10313d8817e4Smiod tos++;
10323d8817e4Smiod check_range ();
10333d8817e4Smiod init_string (tos);
10343d8817e4Smiod
10353d8817e4Smiod while (at (ptr, idx))
10363d8817e4Smiod {
10373d8817e4Smiod if (iscommand (ptr, idx))
10383d8817e4Smiod break;
10393d8817e4Smiod idx = copy_past_newline (ptr, idx, tos);
10403d8817e4Smiod }
10413d8817e4Smiod pc++;
10423d8817e4Smiod }
10433d8817e4Smiod
10443d8817e4Smiod static void
swap()10453d8817e4Smiod swap ()
10463d8817e4Smiod {
10473d8817e4Smiod string_type t;
10483d8817e4Smiod
10493d8817e4Smiod t = tos[0];
10503d8817e4Smiod tos[0] = tos[-1];
10513d8817e4Smiod tos[-1] = t;
10523d8817e4Smiod pc++;
10533d8817e4Smiod }
10543d8817e4Smiod
10553d8817e4Smiod static void
other_dup()10563d8817e4Smiod other_dup ()
10573d8817e4Smiod {
10583d8817e4Smiod tos++;
10593d8817e4Smiod check_range ();
10603d8817e4Smiod init_string (tos);
10613d8817e4Smiod catstr (tos, tos - 1);
10623d8817e4Smiod pc++;
10633d8817e4Smiod }
10643d8817e4Smiod
10653d8817e4Smiod static void
drop()10663d8817e4Smiod drop ()
10673d8817e4Smiod {
10683d8817e4Smiod tos--;
10693d8817e4Smiod check_range ();
10703d8817e4Smiod pc++;
10713d8817e4Smiod }
10723d8817e4Smiod
10733d8817e4Smiod static void
idrop()10743d8817e4Smiod idrop ()
10753d8817e4Smiod {
10763d8817e4Smiod isp--;
10773d8817e4Smiod icheck_range ();
10783d8817e4Smiod pc++;
10793d8817e4Smiod }
10803d8817e4Smiod
10813d8817e4Smiod static void
icatstr()10823d8817e4Smiod icatstr ()
10833d8817e4Smiod {
10843d8817e4Smiod tos--;
10853d8817e4Smiod check_range ();
10863d8817e4Smiod catstr (tos, tos + 1);
10873d8817e4Smiod delete_string (tos + 1);
10883d8817e4Smiod pc++;
10893d8817e4Smiod }
10903d8817e4Smiod
10913d8817e4Smiod static void
skip_past_newline()10923d8817e4Smiod skip_past_newline ()
10933d8817e4Smiod {
10943d8817e4Smiod while (at (ptr, idx)
10953d8817e4Smiod && at (ptr, idx) != '\n')
10963d8817e4Smiod idx++;
10973d8817e4Smiod idx++;
10983d8817e4Smiod pc++;
10993d8817e4Smiod }
11003d8817e4Smiod
11013d8817e4Smiod static void
internalmode()11023d8817e4Smiod internalmode ()
11033d8817e4Smiod {
11043d8817e4Smiod internal_mode = *(isp);
11053d8817e4Smiod isp--;
11063d8817e4Smiod icheck_range ();
11073d8817e4Smiod pc++;
11083d8817e4Smiod }
11093d8817e4Smiod
11103d8817e4Smiod static void
maybecatstr()11113d8817e4Smiod maybecatstr ()
11123d8817e4Smiod {
11133d8817e4Smiod if (internal_wanted == internal_mode)
11143d8817e4Smiod {
11153d8817e4Smiod catstr (tos - 1, tos);
11163d8817e4Smiod }
11173d8817e4Smiod delete_string (tos);
11183d8817e4Smiod tos--;
11193d8817e4Smiod check_range ();
11203d8817e4Smiod pc++;
11213d8817e4Smiod }
11223d8817e4Smiod
11233d8817e4Smiod char *
nextword(string,word)11243d8817e4Smiod nextword (string, word)
11253d8817e4Smiod char *string;
11263d8817e4Smiod char **word;
11273d8817e4Smiod {
11283d8817e4Smiod char *word_start;
11293d8817e4Smiod int idx;
11303d8817e4Smiod char *dst;
11313d8817e4Smiod char *src;
11323d8817e4Smiod
11333d8817e4Smiod int length = 0;
11343d8817e4Smiod
11353d8817e4Smiod while (isspace ((unsigned char) *string) || *string == '-')
11363d8817e4Smiod {
11373d8817e4Smiod if (*string == '-')
11383d8817e4Smiod {
11393d8817e4Smiod while (*string && *string != '\n')
11403d8817e4Smiod string++;
11413d8817e4Smiod
11423d8817e4Smiod }
11433d8817e4Smiod else
11443d8817e4Smiod {
11453d8817e4Smiod string++;
11463d8817e4Smiod }
11473d8817e4Smiod }
11483d8817e4Smiod if (!*string)
11493d8817e4Smiod return 0;
11503d8817e4Smiod
11513d8817e4Smiod word_start = string;
11523d8817e4Smiod if (*string == '"')
11533d8817e4Smiod {
11543d8817e4Smiod do
11553d8817e4Smiod {
11563d8817e4Smiod string++;
11573d8817e4Smiod length++;
11583d8817e4Smiod if (*string == '\\')
11593d8817e4Smiod {
11603d8817e4Smiod string += 2;
11613d8817e4Smiod length += 2;
11623d8817e4Smiod }
11633d8817e4Smiod }
11643d8817e4Smiod while (*string != '"');
11653d8817e4Smiod }
11663d8817e4Smiod else
11673d8817e4Smiod {
11683d8817e4Smiod while (!isspace ((unsigned char) *string))
11693d8817e4Smiod {
11703d8817e4Smiod string++;
11713d8817e4Smiod length++;
11723d8817e4Smiod
11733d8817e4Smiod }
11743d8817e4Smiod }
11753d8817e4Smiod
11763d8817e4Smiod *word = malloc (length + 1);
11773d8817e4Smiod
11783d8817e4Smiod dst = *word;
11793d8817e4Smiod src = word_start;
11803d8817e4Smiod
11813d8817e4Smiod for (idx = 0; idx < length; idx++)
11823d8817e4Smiod {
11833d8817e4Smiod if (src[idx] == '\\')
11843d8817e4Smiod switch (src[idx + 1])
11853d8817e4Smiod {
11863d8817e4Smiod case 'n':
11873d8817e4Smiod *dst++ = '\n';
11883d8817e4Smiod idx++;
11893d8817e4Smiod break;
11903d8817e4Smiod case '"':
11913d8817e4Smiod case '\\':
11923d8817e4Smiod *dst++ = src[idx + 1];
11933d8817e4Smiod idx++;
11943d8817e4Smiod break;
11953d8817e4Smiod default:
11963d8817e4Smiod *dst++ = '\\';
11973d8817e4Smiod break;
11983d8817e4Smiod }
11993d8817e4Smiod else
12003d8817e4Smiod *dst++ = src[idx];
12013d8817e4Smiod }
12023d8817e4Smiod *dst++ = 0;
12033d8817e4Smiod
12043d8817e4Smiod if (*string)
12053d8817e4Smiod return string + 1;
12063d8817e4Smiod else
12073d8817e4Smiod return 0;
12083d8817e4Smiod }
12093d8817e4Smiod
12103d8817e4Smiod dict_type *root;
12113d8817e4Smiod
12123d8817e4Smiod dict_type *
lookup_word(word)12133d8817e4Smiod lookup_word (word)
12143d8817e4Smiod char *word;
12153d8817e4Smiod {
12163d8817e4Smiod dict_type *ptr = root;
12173d8817e4Smiod while (ptr)
12183d8817e4Smiod {
12193d8817e4Smiod if (strcmp (ptr->word, word) == 0)
12203d8817e4Smiod return ptr;
12213d8817e4Smiod ptr = ptr->next;
12223d8817e4Smiod }
12233d8817e4Smiod if (warning)
12243d8817e4Smiod fprintf (stderr, "Can't find %s\n", word);
12253d8817e4Smiod return 0;
12263d8817e4Smiod }
12273d8817e4Smiod
12283d8817e4Smiod static void
perform()12293d8817e4Smiod perform ()
12303d8817e4Smiod {
12313d8817e4Smiod tos = stack;
12323d8817e4Smiod
12333d8817e4Smiod while (at (ptr, idx))
12343d8817e4Smiod {
12353d8817e4Smiod /* It's worth looking through the command list. */
12363d8817e4Smiod if (iscommand (ptr, idx))
12373d8817e4Smiod {
12383d8817e4Smiod char *next;
12393d8817e4Smiod dict_type *word;
12403d8817e4Smiod
12413d8817e4Smiod (void) nextword (addr (ptr, idx), &next);
12423d8817e4Smiod
12433d8817e4Smiod word = lookup_word (next);
12443d8817e4Smiod
12453d8817e4Smiod if (word)
12463d8817e4Smiod {
12473d8817e4Smiod exec (word);
12483d8817e4Smiod }
12493d8817e4Smiod else
12503d8817e4Smiod {
12513d8817e4Smiod if (warning)
12523d8817e4Smiod fprintf (stderr, "warning, %s is not recognised\n", next);
12533d8817e4Smiod skip_past_newline ();
12543d8817e4Smiod }
12553d8817e4Smiod
12563d8817e4Smiod }
12573d8817e4Smiod else
12583d8817e4Smiod skip_past_newline ();
12593d8817e4Smiod }
12603d8817e4Smiod }
12613d8817e4Smiod
12623d8817e4Smiod dict_type *
newentry(word)12633d8817e4Smiod newentry (word)
12643d8817e4Smiod char *word;
12653d8817e4Smiod {
12663d8817e4Smiod dict_type *new = (dict_type *) malloc (sizeof (dict_type));
12673d8817e4Smiod new->word = word;
12683d8817e4Smiod new->next = root;
12693d8817e4Smiod root = new;
12703d8817e4Smiod new->code = (stinst_type *) malloc (sizeof (stinst_type));
12713d8817e4Smiod new->code_length = 1;
12723d8817e4Smiod new->code_end = 0;
12733d8817e4Smiod return new;
12743d8817e4Smiod }
12753d8817e4Smiod
12763d8817e4Smiod unsigned int
add_to_definition(entry,word)12773d8817e4Smiod add_to_definition (entry, word)
12783d8817e4Smiod dict_type *entry;
12793d8817e4Smiod stinst_type word;
12803d8817e4Smiod {
12813d8817e4Smiod if (entry->code_end == entry->code_length)
12823d8817e4Smiod {
12833d8817e4Smiod entry->code_length += 2;
12843d8817e4Smiod entry->code =
12853d8817e4Smiod (stinst_type *) realloc ((char *) (entry->code),
12863d8817e4Smiod entry->code_length * sizeof (word_type));
12873d8817e4Smiod }
12883d8817e4Smiod entry->code[entry->code_end] = word;
12893d8817e4Smiod
12903d8817e4Smiod return entry->code_end++;
12913d8817e4Smiod }
12923d8817e4Smiod
12933d8817e4Smiod void
add_intrinsic(name,func)12943d8817e4Smiod add_intrinsic (name, func)
12953d8817e4Smiod char *name;
12963d8817e4Smiod void (*func) ();
12973d8817e4Smiod {
12983d8817e4Smiod dict_type *new = newentry (name);
12993d8817e4Smiod add_to_definition (new, func);
13003d8817e4Smiod add_to_definition (new, 0);
13013d8817e4Smiod }
13023d8817e4Smiod
13033d8817e4Smiod void
add_var(name)13043d8817e4Smiod add_var (name)
13053d8817e4Smiod char *name;
13063d8817e4Smiod {
13073d8817e4Smiod dict_type *new = newentry (name);
13083d8817e4Smiod add_to_definition (new, push_number);
13093d8817e4Smiod add_to_definition (new, (stinst_type) (&(new->var)));
13103d8817e4Smiod add_to_definition (new, 0);
13113d8817e4Smiod }
13123d8817e4Smiod
13133d8817e4Smiod void
compile(string)13143d8817e4Smiod compile (string)
13153d8817e4Smiod char *string;
13163d8817e4Smiod {
13173d8817e4Smiod /* Add words to the dictionary. */
13183d8817e4Smiod char *word;
13193d8817e4Smiod string = nextword (string, &word);
13203d8817e4Smiod while (string && *string && word[0])
13213d8817e4Smiod {
13223d8817e4Smiod if (strcmp (word, "var") == 0)
13233d8817e4Smiod {
13243d8817e4Smiod string = nextword (string, &word);
13253d8817e4Smiod
13263d8817e4Smiod add_var (word);
13273d8817e4Smiod string = nextword (string, &word);
13283d8817e4Smiod }
13293d8817e4Smiod else if (word[0] == ':')
13303d8817e4Smiod {
13313d8817e4Smiod dict_type *ptr;
13323d8817e4Smiod /* Compile a word and add to dictionary. */
13333d8817e4Smiod string = nextword (string, &word);
13343d8817e4Smiod
13353d8817e4Smiod ptr = newentry (word);
13363d8817e4Smiod string = nextword (string, &word);
13373d8817e4Smiod while (word[0] != ';')
13383d8817e4Smiod {
13393d8817e4Smiod switch (word[0])
13403d8817e4Smiod {
13413d8817e4Smiod case '"':
13423d8817e4Smiod /* got a string, embed magic push string
13433d8817e4Smiod function */
13443d8817e4Smiod add_to_definition (ptr, push_text);
13453d8817e4Smiod add_to_definition (ptr, (stinst_type) (word + 1));
13463d8817e4Smiod break;
13473d8817e4Smiod case '0':
13483d8817e4Smiod case '1':
13493d8817e4Smiod case '2':
13503d8817e4Smiod case '3':
13513d8817e4Smiod case '4':
13523d8817e4Smiod case '5':
13533d8817e4Smiod case '6':
13543d8817e4Smiod case '7':
13553d8817e4Smiod case '8':
13563d8817e4Smiod case '9':
13573d8817e4Smiod /* Got a number, embedd the magic push number
13583d8817e4Smiod function */
13593d8817e4Smiod add_to_definition (ptr, push_number);
13603d8817e4Smiod add_to_definition (ptr, (stinst_type) atol (word));
13613d8817e4Smiod break;
13623d8817e4Smiod default:
13633d8817e4Smiod add_to_definition (ptr, call);
13643d8817e4Smiod add_to_definition (ptr, (stinst_type) lookup_word (word));
13653d8817e4Smiod }
13663d8817e4Smiod
13673d8817e4Smiod string = nextword (string, &word);
13683d8817e4Smiod }
13693d8817e4Smiod add_to_definition (ptr, 0);
13703d8817e4Smiod string = nextword (string, &word);
13713d8817e4Smiod }
13723d8817e4Smiod else
13733d8817e4Smiod {
13743d8817e4Smiod fprintf (stderr, "syntax error at %s\n", string - 1);
13753d8817e4Smiod }
13763d8817e4Smiod }
13773d8817e4Smiod }
13783d8817e4Smiod
13793d8817e4Smiod static void
bang()13803d8817e4Smiod bang ()
13813d8817e4Smiod {
13823d8817e4Smiod *(long *) ((isp[0])) = isp[-1];
13833d8817e4Smiod isp -= 2;
13843d8817e4Smiod icheck_range ();
13853d8817e4Smiod pc++;
13863d8817e4Smiod }
13873d8817e4Smiod
13883d8817e4Smiod static void
atsign()13893d8817e4Smiod atsign ()
13903d8817e4Smiod {
13913d8817e4Smiod isp[0] = *(long *) (isp[0]);
13923d8817e4Smiod pc++;
13933d8817e4Smiod }
13943d8817e4Smiod
13953d8817e4Smiod static void
hello()13963d8817e4Smiod hello ()
13973d8817e4Smiod {
13983d8817e4Smiod printf ("hello\n");
13993d8817e4Smiod pc++;
14003d8817e4Smiod }
14013d8817e4Smiod
14023d8817e4Smiod static void
stdout_()14033d8817e4Smiod stdout_ ()
14043d8817e4Smiod {
14053d8817e4Smiod isp++;
14063d8817e4Smiod icheck_range ();
14073d8817e4Smiod *isp = 1;
14083d8817e4Smiod pc++;
14093d8817e4Smiod }
14103d8817e4Smiod
14113d8817e4Smiod static void
stderr_()14123d8817e4Smiod stderr_ ()
14133d8817e4Smiod {
14143d8817e4Smiod isp++;
14153d8817e4Smiod icheck_range ();
14163d8817e4Smiod *isp = 2;
14173d8817e4Smiod pc++;
14183d8817e4Smiod }
14193d8817e4Smiod
14203d8817e4Smiod static void
print()14213d8817e4Smiod print ()
14223d8817e4Smiod {
14233d8817e4Smiod if (*isp == 1)
14243d8817e4Smiod write_buffer (tos, stdout);
14253d8817e4Smiod else if (*isp == 2)
14263d8817e4Smiod write_buffer (tos, stderr);
14273d8817e4Smiod else
14283d8817e4Smiod fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
14293d8817e4Smiod isp--;
14303d8817e4Smiod tos--;
14313d8817e4Smiod icheck_range ();
14323d8817e4Smiod check_range ();
14333d8817e4Smiod pc++;
14343d8817e4Smiod }
14353d8817e4Smiod
14363d8817e4Smiod static void
read_in(str,file)14373d8817e4Smiod read_in (str, file)
14383d8817e4Smiod string_type *str;
14393d8817e4Smiod FILE *file;
14403d8817e4Smiod {
14413d8817e4Smiod char buff[10000];
14423d8817e4Smiod unsigned int r;
14433d8817e4Smiod do
14443d8817e4Smiod {
14453d8817e4Smiod r = fread (buff, 1, sizeof (buff), file);
14463d8817e4Smiod catbuf (str, buff, r);
14473d8817e4Smiod }
14483d8817e4Smiod while (r);
14493d8817e4Smiod buff[0] = 0;
14503d8817e4Smiod
14513d8817e4Smiod catbuf (str, buff, 1);
14523d8817e4Smiod }
14533d8817e4Smiod
14543d8817e4Smiod static void
usage()14553d8817e4Smiod usage ()
14563d8817e4Smiod {
14573d8817e4Smiod fprintf (stderr, "usage: -[d|i|g] <file >file\n");
14583d8817e4Smiod exit (33);
14593d8817e4Smiod }
14603d8817e4Smiod
14613d8817e4Smiod /* There is no reliable way to declare exit. Sometimes it returns
14623d8817e4Smiod int, and sometimes it returns void. Sometimes it changes between
14633d8817e4Smiod OS releases. Trying to get it declared correctly in the hosts file
14643d8817e4Smiod is a pointless waste of time. */
14653d8817e4Smiod
14663d8817e4Smiod static void
chew_exit()14673d8817e4Smiod chew_exit ()
14683d8817e4Smiod {
14693d8817e4Smiod exit (0);
14703d8817e4Smiod }
14713d8817e4Smiod
14723d8817e4Smiod int
main(ac,av)14733d8817e4Smiod main (ac, av)
14743d8817e4Smiod int ac;
14753d8817e4Smiod char *av[];
14763d8817e4Smiod {
14773d8817e4Smiod unsigned int i;
14783d8817e4Smiod string_type buffer;
14793d8817e4Smiod string_type pptr;
14803d8817e4Smiod
14813d8817e4Smiod init_string (&buffer);
14823d8817e4Smiod init_string (&pptr);
14833d8817e4Smiod init_string (stack + 0);
14843d8817e4Smiod tos = stack + 1;
14853d8817e4Smiod ptr = &pptr;
14863d8817e4Smiod
14873d8817e4Smiod add_intrinsic ("push_text", push_text);
14883d8817e4Smiod add_intrinsic ("!", bang);
14893d8817e4Smiod add_intrinsic ("@", atsign);
14903d8817e4Smiod add_intrinsic ("hello", hello);
14913d8817e4Smiod add_intrinsic ("stdout", stdout_);
14923d8817e4Smiod add_intrinsic ("stderr", stderr_);
14933d8817e4Smiod add_intrinsic ("print", print);
14943d8817e4Smiod add_intrinsic ("skip_past_newline", skip_past_newline);
14953d8817e4Smiod add_intrinsic ("catstr", icatstr);
14963d8817e4Smiod add_intrinsic ("copy_past_newline", icopy_past_newline);
14973d8817e4Smiod add_intrinsic ("dup", other_dup);
14983d8817e4Smiod add_intrinsic ("drop", drop);
14993d8817e4Smiod add_intrinsic ("idrop", idrop);
15003d8817e4Smiod add_intrinsic ("remchar", remchar);
15013d8817e4Smiod add_intrinsic ("get_stuff_in_command", get_stuff_in_command);
15023d8817e4Smiod add_intrinsic ("do_fancy_stuff", do_fancy_stuff);
15033d8817e4Smiod add_intrinsic ("bulletize", bulletize);
15043d8817e4Smiod add_intrinsic ("courierize", courierize);
15053d8817e4Smiod /* If the following line gives an error, exit() is not declared in the
15063d8817e4Smiod ../hosts/foo.h file for this host. Fix it there, not here! */
15073d8817e4Smiod /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */
15083d8817e4Smiod add_intrinsic ("exit", chew_exit);
15093d8817e4Smiod add_intrinsic ("swap", swap);
15103d8817e4Smiod add_intrinsic ("outputdots", outputdots);
15113d8817e4Smiod add_intrinsic ("paramstuff", paramstuff);
15123d8817e4Smiod add_intrinsic ("maybecatstr", maybecatstr);
15133d8817e4Smiod add_intrinsic ("translatecomments", translatecomments);
15143d8817e4Smiod add_intrinsic ("kill_bogus_lines", kill_bogus_lines);
15153d8817e4Smiod add_intrinsic ("indent", indent);
15163d8817e4Smiod add_intrinsic ("internalmode", internalmode);
15173d8817e4Smiod add_intrinsic ("print_stack_level", print_stack_level);
15183d8817e4Smiod add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines);
15193d8817e4Smiod
15203d8817e4Smiod /* Put a nl at the start. */
15213d8817e4Smiod catchar (&buffer, '\n');
15223d8817e4Smiod
15233d8817e4Smiod read_in (&buffer, stdin);
15243d8817e4Smiod remove_noncomments (&buffer, ptr);
15253d8817e4Smiod for (i = 1; i < (unsigned int) ac; i++)
15263d8817e4Smiod {
15273d8817e4Smiod if (av[i][0] == '-')
15283d8817e4Smiod {
15293d8817e4Smiod if (av[i][1] == 'f')
15303d8817e4Smiod {
15313d8817e4Smiod string_type b;
15323d8817e4Smiod FILE *f;
15333d8817e4Smiod init_string (&b);
15343d8817e4Smiod
15353d8817e4Smiod f = fopen (av[i + 1], "r");
15363d8817e4Smiod if (!f)
15373d8817e4Smiod {
15383d8817e4Smiod fprintf (stderr, "Can't open the input file %s\n",
15393d8817e4Smiod av[i + 1]);
15403d8817e4Smiod return 33;
15413d8817e4Smiod }
15423d8817e4Smiod
15433d8817e4Smiod read_in (&b, f);
15443d8817e4Smiod compile (b.ptr);
15453d8817e4Smiod perform ();
15463d8817e4Smiod }
15473d8817e4Smiod else if (av[i][1] == 'i')
15483d8817e4Smiod {
15493d8817e4Smiod internal_wanted = 1;
15503d8817e4Smiod }
15513d8817e4Smiod else if (av[i][1] == 'w')
15523d8817e4Smiod {
15533d8817e4Smiod warning = 1;
15543d8817e4Smiod }
15553d8817e4Smiod else
15563d8817e4Smiod usage ();
15573d8817e4Smiod }
15583d8817e4Smiod }
15593d8817e4Smiod write_buffer (stack + 0, stdout);
15603d8817e4Smiod if (tos != stack)
15613d8817e4Smiod {
1562*738f17d1Sderaadt fprintf (stderr, "finishing with current stack level %ld\n",
15633d8817e4Smiod tos - stack);
15643d8817e4Smiod return 1;
15653d8817e4Smiod }
15663d8817e4Smiod return 0;
15673d8817e4Smiod }
1568