#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;
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 == '*'
&& at (src, idx +1) != '/'
&& at (src, idx -1) != '\n'))
idx++;
return idx;
}
string_type stack[STACK];
string_type *tos;
unsigned int idx = 0;
string_type *ptr;
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++;
}
static void
remove_noncomments (src, dst)
string_type *src;
string_type *dst;
{
unsigned int idx = 0;
while (at (src, idx))
{
if (at (src, idx) == '\n'
&& at (src, idx + 1) == '/'
&& at (src, idx + 2) == '*')
{
idx += 3;
idx = skip_white_and_stars (src, idx);
if (at (src, idx) == '.')
idx++;
while (at (src, idx))
{
if (at (src, idx) == '\n')
{
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++;
}
static void
paramstuff ()
{
unsigned int openp;
unsigned int fname;
unsigned int idx;
unsigned int len;
string_type out;
init_string (&out);
if (find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "("))
{
catstr (&out, tos);
}
else
{
for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++)
;
fname = openp;
fname--;
while (fname && isspace ((unsigned char) at (tos, fname)))
fname--;
while (fname
&& !isspace ((unsigned char) at (tos,fname))
&& at (tos,fname) != '*')
fname--;
fname++;
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");
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++;
}
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
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
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++;
}
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)
{
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++;
}
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++;
}
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)))
{
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++;
}
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')
{
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++;
}
static void
kill_bogus_lines ()
{
int sl;
int idx = 0;
int c;
int dot = 0;
string_type out;
init_string (&out);
while (at (tos, idx) == '\n')
{
idx++;
}
c = idx;
if (at (tos, idx) == '.')
catchar (&out, '\n');
while (at (tos, idx))
{
idx++;
}
idx--;
while (idx && isspace ((unsigned char) at (tos, idx)))
idx--;
idx++;
sl = 1;
while (c < idx)
{
if (at (tos, c) == '\n'
&& at (tos, c + 1) == '\n'
&& at (tos, c + 2) == '.')
{
c++;
}
else if (at (tos, c) == '.' && sl)
{
dot = 2;
}
else if (at (tos, c) == '\n'
&& at (tos, c + 1) == '\n'
&& dot)
{
c++;
}
catchar (&out, at (tos, c));
if (at (tos, c) == '\n')
{
sl = 1;
if (dot == 2)
dot = 1;
else
dot = 0;
}
else
sl = 0;
c++;
}
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))
{
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;
{
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;
string = nextword (string, &word);
ptr = newentry (word);
string = nextword (string, &word);
while (word[0] != ';')
{
switch (word[0])
{
case '"':
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':
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);
}
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);
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);
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;
}