diff options
Diffstat (limited to 'contrib/binutils/bfd/doc/chew.c')
-rw-r--r-- | contrib/binutils/bfd/doc/chew.c | 1605 |
1 files changed, 0 insertions, 1605 deletions
diff --git a/contrib/binutils/bfd/doc/chew.c b/contrib/binutils/bfd/doc/chew.c deleted file mode 100644 index 7c060da2d1cb..000000000000 --- a/contrib/binutils/bfd/doc/chew.c +++ /dev/null @@ -1,1605 +0,0 @@ -/* chew - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, - 2002, 2003 - Free Software Foundation, Inc. - Contributed by steve chamberlain @cygnus - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Yet another way of extracting documentation from source. - No, I haven't finished it yet, but I hope you people like it better - than the old way - - sac - - Basically, this is a sort of string forth, maybe we should call it - struth? - - You define new words thus: - : <newword> <oldwords> ; - -*/ - -/* Primitives provided by the program: - - Two stacks are provided, a string stack and an integer stack. - - Internal state variables: - internal_wanted - indicates whether `-i' was passed - internal_mode - user-settable - - Commands: - push_text - ! - pop top of integer stack for address, pop next for value; store - @ - treat value on integer stack as the address of an integer; push - that integer on the integer stack after popping the "address" - hello - print "hello\n" to stdout - stdout - put stdout marker on TOS - stderr - put stderr marker on TOS - print - print TOS-1 on TOS (eg: "hello\n" stdout print) - skip_past_newline - catstr - fn icatstr - copy_past_newline - append input, up to and including newline into TOS - dup - fn other_dup - drop - discard TOS - idrop - ditto - remchar - delete last character from TOS - get_stuff_in_command - do_fancy_stuff - translate <<foo>> to @code{foo} in TOS - bulletize - if "o" lines found, prepend @itemize @bullet to TOS - and @item to each "o" line; append @end itemize - courierize - put @example around . and | lines, translate {* *} { } - exit - fn chew_exit - swap - outputdots - strip out lines without leading dots - paramstuff - convert full declaration into "PARAMS" form if not already - maybecatstr - do catstr if internal_mode == internal_wanted, discard - value in any case - translatecomments - turn {* and *} into comment delimiters - kill_bogus_lines - get rid of extra newlines - indent - internalmode - pop from integer stack, set `internalmode' to that value - print_stack_level - print current stack depth to stderr - strip_trailing_newlines - go ahead, guess... - [quoted string] - push string onto string stack - [word starting with digit] - push atol(str) onto integer stack - - A command must be all upper-case, and alone on a line. - - Foo. */ - -#include "ansidecl.h" -#include "sysdep.h" -#include <assert.h> -#include <stdio.h> -#include <ctype.h> - -#define DEF_SIZE 5000 -#define STACK 50 - -int internal_wanted; -int internal_mode; - -int warning; - -/* Here is a string type ... */ - -typedef struct buffer -{ - char *ptr; - unsigned long write_idx; - unsigned long size; -} string_type; - -#ifdef __STDC__ -static void init_string_with_size (string_type *, unsigned int); -static void init_string (string_type *); -static int find (string_type *, char *); -static void write_buffer (string_type *, FILE *); -static void delete_string (string_type *); -static char *addr (string_type *, unsigned int); -static char at (string_type *, unsigned int); -static void catchar (string_type *, int); -static void overwrite_string (string_type *, string_type *); -static void catbuf (string_type *, char *, unsigned int); -static void cattext (string_type *, char *); -static void catstr (string_type *, string_type *); -#endif - -static void -init_string_with_size (buffer, size) - string_type *buffer; - unsigned int size; -{ - buffer->write_idx = 0; - buffer->size = size; - buffer->ptr = malloc (size); -} - -static void -init_string (buffer) - string_type *buffer; -{ - init_string_with_size (buffer, DEF_SIZE); -} - -static int -find (str, what) - string_type *str; - char *what; -{ - unsigned int i; - char *p; - p = what; - for (i = 0; i < str->write_idx && *p; i++) - { - if (*p == str->ptr[i]) - p++; - else - p = what; - } - return (*p == 0); -} - -static void -write_buffer (buffer, f) - string_type *buffer; - FILE *f; -{ - fwrite (buffer->ptr, buffer->write_idx, 1, f); -} - -static void -delete_string (buffer) - string_type *buffer; -{ - free (buffer->ptr); -} - -static char * -addr (buffer, idx) - string_type *buffer; - unsigned int idx; -{ - return buffer->ptr + idx; -} - -static char -at (buffer, pos) - string_type *buffer; - unsigned int pos; -{ - if (pos >= buffer->write_idx) - return 0; - return buffer->ptr[pos]; -} - -static void -catchar (buffer, ch) - string_type *buffer; - int ch; -{ - if (buffer->write_idx == buffer->size) - { - buffer->size *= 2; - buffer->ptr = realloc (buffer->ptr, buffer->size); - } - - buffer->ptr[buffer->write_idx++] = ch; -} - -static void -overwrite_string (dst, src) - string_type *dst; - string_type *src; -{ - free (dst->ptr); - dst->size = src->size; - dst->write_idx = src->write_idx; - dst->ptr = src->ptr; -} - -static void -catbuf (buffer, buf, len) - string_type *buffer; - char *buf; - unsigned int len; -{ - if (buffer->write_idx + len >= buffer->size) - { - while (buffer->write_idx + len >= buffer->size) - buffer->size *= 2; - buffer->ptr = realloc (buffer->ptr, buffer->size); - } - memcpy (buffer->ptr + buffer->write_idx, buf, len); - buffer->write_idx += len; -} - -static void -cattext (buffer, string) - string_type *buffer; - char *string; -{ - catbuf (buffer, string, (unsigned int) strlen (string)); -} - -static void -catstr (dst, src) - string_type *dst; - string_type *src; -{ - catbuf (dst, src->ptr, src->write_idx); -} - -static unsigned int -skip_white_and_stars (src, idx) - string_type *src; - unsigned int idx; -{ - char c; - while ((c = at (src, idx)), - isspace ((unsigned char) c) - || (c == '*' - /* Don't skip past end-of-comment or star as first - character on its line. */ - && at (src, idx +1) != '/' - && at (src, idx -1) != '\n')) - idx++; - return idx; -} - -/***********************************************************************/ - -string_type stack[STACK]; -string_type *tos; - -unsigned int idx = 0; /* Pos in input buffer */ -string_type *ptr; /* and the buffer */ -typedef void (*stinst_type)(); -stinst_type *pc; -stinst_type sstack[STACK]; -stinst_type *ssp = &sstack[0]; -long istack[STACK]; -long *isp = &istack[0]; - -typedef int *word_type; - -struct dict_struct -{ - char *word; - struct dict_struct *next; - stinst_type *code; - int code_length; - int code_end; - int var; -}; - -typedef struct dict_struct dict_type; - -static void -die (msg) - char *msg; -{ - fprintf (stderr, "%s\n", msg); - exit (1); -} - -static void -check_range () -{ - if (tos < stack) - die ("underflow in string stack"); - if (tos >= stack + STACK) - die ("overflow in string stack"); -} - -static void -icheck_range () -{ - if (isp < istack) - die ("underflow in integer stack"); - if (isp >= istack + STACK) - die ("overflow in integer stack"); -} - -#ifdef __STDC__ -static void exec (dict_type *); -static void call (void); -static void remchar (void), strip_trailing_newlines (void), push_number (void); -static void push_text (void); -static void remove_noncomments (string_type *, string_type *); -static void print_stack_level (void); -static void paramstuff (void), translatecomments (void); -static void outputdots (void), courierize (void), bulletize (void); -static void do_fancy_stuff (void); -static int iscommand (string_type *, unsigned int); -static int copy_past_newline (string_type *, unsigned int, string_type *); -static void icopy_past_newline (void), kill_bogus_lines (void), indent (void); -static void get_stuff_in_command (void), swap (void), other_dup (void); -static void drop (void), idrop (void); -static void icatstr (void), skip_past_newline (void), internalmode (void); -static void maybecatstr (void); -static char *nextword (char *, char **); -dict_type *lookup_word (char *); -static void perform (void); -dict_type *newentry (char *); -unsigned int add_to_definition (dict_type *, stinst_type); -void add_intrinsic (char *, void (*)()); -void add_var (char *); -void compile (char *); -static void bang (void); -static void atsign (void); -static void hello (void); -static void stdout_ (void); -static void stderr_ (void); -static void print (void); -static void read_in (string_type *, FILE *); -static void usage (void); -static void chew_exit (void); -#endif - -static void -exec (word) - dict_type *word; -{ - pc = word->code; - while (*pc) - (*pc) (); -} - -static void -call () -{ - stinst_type *oldpc = pc; - dict_type *e; - e = (dict_type *) (pc[1]); - exec (e); - pc = oldpc + 2; -} - -static void -remchar () -{ - if (tos->write_idx) - tos->write_idx--; - pc++; -} - -static void -strip_trailing_newlines () -{ - while ((isspace ((unsigned char) at (tos, tos->write_idx - 1)) - || at (tos, tos->write_idx - 1) == '\n') - && tos->write_idx > 0) - tos->write_idx--; - pc++; -} - -static void -push_number () -{ - isp++; - icheck_range (); - pc++; - *isp = (long) (*pc); - pc++; -} - -static void -push_text () -{ - tos++; - check_range (); - init_string (tos); - pc++; - cattext (tos, *((char **) pc)); - pc++; -} - -/* This function removes everything not inside comments starting on - the first char of the line from the string, also when copying - comments, removes blank space and leading *'s. - Blank lines are turned into one blank line. */ - -static void -remove_noncomments (src, dst) - string_type *src; - string_type *dst; -{ - unsigned int idx = 0; - - while (at (src, idx)) - { - /* Now see if we have a comment at the start of the line. */ - if (at (src, idx) == '\n' - && at (src, idx + 1) == '/' - && at (src, idx + 2) == '*') - { - idx += 3; - - idx = skip_white_and_stars (src, idx); - - /* Remove leading dot */ - if (at (src, idx) == '.') - idx++; - - /* Copy to the end of the line, or till the end of the - comment. */ - while (at (src, idx)) - { - if (at (src, idx) == '\n') - { - /* end of line, echo and scrape of leading blanks */ - if (at (src, idx + 1) == '\n') - catchar (dst, '\n'); - catchar (dst, '\n'); - idx++; - idx = skip_white_and_stars (src, idx); - } - else if (at (src, idx) == '*' && at (src, idx + 1) == '/') - { - idx += 2; - cattext (dst, "\nENDDD\n"); - break; - } - else - { - catchar (dst, at (src, idx)); - idx++; - } - } - } - else - idx++; - } -} - -static void -print_stack_level () -{ - fprintf (stderr, "current string stack depth = %d, ", tos - stack); - fprintf (stderr, "current integer stack depth = %d\n", isp - istack); - pc++; -} - -/* turn: - foobar name(stuff); - into: - foobar - name PARAMS ((stuff)); - and a blank line. - */ - -static void -paramstuff () -{ - unsigned int openp; - unsigned int fname; - unsigned int idx; - unsigned int len; - string_type out; - init_string (&out); - -#define NO_PARAMS 1 - - /* Make sure that it's not already param'd or proto'd. */ - if (NO_PARAMS - || find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "(")) - { - catstr (&out, tos); - } - else - { - /* Find the open paren. */ - for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++) - ; - - fname = openp; - /* Step back to the fname. */ - fname--; - while (fname && isspace ((unsigned char) at (tos, fname))) - fname--; - while (fname - && !isspace ((unsigned char) at (tos,fname)) - && at (tos,fname) != '*') - fname--; - - fname++; - - /* Output type, omitting trailing whitespace character(s), if - any. */ - for (len = fname; 0 < len; len--) - { - if (!isspace ((unsigned char) at (tos, len - 1))) - break; - } - for (idx = 0; idx < len; idx++) - catchar (&out, at (tos, idx)); - - cattext (&out, "\n"); /* Insert a newline between type and fnname */ - - /* Output function name, omitting trailing whitespace - character(s), if any. */ - for (len = openp; 0 < len; len--) - { - if (!isspace ((unsigned char) at (tos, len - 1))) - break; - } - for (idx = fname; idx < len; idx++) - catchar (&out, at (tos, idx)); - - cattext (&out, " PARAMS ("); - - for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++) - catchar (&out, at (tos, idx)); - - cattext (&out, ");\n\n"); - } - overwrite_string (tos, &out); - pc++; - -} - -/* turn {* - and *} into comments */ - -static void -translatecomments () -{ - unsigned int idx = 0; - string_type out; - init_string (&out); - - while (at (tos, idx)) - { - if (at (tos, idx) == '{' && at (tos, idx + 1) == '*') - { - cattext (&out, "/*"); - idx += 2; - } - else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}') - { - cattext (&out, "*/"); - idx += 2; - } - else - { - catchar (&out, at (tos, idx)); - idx++; - } - } - - overwrite_string (tos, &out); - - pc++; -} - -#if 0 - -/* This is not currently used. */ - -/* turn everything not starting with a . into a comment */ - -static void -manglecomments () -{ - unsigned int idx = 0; - string_type out; - init_string (&out); - - while (at (tos, idx)) - { - if (at (tos, idx) == '\n' && at (tos, idx + 1) == '*') - { - cattext (&out, " /*"); - idx += 2; - } - else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}') - { - cattext (&out, "*/"); - idx += 2; - } - else - { - catchar (&out, at (tos, idx)); - idx++; - } - } - - overwrite_string (tos, &out); - - pc++; -} - -#endif - -/* Mod tos so that only lines with leading dots remain */ -static void -outputdots () -{ - unsigned int idx = 0; - string_type out; - init_string (&out); - - while (at (tos, idx)) - { - if (at (tos, idx) == '\n' && at (tos, idx + 1) == '.') - { - char c; - idx += 2; - - while ((c = at (tos, idx)) && c != '\n') - { - if (c == '{' && at (tos, idx + 1) == '*') - { - cattext (&out, "/*"); - idx += 2; - } - else if (c == '*' && at (tos, idx + 1) == '}') - { - cattext (&out, "*/"); - idx += 2; - } - else - { - catchar (&out, c); - idx++; - } - } - catchar (&out, '\n'); - } - else - { - idx++; - } - } - - overwrite_string (tos, &out); - pc++; -} - -/* Find lines starting with . and | and put example around them on tos */ -static void -courierize () -{ - string_type out; - unsigned int idx = 0; - int command = 0; - - init_string (&out); - - while (at (tos, idx)) - { - if (at (tos, idx) == '\n' - && (at (tos, idx +1 ) == '.' - || at (tos, idx + 1) == '|')) - { - cattext (&out, "\n@example\n"); - do - { - idx += 2; - - while (at (tos, idx) && at (tos, idx) != '\n') - { - if (command > 1) - { - /* We are inside {} parameters of some command; - Just pass through until matching brace. */ - if (at (tos, idx) == '{') - ++command; - else if (at (tos, idx) == '}') - --command; - } - else if (command != 0) - { - if (at (tos, idx) == '{') - ++command; - else if (!islower ((unsigned char) at (tos, idx))) - --command; - } - else if (at (tos, idx) == '@' - && islower ((unsigned char) at (tos, idx + 1))) - { - ++command; - } - else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*') - { - cattext (&out, "/*"); - idx += 2; - continue; - } - else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}') - { - cattext (&out, "*/"); - idx += 2; - continue; - } - else if (at (tos, idx) == '{' - || at (tos, idx) == '}') - { - catchar (&out, '@'); - } - - catchar (&out, at (tos, idx)); - idx++; - } - catchar (&out, '\n'); - } - while (at (tos, idx) == '\n' - && ((at (tos, idx + 1) == '.') - || (at (tos, idx + 1) == '|'))) - ; - cattext (&out, "@end example"); - } - else - { - catchar (&out, at (tos, idx)); - idx++; - } - } - - overwrite_string (tos, &out); - pc++; -} - -/* Finds any lines starting with "o ", if there are any, then turns - on @itemize @bullet, and @items each of them. Then ends with @end - itemize, inplace at TOS*/ - -static void -bulletize () -{ - unsigned int idx = 0; - int on = 0; - string_type out; - init_string (&out); - - while (at (tos, idx)) - { - if (at (tos, idx) == '@' - && at (tos, idx + 1) == '*') - { - cattext (&out, "*"); - idx += 2; - } - else if (at (tos, idx) == '\n' - && at (tos, idx + 1) == 'o' - && isspace ((unsigned char) at (tos, idx + 2))) - { - if (!on) - { - cattext (&out, "\n@itemize @bullet\n"); - on = 1; - - } - cattext (&out, "\n@item\n"); - idx += 3; - } - else - { - catchar (&out, at (tos, idx)); - if (on && at (tos, idx) == '\n' - && at (tos, idx + 1) == '\n' - && at (tos, idx + 2) != 'o') - { - cattext (&out, "@end itemize"); - on = 0; - } - idx++; - - } - } - if (on) - { - cattext (&out, "@end itemize\n"); - } - - delete_string (tos); - *tos = out; - pc++; -} - -/* Turn <<foo>> into @code{foo} in place at TOS*/ - -static void -do_fancy_stuff () -{ - unsigned int idx = 0; - string_type out; - init_string (&out); - while (at (tos, idx)) - { - if (at (tos, idx) == '<' - && at (tos, idx + 1) == '<' - && !isspace ((unsigned char) at (tos, idx + 2))) - { - /* This qualifies as a << startup. */ - idx += 2; - cattext (&out, "@code{"); - while (at (tos, idx) - && at (tos, idx) != '>' ) - { - catchar (&out, at (tos, idx)); - idx++; - - } - cattext (&out, "}"); - idx += 2; - } - else - { - catchar (&out, at (tos, idx)); - idx++; - } - } - delete_string (tos); - *tos = out; - pc++; - -} - -/* A command is all upper case,and alone on a line. */ - -static int -iscommand (ptr, idx) - string_type *ptr; - unsigned int idx; -{ - unsigned int len = 0; - while (at (ptr, idx)) - { - if (isupper ((unsigned char) at (ptr, idx)) - || at (ptr, idx) == ' ' || at (ptr, idx) == '_') - { - len++; - idx++; - } - else if (at (ptr, idx) == '\n') - { - if (len > 3) - return 1; - return 0; - } - else - return 0; - } - return 0; -} - -static int -copy_past_newline (ptr, idx, dst) - string_type *ptr; - unsigned int idx; - string_type *dst; -{ - int column = 0; - - while (at (ptr, idx) && at (ptr, idx) != '\n') - { - if (at (ptr, idx) == '\t') - { - /* Expand tabs. Neither makeinfo nor TeX can cope well with - them. */ - do - catchar (dst, ' '); - while (++column & 7); - } - else - { - catchar (dst, at (ptr, idx)); - column++; - } - idx++; - - } - catchar (dst, at (ptr, idx)); - idx++; - return idx; - -} - -static void -icopy_past_newline () -{ - tos++; - check_range (); - init_string (tos); - idx = copy_past_newline (ptr, idx, tos); - pc++; -} - -/* indent - Take the string at the top of the stack, do some prettying. */ - -static void -kill_bogus_lines () -{ - int sl; - - int idx = 0; - int c; - int dot = 0; - - string_type out; - init_string (&out); - /* Drop leading nl. */ - while (at (tos, idx) == '\n') - { - idx++; - } - c = idx; - - /* If the first char is a '.' prepend a newline so that it is - recognized properly later. */ - if (at (tos, idx) == '.') - catchar (&out, '\n'); - - /* Find the last char. */ - while (at (tos, idx)) - { - idx++; - } - - /* Find the last non white before the nl. */ - idx--; - - while (idx && isspace ((unsigned char) at (tos, idx))) - idx--; - idx++; - - /* Copy buffer upto last char, but blank lines before and after - dots don't count. */ - sl = 1; - - while (c < idx) - { - if (at (tos, c) == '\n' - && at (tos, c + 1) == '\n' - && at (tos, c + 2) == '.') - { - /* Ignore two newlines before a dot. */ - c++; - } - else if (at (tos, c) == '.' && sl) - { - /* remember that this line started with a dot. */ - dot = 2; - } - else if (at (tos, c) == '\n' - && at (tos, c + 1) == '\n' - && dot) - { - c++; - /* Ignore two newlines when last line was dot. */ - } - - catchar (&out, at (tos, c)); - if (at (tos, c) == '\n') - { - sl = 1; - - if (dot == 2) - dot = 1; - else - dot = 0; - } - else - sl = 0; - - c++; - - } - - /* Append nl. */ - catchar (&out, '\n'); - pc++; - delete_string (tos); - *tos = out; - -} - -static void -indent () -{ - string_type out; - int tab = 0; - int idx = 0; - int ol = 0; - init_string (&out); - while (at (tos, idx)) - { - switch (at (tos, idx)) - { - case '\n': - cattext (&out, "\n"); - idx++; - if (tab && at (tos, idx)) - { - cattext (&out, " "); - } - ol = 0; - break; - case '(': - tab++; - if (ol == 0) - cattext (&out, " "); - idx++; - cattext (&out, "("); - ol = 1; - break; - case ')': - tab--; - cattext (&out, ")"); - idx++; - ol = 1; - - break; - default: - catchar (&out, at (tos, idx)); - ol = 1; - - idx++; - break; - } - } - - pc++; - delete_string (tos); - *tos = out; - -} - -static void -get_stuff_in_command () -{ - tos++; - check_range (); - init_string (tos); - - while (at (ptr, idx)) - { - if (iscommand (ptr, idx)) - break; - idx = copy_past_newline (ptr, idx, tos); - } - pc++; -} - -static void -swap () -{ - string_type t; - - t = tos[0]; - tos[0] = tos[-1]; - tos[-1] = t; - pc++; -} - -static void -other_dup () -{ - tos++; - check_range (); - init_string (tos); - catstr (tos, tos - 1); - pc++; -} - -static void -drop () -{ - tos--; - check_range (); - pc++; -} - -static void -idrop () -{ - isp--; - icheck_range (); - pc++; -} - -static void -icatstr () -{ - tos--; - check_range (); - catstr (tos, tos + 1); - delete_string (tos + 1); - pc++; -} - -static void -skip_past_newline () -{ - while (at (ptr, idx) - && at (ptr, idx) != '\n') - idx++; - idx++; - pc++; -} - -static void -internalmode () -{ - internal_mode = *(isp); - isp--; - icheck_range (); - pc++; -} - -static void -maybecatstr () -{ - if (internal_wanted == internal_mode) - { - catstr (tos - 1, tos); - } - delete_string (tos); - tos--; - check_range (); - pc++; -} - -char * -nextword (string, word) - char *string; - char **word; -{ - char *word_start; - int idx; - char *dst; - char *src; - - int length = 0; - - while (isspace ((unsigned char) *string) || *string == '-') - { - if (*string == '-') - { - while (*string && *string != '\n') - string++; - - } - else - { - string++; - } - } - if (!*string) - return 0; - - word_start = string; - if (*string == '"') - { - do - { - string++; - length++; - if (*string == '\\') - { - string += 2; - length += 2; - } - } - while (*string != '"'); - } - else - { - while (!isspace ((unsigned char) *string)) - { - string++; - length++; - - } - } - - *word = malloc (length + 1); - - dst = *word; - src = word_start; - - for (idx = 0; idx < length; idx++) - { - if (src[idx] == '\\') - switch (src[idx + 1]) - { - case 'n': - *dst++ = '\n'; - idx++; - break; - case '"': - case '\\': - *dst++ = src[idx + 1]; - idx++; - break; - default: - *dst++ = '\\'; - break; - } - else - *dst++ = src[idx]; - } - *dst++ = 0; - - if (*string) - return string + 1; - else - return 0; -} - -dict_type *root; - -dict_type * -lookup_word (word) - char *word; -{ - dict_type *ptr = root; - while (ptr) - { - if (strcmp (ptr->word, word) == 0) - return ptr; - ptr = ptr->next; - } - if (warning) - fprintf (stderr, "Can't find %s\n", word); - return 0; -} - -static void -perform () -{ - tos = stack; - - while (at (ptr, idx)) - { - /* It's worth looking through the command list. */ - if (iscommand (ptr, idx)) - { - char *next; - dict_type *word; - - (void) nextword (addr (ptr, idx), &next); - - word = lookup_word (next); - - if (word) - { - exec (word); - } - else - { - if (warning) - fprintf (stderr, "warning, %s is not recognised\n", next); - skip_past_newline (); - } - - } - else - skip_past_newline (); - } -} - -dict_type * -newentry (word) - char *word; -{ - dict_type *new = (dict_type *) malloc (sizeof (dict_type)); - new->word = word; - new->next = root; - root = new; - new->code = (stinst_type *) malloc (sizeof (stinst_type)); - new->code_length = 1; - new->code_end = 0; - return new; -} - -unsigned int -add_to_definition (entry, word) - dict_type *entry; - stinst_type word; -{ - if (entry->code_end == entry->code_length) - { - entry->code_length += 2; - entry->code = - (stinst_type *) realloc ((char *) (entry->code), - entry->code_length * sizeof (word_type)); - } - entry->code[entry->code_end] = word; - - return entry->code_end++; -} - -void -add_intrinsic (name, func) - char *name; - void (*func) (); -{ - dict_type *new = newentry (name); - add_to_definition (new, func); - add_to_definition (new, 0); -} - -void -add_var (name) - char *name; -{ - dict_type *new = newentry (name); - add_to_definition (new, push_number); - add_to_definition (new, (stinst_type) (&(new->var))); - add_to_definition (new, 0); -} - -void -compile (string) - char *string; -{ - /* Add words to the dictionary. */ - char *word; - string = nextword (string, &word); - while (string && *string && word[0]) - { - if (strcmp (word, "var") == 0) - { - string = nextword (string, &word); - - add_var (word); - string = nextword (string, &word); - } - else if (word[0] == ':') - { - dict_type *ptr; - /* Compile a word and add to dictionary. */ - string = nextword (string, &word); - - ptr = newentry (word); - string = nextword (string, &word); - while (word[0] != ';') - { - switch (word[0]) - { - case '"': - /* got a string, embed magic push string - function */ - add_to_definition (ptr, push_text); - add_to_definition (ptr, (stinst_type) (word + 1)); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* Got a number, embedd the magic push number - function */ - add_to_definition (ptr, push_number); - add_to_definition (ptr, (stinst_type) atol (word)); - break; - default: - add_to_definition (ptr, call); - add_to_definition (ptr, (stinst_type) lookup_word (word)); - } - - string = nextword (string, &word); - } - add_to_definition (ptr, 0); - string = nextword (string, &word); - } - else - { - fprintf (stderr, "syntax error at %s\n", string - 1); - } - } -} - -static void -bang () -{ - *(long *) ((isp[0])) = isp[-1]; - isp -= 2; - icheck_range (); - pc++; -} - -static void -atsign () -{ - isp[0] = *(long *) (isp[0]); - pc++; -} - -static void -hello () -{ - printf ("hello\n"); - pc++; -} - -static void -stdout_ () -{ - isp++; - icheck_range (); - *isp = 1; - pc++; -} - -static void -stderr_ () -{ - isp++; - icheck_range (); - *isp = 2; - pc++; -} - -static void -print () -{ - if (*isp == 1) - write_buffer (tos, stdout); - else if (*isp == 2) - write_buffer (tos, stderr); - else - fprintf (stderr, "print: illegal print destination `%ld'\n", *isp); - isp--; - tos--; - icheck_range (); - check_range (); - pc++; -} - -static void -read_in (str, file) - string_type *str; - FILE *file; -{ - char buff[10000]; - unsigned int r; - do - { - r = fread (buff, 1, sizeof (buff), file); - catbuf (str, buff, r); - } - while (r); - buff[0] = 0; - - catbuf (str, buff, 1); -} - -static void -usage () -{ - fprintf (stderr, "usage: -[d|i|g] <file >file\n"); - exit (33); -} - -/* There is no reliable way to declare exit. Sometimes it returns - int, and sometimes it returns void. Sometimes it changes between - OS releases. Trying to get it declared correctly in the hosts file - is a pointless waste of time. */ - -static void -chew_exit () -{ - exit (0); -} - -int -main (ac, av) - int ac; - char *av[]; -{ - unsigned int i; - string_type buffer; - string_type pptr; - - init_string (&buffer); - init_string (&pptr); - init_string (stack + 0); - tos = stack + 1; - ptr = &pptr; - - add_intrinsic ("push_text", push_text); - add_intrinsic ("!", bang); - add_intrinsic ("@", atsign); - add_intrinsic ("hello", hello); - add_intrinsic ("stdout", stdout_); - add_intrinsic ("stderr", stderr_); - add_intrinsic ("print", print); - add_intrinsic ("skip_past_newline", skip_past_newline); - add_intrinsic ("catstr", icatstr); - add_intrinsic ("copy_past_newline", icopy_past_newline); - add_intrinsic ("dup", other_dup); - add_intrinsic ("drop", drop); - add_intrinsic ("idrop", idrop); - add_intrinsic ("remchar", remchar); - add_intrinsic ("get_stuff_in_command", get_stuff_in_command); - add_intrinsic ("do_fancy_stuff", do_fancy_stuff); - add_intrinsic ("bulletize", bulletize); - add_intrinsic ("courierize", courierize); - /* If the following line gives an error, exit() is not declared in the - ../hosts/foo.h file for this host. Fix it there, not here! */ - /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */ - add_intrinsic ("exit", chew_exit); - add_intrinsic ("swap", swap); - add_intrinsic ("outputdots", outputdots); - add_intrinsic ("paramstuff", paramstuff); - add_intrinsic ("maybecatstr", maybecatstr); - add_intrinsic ("translatecomments", translatecomments); - add_intrinsic ("kill_bogus_lines", kill_bogus_lines); - add_intrinsic ("indent", indent); - add_intrinsic ("internalmode", internalmode); - add_intrinsic ("print_stack_level", print_stack_level); - add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines); - - /* Put a nl at the start. */ - catchar (&buffer, '\n'); - - read_in (&buffer, stdin); - remove_noncomments (&buffer, ptr); - for (i = 1; i < (unsigned int) ac; i++) - { - if (av[i][0] == '-') - { - if (av[i][1] == 'f') - { - string_type b; - FILE *f; - init_string (&b); - - f = fopen (av[i + 1], "r"); - if (!f) - { - fprintf (stderr, "Can't open the input file %s\n", - av[i + 1]); - return 33; - } - - read_in (&b, f); - compile (b.ptr); - perform (); - } - else if (av[i][1] == 'i') - { - internal_wanted = 1; - } - else if (av[i][1] == 'w') - { - warning = 1; - } - else - usage (); - } - } - write_buffer (stack + 0, stdout); - if (tos != stack) - { - fprintf (stderr, "finishing with current stack level %d\n", - tos - stack); - return 1; - } - return 0; -} |