/* chew
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2022 Free Software Foundation, Inc.
Contributed by steve chamberlain @cygnus
This file is part of BFD, the Binary File Descriptor library.
Foo. */
-#include "ansidecl.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
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 *);
-static void die (char *);
-#endif
+/* Compiled programs consist of arrays of these. */
+
+typedef union
+{
+ void (*f) (void);
+ struct dict_struct *e;
+ char *s;
+ long l;
+} pcu;
+
+typedef struct dict_struct
+{
+ char *word;
+ struct dict_struct *next;
+ pcu *code;
+ int code_length;
+ int code_end;
+} dict_type;
+
+int internal_wanted;
+int internal_mode;
+
+int warning;
+
+string_type stack[STACK];
+string_type *tos;
+
+unsigned int idx = 0; /* Pos in input buffer */
+string_type *ptr; /* and the buffer */
+
+long istack[STACK];
+long *isp = &istack[0];
+
+dict_type *root;
+
+pcu *pc;
static void
-init_string_with_size (buffer, size)
- string_type *buffer;
- unsigned int size;
+die (char *msg)
+{
+ fprintf (stderr, "%s\n", msg);
+ exit (1);
+}
+
+void *
+xmalloc (size_t size)
+{
+ void *newmem;
+
+ if (size == 0)
+ size = 1;
+ newmem = malloc (size);
+ if (!newmem)
+ die ("out of memory");
+
+ return newmem;
+}
+
+void *
+xrealloc (void *oldmem, size_t size)
+{
+ void *newmem;
+
+ if (size == 0)
+ size = 1;
+ if (!oldmem)
+ newmem = malloc (size);
+ else
+ newmem = realloc (oldmem, size);
+ if (!newmem)
+ die ("out of memory");
+
+ return newmem;
+}
+
+char *
+xstrdup (const char *s)
+{
+ size_t len = strlen (s) + 1;
+ char *ret = xmalloc (len);
+ return memcpy (ret, s, len);
+}
+
+static void
+init_string_with_size (string_type *buffer, unsigned int size)
{
buffer->write_idx = 0;
buffer->size = size;
- buffer->ptr = (char *) malloc (size);
+ buffer->ptr = xmalloc (size);
}
static void
-init_string (buffer)
- string_type *buffer;
+init_string (string_type *buffer)
{
init_string_with_size (buffer, DEF_SIZE);
}
static int
-find (str, what)
- string_type *str;
- char *what;
+find (string_type *str, char *what)
{
unsigned int i;
char *p;
}
static void
-write_buffer (buffer, f)
- string_type *buffer;
- FILE *f;
+write_buffer (string_type *buffer, FILE *f)
{
if (buffer->write_idx != 0
&& fwrite (buffer->ptr, buffer->write_idx, 1, f) != 1)
}
static void
-delete_string (buffer)
- string_type *buffer;
+delete_string (string_type *buffer)
{
free (buffer->ptr);
+ buffer->ptr = NULL;
}
static char *
-addr (buffer, idx)
- string_type *buffer;
- unsigned int idx;
+addr (string_type *buffer, unsigned int idx)
{
return buffer->ptr + idx;
}
static char
-at (buffer, pos)
- string_type *buffer;
- unsigned int pos;
+at (string_type *buffer, unsigned int pos)
{
if (pos >= buffer->write_idx)
return 0;
}
static void
-catchar (buffer, ch)
- string_type *buffer;
- int ch;
+catchar (string_type *buffer, int ch)
{
if (buffer->write_idx == buffer->size)
{
buffer->size *= 2;
- buffer->ptr = (char *) realloc (buffer->ptr, buffer->size);
+ buffer->ptr = xrealloc (buffer->ptr, buffer->size);
}
buffer->ptr[buffer->write_idx++] = ch;
}
static void
-overwrite_string (dst, src)
- string_type *dst;
- string_type *src;
+overwrite_string (string_type *dst, string_type *src)
{
free (dst->ptr);
dst->size = src->size;
}
static void
-catbuf (buffer, buf, len)
- string_type *buffer;
- char *buf;
- unsigned int len;
+catbuf (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 = (char *) realloc (buffer->ptr, buffer->size);
+ buffer->ptr = xrealloc (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;
+cattext (string_type *buffer, char *string)
{
catbuf (buffer, string, (unsigned int) strlen (string));
}
static void
-catstr (dst, src)
- string_type *dst;
- string_type *src;
+catstr (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;
+skip_white_and_stars (string_type *src, unsigned int idx)
{
char c;
while ((c = at (src, idx)),
}
static unsigned int
-skip_past_newline_1 (ptr, idx)
- string_type *ptr;
- unsigned int idx;
+skip_past_newline_1 (string_type *ptr, unsigned int idx)
{
while (at (ptr, idx)
&& at (ptr, idx) != '\n')
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 ()
+check_range (void)
{
if (tos < stack)
die ("underflow in string stack");
}
static void
-icheck_range ()
+icheck_range (void)
{
if (isp < istack)
die ("underflow in integer 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;
+exec (dict_type *word)
{
pc = word->code;
- while (*pc)
- (*pc) ();
+ while (pc->f)
+ pc->f ();
}
static void
-call ()
+call (void)
{
- stinst_type *oldpc = pc;
- dict_type *e;
- e = (dict_type *) (pc[1]);
+ pcu *oldpc = pc;
+ dict_type *e = pc[1].e;
exec (e);
pc = oldpc + 2;
}
static void
-remchar ()
+remchar (void)
{
if (tos->write_idx)
tos->write_idx--;
}
static void
-strip_trailing_newlines ()
+strip_trailing_newlines (void)
{
while ((isspace ((unsigned char) at (tos, tos->write_idx - 1))
|| at (tos, tos->write_idx - 1) == '\n')
}
static void
-push_number ()
+push_number (void)
{
isp++;
icheck_range ();
pc++;
- *isp = (long) (*pc);
+ *isp = pc->l;
pc++;
}
static void
-push_text ()
+push_text (void)
{
tos++;
check_range ();
init_string (tos);
pc++;
- cattext (tos, *((char **) pc));
+ cattext (tos, pc->s);
pc++;
}
Blank lines are turned into one blank line. */
static void
-remove_noncomments (src, dst)
- string_type *src;
- string_type *dst;
+remove_noncomments (string_type *src, string_type *dst)
{
unsigned int idx = 0;
}
static void
-print_stack_level ()
+print_stack_level (void)
{
fprintf (stderr, "current string stack depth = %ld, ",
(long) (tos - stack));
*/
static void
-paramstuff ()
+paramstuff (void)
{
unsigned int openp;
unsigned int fname;
and *} into comments */
static void
-translatecomments ()
+translatecomments (void)
{
unsigned int idx = 0;
string_type out;
/* Mod tos so that only lines with leading dots remain */
static void
-outputdots ()
+outputdots (void)
{
unsigned int idx = 0;
string_type out;
/* Find lines starting with . and | and put example around them on tos */
static void
-courierize ()
+courierize (void)
{
string_type out;
unsigned int idx = 0;
itemize, inplace at TOS*/
static void
-bulletize ()
+bulletize (void)
{
unsigned int idx = 0;
int on = 0;
/* Turn <<foo>> into @code{foo} in place at TOS*/
static void
-do_fancy_stuff ()
+do_fancy_stuff (void)
{
unsigned int idx = 0;
string_type out;
/* A command is all upper case,and alone on a line. */
static int
-iscommand (ptr, idx)
- string_type *ptr;
- unsigned int idx;
+iscommand (string_type *ptr, unsigned int idx)
{
unsigned int len = 0;
while (at (ptr, idx))
}
static int
-copy_past_newline (ptr, idx, dst)
- string_type *ptr;
- unsigned int idx;
- string_type *dst;
+copy_past_newline (string_type *ptr, unsigned int idx, string_type *dst)
{
int column = 0;
}
static void
-icopy_past_newline ()
+icopy_past_newline (void)
{
tos++;
check_range ();
Take the string at the top of the stack, do some prettying. */
static void
-kill_bogus_lines ()
+kill_bogus_lines (void)
{
int sl;
}
static void
-indent ()
+indent (void)
{
string_type out;
int tab = 0;
}
static void
-get_stuff_in_command ()
+get_stuff_in_command (void)
{
tos++;
check_range ();
}
static void
-swap ()
+swap (void)
{
string_type t;
}
static void
-other_dup ()
+other_dup (void)
{
tos++;
check_range ();
}
static void
-drop ()
+drop (void)
{
tos--;
check_range ();
+ delete_string (tos + 1);
pc++;
}
static void
-idrop ()
+idrop (void)
{
isp--;
icheck_range ();
}
static void
-icatstr ()
+icatstr (void)
{
tos--;
check_range ();
}
static void
-skip_past_newline ()
+skip_past_newline (void)
{
idx = skip_past_newline_1 (ptr, idx);
pc++;
}
static void
-internalmode ()
+internalmode (void)
{
internal_mode = *(isp);
isp--;
}
static void
-maybecatstr ()
+maybecatstr (void)
{
if (internal_wanted == internal_mode)
{
}
char *
-nextword (string, word)
- char *string;
- char **word;
+nextword (char *string, char **word)
{
char *word_start;
int idx;
}
}
if (!*string)
- return 0;
+ {
+ *word = NULL;
+ return NULL;
+ }
word_start = string;
if (*string == '"')
}
}
- *word = (char *) malloc (length + 1);
+ *word = xmalloc (length + 1);
dst = *word;
src = word_start;
if (*string)
return string + 1;
else
- return 0;
+ return NULL;
}
-dict_type *root;
-
dict_type *
-lookup_word (word)
- char *word;
+lookup_word (char *word)
{
dict_type *ptr = root;
while (ptr)
}
if (warning)
fprintf (stderr, "Can't find %s\n", word);
- return 0;
+ return NULL;
+}
+
+static void
+free_words (void)
+{
+ dict_type *ptr = root;
+
+ while (ptr)
+ {
+ dict_type *next;
+
+ free (ptr->word);
+ if (ptr->code)
+ {
+ int i;
+ for (i = 0; i < ptr->code_end - 1; i ++)
+ if (ptr->code[i].f == push_text
+ && ptr->code[i + 1].s)
+ {
+ free (ptr->code[i + 1].s - 1);
+ ++i;
+ }
+ free (ptr->code);
+ }
+ next = ptr->next;
+ free (ptr);
+ ptr = next;
+ }
}
static void
-perform ()
+perform (void)
{
tos = stack;
{
if (warning)
fprintf (stderr, "warning, %s is not recognised\n", next);
- skip_past_newline ();
+ idx = skip_past_newline_1 (ptr, idx);
}
free (next);
}
else
- skip_past_newline ();
+ idx = skip_past_newline_1 (ptr, idx);
}
}
dict_type *
-newentry (word)
- char *word;
+newentry (char *word)
{
- dict_type *new_d = (dict_type *) malloc (sizeof (dict_type));
+ dict_type *new_d = xmalloc (sizeof (*new_d));
new_d->word = word;
new_d->next = root;
root = new_d;
- new_d->code = (stinst_type *) malloc (sizeof (stinst_type));
+ new_d->code = xmalloc (sizeof (*new_d->code));
new_d->code_length = 1;
new_d->code_end = 0;
return new_d;
}
unsigned int
-add_to_definition (entry, word)
- dict_type *entry;
- stinst_type word;
+add_to_definition (dict_type *entry, pcu 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 = xrealloc (entry->code,
+ entry->code_length * sizeof (*entry->code));
}
entry->code[entry->code_end] = word;
}
void
-add_intrinsic (name, func)
- char *name;
- void (*func) ();
+add_intrinsic (char *name, void (*func) (void))
{
- dict_type *new_d = newentry (name);
- add_to_definition (new_d, func);
- add_to_definition (new_d, 0);
+ dict_type *new_d = newentry (xstrdup (name));
+ pcu p = { func };
+ add_to_definition (new_d, p);
+ p.f = 0;
+ add_to_definition (new_d, p);
}
void
-add_var (name)
- char *name;
-{
- dict_type *new_d = newentry (name);
- add_to_definition (new_d, push_number);
- add_to_definition (new_d, (stinst_type) (&(new_d->var)));
- add_to_definition (new_d, 0);
-}
-
-void
-compile (string)
- char *string;
+compile (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] == ':')
+ if (word[0] == ':')
{
dict_type *ptr;
+ pcu p;
+
/* Compile a word and add to dictionary. */
+ free (word);
string = nextword (string, &word);
-
+ if (!string)
+ continue;
ptr = newentry (word);
string = nextword (string, &word);
+ if (!string)
+ {
+ free (ptr->code);
+ free (ptr);
+ continue;
+ }
+
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));
+ p.f = push_text;
+ add_to_definition (ptr, p);
+ p.s = word + 1;
+ add_to_definition (ptr, p);
break;
case '0':
case '1':
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));
+ p.f = push_number;
+ add_to_definition (ptr, p);
+ p.l = atol (word);
+ add_to_definition (ptr, p);
+ free (word);
break;
default:
- add_to_definition (ptr, call);
- add_to_definition (ptr, (stinst_type) lookup_word (word));
+ p.f = call;
+ add_to_definition (ptr, p);
+ p.e = lookup_word (word);
+ add_to_definition (ptr, p);
+ free (word);
}
string = nextword (string, &word);
}
- add_to_definition (ptr, 0);
+ p.f = 0;
+ add_to_definition (ptr, p);
+ free (word);
string = nextword (string, &word);
}
else
fprintf (stderr, "syntax error at %s\n", string - 1);
}
}
+ free (word);
}
static void
-bang ()
+bang (void)
{
*(long *) ((isp[0])) = isp[-1];
isp -= 2;
}
static void
-atsign ()
+atsign (void)
{
isp[0] = *(long *) (isp[0]);
pc++;
}
static void
-hello ()
+hello (void)
{
printf ("hello\n");
pc++;
}
static void
-stdout_ ()
+stdout_ (void)
{
isp++;
icheck_range ();
}
static void
-stderr_ ()
+stderr_ (void)
{
isp++;
icheck_range ();
}
static void
-print ()
+print (void)
{
if (*isp == 1)
write_buffer (tos, stdout);
}
static void
-read_in (str, file)
- string_type *str;
- FILE *file;
+read_in (string_type *str, FILE *file)
{
char buff[10000];
unsigned int r;
}
static void
-usage ()
+usage (void)
{
fprintf (stderr, "usage: -[d|i|g] <file >file\n");
exit (33);
is a pointless waste of time. */
static void
-chew_exit ()
+chew_exit (void)
{
exit (0);
}
int
-main (ac, av)
- int ac;
- char *av[];
+main (int ac, char *av[])
{
unsigned int i;
string_type buffer;
read_in (&b, f);
compile (b.ptr);
perform ();
+ delete_string (&b);
}
else if (av[i][1] == 'i')
{
}
}
write_buffer (stack + 0, stdout);
+ free_words ();
+ delete_string (&pptr);
+ delete_string (&buffer);
if (tos != stack)
{
fprintf (stderr, "finishing with current stack level %ld\n",