133965Sjdp/* chew 291041Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 3218822Sdim 2002, 2003, 2005 438889Sjdp Free Software Foundation, Inc. 533965Sjdp Contributed by steve chamberlain @cygnus 633965Sjdp 733965SjdpThis file is part of BFD, the Binary File Descriptor library. 833965Sjdp 933965SjdpThis program is free software; you can redistribute it and/or modify 1033965Sjdpit under the terms of the GNU General Public License as published by 1133965Sjdpthe Free Software Foundation; either version 2 of the License, or 1233965Sjdp(at your option) any later version. 1333965Sjdp 1433965SjdpThis program is distributed in the hope that it will be useful, 1533965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1633965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1733965SjdpGNU General Public License for more details. 1833965Sjdp 1933965SjdpYou should have received a copy of the GNU General Public License 2033965Sjdpalong with this program; if not, write to the Free Software 21218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2233965Sjdp 2333965Sjdp/* Yet another way of extracting documentation from source. 2433965Sjdp No, I haven't finished it yet, but I hope you people like it better 2533965Sjdp than the old way 2677298Sobrien 2733965Sjdp sac 2833965Sjdp 2933965Sjdp Basically, this is a sort of string forth, maybe we should call it 3033965Sjdp struth? 3133965Sjdp 3233965Sjdp You define new words thus: 3333965Sjdp : <newword> <oldwords> ; 3433965Sjdp 3533965Sjdp*/ 3633965Sjdp 3733965Sjdp/* Primitives provided by the program: 3833965Sjdp 3933965Sjdp Two stacks are provided, a string stack and an integer stack. 4033965Sjdp 4133965Sjdp Internal state variables: 4233965Sjdp internal_wanted - indicates whether `-i' was passed 4333965Sjdp internal_mode - user-settable 4433965Sjdp 4533965Sjdp Commands: 4633965Sjdp push_text 4733965Sjdp ! - pop top of integer stack for address, pop next for value; store 4833965Sjdp @ - treat value on integer stack as the address of an integer; push 4933965Sjdp that integer on the integer stack after popping the "address" 5033965Sjdp hello - print "hello\n" to stdout 5133965Sjdp stdout - put stdout marker on TOS 5233965Sjdp stderr - put stderr marker on TOS 5333965Sjdp print - print TOS-1 on TOS (eg: "hello\n" stdout print) 5433965Sjdp skip_past_newline 5533965Sjdp catstr - fn icatstr 5633965Sjdp copy_past_newline - append input, up to and including newline into TOS 5733965Sjdp dup - fn other_dup 5833965Sjdp drop - discard TOS 5933965Sjdp idrop - ditto 6033965Sjdp remchar - delete last character from TOS 6133965Sjdp get_stuff_in_command 6233965Sjdp do_fancy_stuff - translate <<foo>> to @code{foo} in TOS 6333965Sjdp bulletize - if "o" lines found, prepend @itemize @bullet to TOS 6433965Sjdp and @item to each "o" line; append @end itemize 6533965Sjdp courierize - put @example around . and | lines, translate {* *} { } 6633965Sjdp exit - fn chew_exit 6733965Sjdp swap 6833965Sjdp outputdots - strip out lines without leading dots 6933965Sjdp paramstuff - convert full declaration into "PARAMS" form if not already 7033965Sjdp maybecatstr - do catstr if internal_mode == internal_wanted, discard 7133965Sjdp value in any case 7233965Sjdp translatecomments - turn {* and *} into comment delimiters 7333965Sjdp kill_bogus_lines - get rid of extra newlines 7433965Sjdp indent 7533965Sjdp internalmode - pop from integer stack, set `internalmode' to that value 7633965Sjdp print_stack_level - print current stack depth to stderr 7733965Sjdp strip_trailing_newlines - go ahead, guess... 7833965Sjdp [quoted string] - push string onto string stack 7933965Sjdp [word starting with digit] - push atol(str) onto integer stack 8033965Sjdp 8133965Sjdp A command must be all upper-case, and alone on a line. 8233965Sjdp 8333965Sjdp Foo. */ 8433965Sjdp 85104834Sobrien#include "ansidecl.h" 8633965Sjdp#include <assert.h> 8733965Sjdp#include <stdio.h> 8833965Sjdp#include <ctype.h> 89218822Sdim#include <stdlib.h> 90218822Sdim#include <string.h> 9133965Sjdp 9233965Sjdp#define DEF_SIZE 5000 9333965Sjdp#define STACK 50 9433965Sjdp 9533965Sjdpint internal_wanted; 9633965Sjdpint internal_mode; 9733965Sjdp 9833965Sjdpint warning; 9933965Sjdp 10077298Sobrien/* Here is a string type ... */ 10133965Sjdp 10277298Sobrientypedef struct buffer 10333965Sjdp{ 10433965Sjdp char *ptr; 10533965Sjdp unsigned long write_idx; 10633965Sjdp unsigned long size; 10733965Sjdp} string_type; 10833965Sjdp 10933965Sjdp#ifdef __STDC__ 11033965Sjdpstatic void init_string_with_size (string_type *, unsigned int); 11133965Sjdpstatic void init_string (string_type *); 11233965Sjdpstatic int find (string_type *, char *); 11333965Sjdpstatic void write_buffer (string_type *, FILE *); 11433965Sjdpstatic void delete_string (string_type *); 11533965Sjdpstatic char *addr (string_type *, unsigned int); 11633965Sjdpstatic char at (string_type *, unsigned int); 11733965Sjdpstatic void catchar (string_type *, int); 11833965Sjdpstatic void overwrite_string (string_type *, string_type *); 11933965Sjdpstatic void catbuf (string_type *, char *, unsigned int); 12033965Sjdpstatic void cattext (string_type *, char *); 12133965Sjdpstatic void catstr (string_type *, string_type *); 12233965Sjdp#endif 12333965Sjdp 12477298Sobrienstatic void 12577298Sobrieninit_string_with_size (buffer, size) 12677298Sobrien string_type *buffer; 12777298Sobrien unsigned int size; 12833965Sjdp{ 12977298Sobrien buffer->write_idx = 0; 13077298Sobrien buffer->size = size; 13177298Sobrien buffer->ptr = malloc (size); 13233965Sjdp} 13333965Sjdp 13477298Sobrienstatic void 13577298Sobrieninit_string (buffer) 13677298Sobrien string_type *buffer; 13733965Sjdp{ 13877298Sobrien init_string_with_size (buffer, DEF_SIZE); 13933965Sjdp} 14033965Sjdp 14177298Sobrienstatic int 14277298Sobrienfind (str, what) 14377298Sobrien string_type *str; 14477298Sobrien char *what; 14533965Sjdp{ 14677298Sobrien unsigned int i; 14777298Sobrien char *p; 14877298Sobrien p = what; 14977298Sobrien for (i = 0; i < str->write_idx && *p; i++) 15033965Sjdp { 15177298Sobrien if (*p == str->ptr[i]) 15277298Sobrien p++; 15377298Sobrien else 15477298Sobrien p = what; 15533965Sjdp } 15677298Sobrien return (*p == 0); 15733965Sjdp} 15833965Sjdp 15977298Sobrienstatic void 16077298Sobrienwrite_buffer (buffer, f) 16177298Sobrien string_type *buffer; 16277298Sobrien FILE *f; 16333965Sjdp{ 16477298Sobrien fwrite (buffer->ptr, buffer->write_idx, 1, f); 16533965Sjdp} 16633965Sjdp 16777298Sobrienstatic void 16877298Sobriendelete_string (buffer) 16977298Sobrien string_type *buffer; 17033965Sjdp{ 17177298Sobrien free (buffer->ptr); 17233965Sjdp} 17333965Sjdp 17477298Sobrienstatic char * 17577298Sobrienaddr (buffer, idx) 17677298Sobrien string_type *buffer; 17777298Sobrien unsigned int idx; 17833965Sjdp{ 17977298Sobrien return buffer->ptr + idx; 18033965Sjdp} 18133965Sjdp 18277298Sobrienstatic char 18377298Sobrienat (buffer, pos) 18477298Sobrien string_type *buffer; 18577298Sobrien unsigned int pos; 18633965Sjdp{ 18777298Sobrien if (pos >= buffer->write_idx) 18833965Sjdp return 0; 18933965Sjdp return buffer->ptr[pos]; 19033965Sjdp} 19133965Sjdp 19277298Sobrienstatic void 19377298Sobriencatchar (buffer, ch) 19477298Sobrien string_type *buffer; 19577298Sobrien int ch; 19633965Sjdp{ 19777298Sobrien if (buffer->write_idx == buffer->size) 19833965Sjdp { 19977298Sobrien buffer->size *= 2; 20077298Sobrien buffer->ptr = realloc (buffer->ptr, buffer->size); 20133965Sjdp } 20233965Sjdp 20377298Sobrien buffer->ptr[buffer->write_idx++] = ch; 20433965Sjdp} 20533965Sjdp 20677298Sobrienstatic void 20777298Sobrienoverwrite_string (dst, src) 20877298Sobrien string_type *dst; 20977298Sobrien string_type *src; 21033965Sjdp{ 21177298Sobrien free (dst->ptr); 21277298Sobrien dst->size = src->size; 21377298Sobrien dst->write_idx = src->write_idx; 21477298Sobrien dst->ptr = src->ptr; 21533965Sjdp} 21633965Sjdp 21777298Sobrienstatic void 21877298Sobriencatbuf (buffer, buf, len) 21977298Sobrien string_type *buffer; 22077298Sobrien char *buf; 22177298Sobrien unsigned int len; 22233965Sjdp{ 22333965Sjdp if (buffer->write_idx + len >= buffer->size) 22433965Sjdp { 22533965Sjdp while (buffer->write_idx + len >= buffer->size) 22633965Sjdp buffer->size *= 2; 22733965Sjdp buffer->ptr = realloc (buffer->ptr, buffer->size); 22833965Sjdp } 22933965Sjdp memcpy (buffer->ptr + buffer->write_idx, buf, len); 23033965Sjdp buffer->write_idx += len; 23133965Sjdp} 23233965Sjdp 23377298Sobrienstatic void 23477298Sobriencattext (buffer, string) 23577298Sobrien string_type *buffer; 23677298Sobrien char *string; 23733965Sjdp{ 23833965Sjdp catbuf (buffer, string, (unsigned int) strlen (string)); 23933965Sjdp} 24033965Sjdp 24177298Sobrienstatic void 24277298Sobriencatstr (dst, src) 24377298Sobrien string_type *dst; 24477298Sobrien string_type *src; 24533965Sjdp{ 24633965Sjdp catbuf (dst, src->ptr, src->write_idx); 24733965Sjdp} 24833965Sjdp 24977298Sobrienstatic unsigned int 25077298Sobrienskip_white_and_stars (src, idx) 25177298Sobrien string_type *src; 25277298Sobrien unsigned int idx; 25333965Sjdp{ 25433965Sjdp char c; 25577298Sobrien while ((c = at (src, idx)), 25638889Sjdp isspace ((unsigned char) c) 25733965Sjdp || (c == '*' 25833965Sjdp /* Don't skip past end-of-comment or star as first 25933965Sjdp character on its line. */ 26077298Sobrien && at (src, idx +1) != '/' 26177298Sobrien && at (src, idx -1) != '\n')) 26233965Sjdp idx++; 26333965Sjdp return idx; 26433965Sjdp} 26533965Sjdp 26633965Sjdp/***********************************************************************/ 26733965Sjdp 26833965Sjdpstring_type stack[STACK]; 26933965Sjdpstring_type *tos; 27033965Sjdp 27133965Sjdpunsigned int idx = 0; /* Pos in input buffer */ 27233965Sjdpstring_type *ptr; /* and the buffer */ 27333965Sjdptypedef void (*stinst_type)(); 27433965Sjdpstinst_type *pc; 27533965Sjdpstinst_type sstack[STACK]; 27633965Sjdpstinst_type *ssp = &sstack[0]; 27733965Sjdplong istack[STACK]; 27833965Sjdplong *isp = &istack[0]; 27933965Sjdp 28033965Sjdptypedef int *word_type; 28133965Sjdp 28233965Sjdpstruct dict_struct 28333965Sjdp{ 28477298Sobrien char *word; 28577298Sobrien struct dict_struct *next; 28677298Sobrien stinst_type *code; 28777298Sobrien int code_length; 28877298Sobrien int code_end; 28977298Sobrien int var; 29033965Sjdp}; 29177298Sobrien 29233965Sjdptypedef struct dict_struct dict_type; 29377298Sobrien 29433965Sjdpstatic void 29533965Sjdpdie (msg) 29633965Sjdp char *msg; 29733965Sjdp{ 29833965Sjdp fprintf (stderr, "%s\n", msg); 29933965Sjdp exit (1); 30033965Sjdp} 30133965Sjdp 30233965Sjdpstatic void 30333965Sjdpcheck_range () 30433965Sjdp{ 30533965Sjdp if (tos < stack) 30633965Sjdp die ("underflow in string stack"); 30733965Sjdp if (tos >= stack + STACK) 30833965Sjdp die ("overflow in string stack"); 30933965Sjdp} 31033965Sjdp 31133965Sjdpstatic void 31233965Sjdpicheck_range () 31333965Sjdp{ 31433965Sjdp if (isp < istack) 31533965Sjdp die ("underflow in integer stack"); 31633965Sjdp if (isp >= istack + STACK) 31733965Sjdp die ("overflow in integer stack"); 31833965Sjdp} 31933965Sjdp 32033965Sjdp#ifdef __STDC__ 32133965Sjdpstatic void exec (dict_type *); 32233965Sjdpstatic void call (void); 32333965Sjdpstatic void remchar (void), strip_trailing_newlines (void), push_number (void); 32433965Sjdpstatic void push_text (void); 32533965Sjdpstatic void remove_noncomments (string_type *, string_type *); 32633965Sjdpstatic void print_stack_level (void); 32738889Sjdpstatic void paramstuff (void), translatecomments (void); 32833965Sjdpstatic void outputdots (void), courierize (void), bulletize (void); 32933965Sjdpstatic void do_fancy_stuff (void); 33033965Sjdpstatic int iscommand (string_type *, unsigned int); 33133965Sjdpstatic int copy_past_newline (string_type *, unsigned int, string_type *); 33233965Sjdpstatic void icopy_past_newline (void), kill_bogus_lines (void), indent (void); 33333965Sjdpstatic void get_stuff_in_command (void), swap (void), other_dup (void); 33433965Sjdpstatic void drop (void), idrop (void); 33533965Sjdpstatic void icatstr (void), skip_past_newline (void), internalmode (void); 33633965Sjdpstatic void maybecatstr (void); 33733965Sjdpstatic char *nextword (char *, char **); 33833965Sjdpdict_type *lookup_word (char *); 33933965Sjdpstatic void perform (void); 34033965Sjdpdict_type *newentry (char *); 34133965Sjdpunsigned int add_to_definition (dict_type *, stinst_type); 34233965Sjdpvoid add_intrinsic (char *, void (*)()); 34333965Sjdpvoid add_var (char *); 34433965Sjdpvoid compile (char *); 34533965Sjdpstatic void bang (void); 34633965Sjdpstatic void atsign (void); 34733965Sjdpstatic void hello (void); 34833965Sjdpstatic void stdout_ (void); 34933965Sjdpstatic void stderr_ (void); 35033965Sjdpstatic void print (void); 35133965Sjdpstatic void read_in (string_type *, FILE *); 35233965Sjdpstatic void usage (void); 35333965Sjdpstatic void chew_exit (void); 35433965Sjdp#endif 35533965Sjdp 35677298Sobrienstatic void 35777298Sobrienexec (word) 35877298Sobrien dict_type *word; 35933965Sjdp{ 36033965Sjdp pc = word->code; 36177298Sobrien while (*pc) 36277298Sobrien (*pc) (); 36333965Sjdp} 36477298Sobrien 36591041Sobrienstatic void 36691041Sobriencall () 36733965Sjdp{ 36877298Sobrien stinst_type *oldpc = pc; 36977298Sobrien dict_type *e; 37077298Sobrien e = (dict_type *) (pc[1]); 37177298Sobrien exec (e); 37277298Sobrien pc = oldpc + 2; 37333965Sjdp} 37433965Sjdp 37591041Sobrienstatic void 37691041Sobrienremchar () 37733965Sjdp{ 37833965Sjdp if (tos->write_idx) 37977298Sobrien tos->write_idx--; 38033965Sjdp pc++; 38133965Sjdp} 38233965Sjdp 38333965Sjdpstatic void 38433965Sjdpstrip_trailing_newlines () 38533965Sjdp{ 38638889Sjdp while ((isspace ((unsigned char) at (tos, tos->write_idx - 1)) 38733965Sjdp || at (tos, tos->write_idx - 1) == '\n') 38833965Sjdp && tos->write_idx > 0) 38933965Sjdp tos->write_idx--; 39033965Sjdp pc++; 39133965Sjdp} 39233965Sjdp 39391041Sobrienstatic void 39491041Sobrienpush_number () 39533965Sjdp{ 39677298Sobrien isp++; 39777298Sobrien icheck_range (); 39877298Sobrien pc++; 39977298Sobrien *isp = (long) (*pc); 40077298Sobrien pc++; 40133965Sjdp} 40233965Sjdp 40391041Sobrienstatic void 40491041Sobrienpush_text () 40533965Sjdp{ 40677298Sobrien tos++; 40777298Sobrien check_range (); 40877298Sobrien init_string (tos); 40977298Sobrien pc++; 41077298Sobrien cattext (tos, *((char **) pc)); 41177298Sobrien pc++; 41233965Sjdp} 41333965Sjdp 41433965Sjdp/* This function removes everything not inside comments starting on 41533965Sjdp the first char of the line from the string, also when copying 41633965Sjdp comments, removes blank space and leading *'s. 41733965Sjdp Blank lines are turned into one blank line. */ 41833965Sjdp 41977298Sobrienstatic void 42077298Sobrienremove_noncomments (src, dst) 42177298Sobrien string_type *src; 42277298Sobrien string_type *dst; 42333965Sjdp{ 42477298Sobrien unsigned int idx = 0; 42577298Sobrien 42677298Sobrien while (at (src, idx)) 42733965Sjdp { 42877298Sobrien /* Now see if we have a comment at the start of the line. */ 42977298Sobrien if (at (src, idx) == '\n' 43077298Sobrien && at (src, idx + 1) == '/' 43177298Sobrien && at (src, idx + 2) == '*') 43233965Sjdp { 43377298Sobrien idx += 3; 43433965Sjdp 43577298Sobrien idx = skip_white_and_stars (src, idx); 43677298Sobrien 43777298Sobrien /* Remove leading dot */ 43877298Sobrien if (at (src, idx) == '.') 43977298Sobrien idx++; 44077298Sobrien 44177298Sobrien /* Copy to the end of the line, or till the end of the 44277298Sobrien comment. */ 44377298Sobrien while (at (src, idx)) 44433965Sjdp { 44577298Sobrien if (at (src, idx) == '\n') 44633965Sjdp { 44777298Sobrien /* end of line, echo and scrape of leading blanks */ 44877298Sobrien if (at (src, idx + 1) == '\n') 44977298Sobrien catchar (dst, '\n'); 45077298Sobrien catchar (dst, '\n'); 45177298Sobrien idx++; 45277298Sobrien idx = skip_white_and_stars (src, idx); 45333965Sjdp } 45477298Sobrien else if (at (src, idx) == '*' && at (src, idx + 1) == '/') 45533965Sjdp { 45677298Sobrien idx += 2; 45777298Sobrien cattext (dst, "\nENDDD\n"); 45877298Sobrien break; 45933965Sjdp } 46077298Sobrien else 46133965Sjdp { 46277298Sobrien catchar (dst, at (src, idx)); 46377298Sobrien idx++; 46433965Sjdp } 46533965Sjdp } 46633965Sjdp } 46777298Sobrien else 46877298Sobrien idx++; 46933965Sjdp } 47033965Sjdp} 47133965Sjdp 47233965Sjdpstatic void 47333965Sjdpprint_stack_level () 47433965Sjdp{ 47533965Sjdp fprintf (stderr, "current string stack depth = %d, ", tos - stack); 47633965Sjdp fprintf (stderr, "current integer stack depth = %d\n", isp - istack); 47733965Sjdp pc++; 47833965Sjdp} 47933965Sjdp 48033965Sjdp/* turn: 48133965Sjdp foobar name(stuff); 48233965Sjdp into: 48333965Sjdp foobar 48433965Sjdp name PARAMS ((stuff)); 48533965Sjdp and a blank line. 48633965Sjdp */ 48733965Sjdp 48833965Sjdpstatic void 489104834Sobrienparamstuff () 49033965Sjdp{ 49177298Sobrien unsigned int openp; 49277298Sobrien unsigned int fname; 49377298Sobrien unsigned int idx; 49477298Sobrien unsigned int len; 49577298Sobrien string_type out; 49677298Sobrien init_string (&out); 49733965Sjdp 498130561Sobrien#define NO_PARAMS 1 499130561Sobrien 50077298Sobrien /* Make sure that it's not already param'd or proto'd. */ 501130561Sobrien if (NO_PARAMS 502130561Sobrien || find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "(")) 50333965Sjdp { 50477298Sobrien catstr (&out, tos); 50577298Sobrien } 50677298Sobrien else 50777298Sobrien { 50877298Sobrien /* Find the open paren. */ 50977298Sobrien for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++) 51077298Sobrien ; 51133965Sjdp 51277298Sobrien fname = openp; 51377298Sobrien /* Step back to the fname. */ 51477298Sobrien fname--; 51577298Sobrien while (fname && isspace ((unsigned char) at (tos, fname))) 51633965Sjdp fname--; 51777298Sobrien while (fname 51877298Sobrien && !isspace ((unsigned char) at (tos,fname)) 51977298Sobrien && at (tos,fname) != '*') 52077298Sobrien fname--; 52133965Sjdp 52277298Sobrien fname++; 52377298Sobrien 52477298Sobrien /* Output type, omitting trailing whitespace character(s), if 52577298Sobrien any. */ 52677298Sobrien for (len = fname; 0 < len; len--) 52733965Sjdp { 52877298Sobrien if (!isspace ((unsigned char) at (tos, len - 1))) 52977298Sobrien break; 53033965Sjdp } 53177298Sobrien for (idx = 0; idx < len; idx++) 53277298Sobrien catchar (&out, at (tos, idx)); 53333965Sjdp 53477298Sobrien cattext (&out, "\n"); /* Insert a newline between type and fnname */ 53577298Sobrien 53677298Sobrien /* Output function name, omitting trailing whitespace 53777298Sobrien character(s), if any. */ 53877298Sobrien for (len = openp; 0 < len; len--) 53933965Sjdp { 54077298Sobrien if (!isspace ((unsigned char) at (tos, len - 1))) 54177298Sobrien break; 54233965Sjdp } 54377298Sobrien for (idx = fname; idx < len; idx++) 54477298Sobrien catchar (&out, at (tos, idx)); 54533965Sjdp 54677298Sobrien cattext (&out, " PARAMS ("); 54733965Sjdp 54877298Sobrien for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++) 54977298Sobrien catchar (&out, at (tos, idx)); 55077298Sobrien 55177298Sobrien cattext (&out, ");\n\n"); 55233965Sjdp } 55377298Sobrien overwrite_string (tos, &out); 55477298Sobrien pc++; 55577298Sobrien 55633965Sjdp} 55733965Sjdp 55833965Sjdp/* turn {* 55933965Sjdp and *} into comments */ 56033965Sjdp 56191041Sobrienstatic void 56291041Sobrientranslatecomments () 56333965Sjdp{ 56477298Sobrien unsigned int idx = 0; 56577298Sobrien string_type out; 56677298Sobrien init_string (&out); 56777298Sobrien 56877298Sobrien while (at (tos, idx)) 56933965Sjdp { 57077298Sobrien if (at (tos, idx) == '{' && at (tos, idx + 1) == '*') 57133965Sjdp { 57277298Sobrien cattext (&out, "/*"); 57377298Sobrien idx += 2; 57433965Sjdp } 57577298Sobrien else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}') 57633965Sjdp { 57777298Sobrien cattext (&out, "*/"); 57877298Sobrien idx += 2; 57933965Sjdp } 58077298Sobrien else 58133965Sjdp { 58277298Sobrien catchar (&out, at (tos, idx)); 58377298Sobrien idx++; 58433965Sjdp } 58533965Sjdp } 58633965Sjdp 58777298Sobrien overwrite_string (tos, &out); 58833965Sjdp 58977298Sobrien pc++; 59033965Sjdp} 59133965Sjdp 59233965Sjdp/* Mod tos so that only lines with leading dots remain */ 59333965Sjdpstatic void 594104834Sobrienoutputdots () 59533965Sjdp{ 59677298Sobrien unsigned int idx = 0; 59777298Sobrien string_type out; 59877298Sobrien init_string (&out); 59977298Sobrien 60077298Sobrien while (at (tos, idx)) 60133965Sjdp { 60277298Sobrien if (at (tos, idx) == '\n' && at (tos, idx + 1) == '.') 60333965Sjdp { 60438889Sjdp char c; 60533965Sjdp idx += 2; 60677298Sobrien 60777298Sobrien while ((c = at (tos, idx)) && c != '\n') 60833965Sjdp { 60977298Sobrien if (c == '{' && at (tos, idx + 1) == '*') 61033965Sjdp { 61177298Sobrien cattext (&out, "/*"); 61277298Sobrien idx += 2; 61333965Sjdp } 61477298Sobrien else if (c == '*' && at (tos, idx + 1) == '}') 61533965Sjdp { 61677298Sobrien cattext (&out, "*/"); 61777298Sobrien idx += 2; 61833965Sjdp } 61933965Sjdp else 62033965Sjdp { 62177298Sobrien catchar (&out, c); 62277298Sobrien idx++; 62333965Sjdp } 62433965Sjdp } 62577298Sobrien catchar (&out, '\n'); 62633965Sjdp } 62777298Sobrien else 62833965Sjdp { 62977298Sobrien idx++; 63033965Sjdp } 63177298Sobrien } 63233965Sjdp 63377298Sobrien overwrite_string (tos, &out); 63477298Sobrien pc++; 63533965Sjdp} 63633965Sjdp 63733965Sjdp/* Find lines starting with . and | and put example around them on tos */ 63891041Sobrienstatic void 63991041Sobriencourierize () 64033965Sjdp{ 64177298Sobrien string_type out; 64277298Sobrien unsigned int idx = 0; 64377298Sobrien int command = 0; 64477298Sobrien 64577298Sobrien init_string (&out); 64677298Sobrien 64777298Sobrien while (at (tos, idx)) 64833965Sjdp { 64977298Sobrien if (at (tos, idx) == '\n' 65077298Sobrien && (at (tos, idx +1 ) == '.' 65177298Sobrien || at (tos, idx + 1) == '|')) 65233965Sjdp { 65377298Sobrien cattext (&out, "\n@example\n"); 65477298Sobrien do 65533965Sjdp { 65677298Sobrien idx += 2; 65777298Sobrien 65877298Sobrien while (at (tos, idx) && at (tos, idx) != '\n') 65933965Sjdp { 66091041Sobrien if (command > 1) 66133965Sjdp { 66291041Sobrien /* We are inside {} parameters of some command; 66391041Sobrien Just pass through until matching brace. */ 66491041Sobrien if (at (tos, idx) == '{') 66591041Sobrien ++command; 66691041Sobrien else if (at (tos, idx) == '}') 66791041Sobrien --command; 66891041Sobrien } 66991041Sobrien else if (command != 0) 67091041Sobrien { 67191041Sobrien if (at (tos, idx) == '{') 67291041Sobrien ++command; 67391041Sobrien else if (!islower ((unsigned char) at (tos, idx))) 67491041Sobrien --command; 67591041Sobrien } 67691041Sobrien else if (at (tos, idx) == '@' 67791041Sobrien && islower ((unsigned char) at (tos, idx + 1))) 67891041Sobrien { 67991041Sobrien ++command; 68091041Sobrien } 68191041Sobrien else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*') 68291041Sobrien { 68377298Sobrien cattext (&out, "/*"); 68477298Sobrien idx += 2; 68591041Sobrien continue; 68633965Sjdp } 68777298Sobrien else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}') 68833965Sjdp { 68977298Sobrien cattext (&out, "*/"); 69077298Sobrien idx += 2; 69191041Sobrien continue; 69233965Sjdp } 69391041Sobrien else if (at (tos, idx) == '{' 69491041Sobrien || at (tos, idx) == '}') 69533965Sjdp { 69691041Sobrien catchar (&out, '@'); 69733965Sjdp } 69877298Sobrien 69991041Sobrien catchar (&out, at (tos, idx)); 70091041Sobrien idx++; 70133965Sjdp } 70277298Sobrien catchar (&out, '\n'); 70377298Sobrien } 70477298Sobrien while (at (tos, idx) == '\n' 70577298Sobrien && ((at (tos, idx + 1) == '.') 70677298Sobrien || (at (tos, idx + 1) == '|'))) 70777298Sobrien ; 70877298Sobrien cattext (&out, "@end example"); 70933965Sjdp } 71077298Sobrien else 71177298Sobrien { 71277298Sobrien catchar (&out, at (tos, idx)); 71377298Sobrien idx++; 71433965Sjdp } 71577298Sobrien } 71633965Sjdp 71777298Sobrien overwrite_string (tos, &out); 71877298Sobrien pc++; 71933965Sjdp} 72033965Sjdp 72133965Sjdp/* Finds any lines starting with "o ", if there are any, then turns 72233965Sjdp on @itemize @bullet, and @items each of them. Then ends with @end 72333965Sjdp itemize, inplace at TOS*/ 72433965Sjdp 72591041Sobrienstatic void 72691041Sobrienbulletize () 72777298Sobrien{ 72877298Sobrien unsigned int idx = 0; 72977298Sobrien int on = 0; 73077298Sobrien string_type out; 73177298Sobrien init_string (&out); 73233965Sjdp 73377298Sobrien while (at (tos, idx)) 73477298Sobrien { 73577298Sobrien if (at (tos, idx) == '@' 73677298Sobrien && at (tos, idx + 1) == '*') 73733965Sjdp { 73877298Sobrien cattext (&out, "*"); 73977298Sobrien idx += 2; 74033965Sjdp } 74177298Sobrien else if (at (tos, idx) == '\n' 74277298Sobrien && at (tos, idx + 1) == 'o' 74377298Sobrien && isspace ((unsigned char) at (tos, idx + 2))) 74477298Sobrien { 74577298Sobrien if (!on) 74633965Sjdp { 74777298Sobrien cattext (&out, "\n@itemize @bullet\n"); 74877298Sobrien on = 1; 74977298Sobrien 75033965Sjdp } 75177298Sobrien cattext (&out, "\n@item\n"); 75277298Sobrien idx += 3; 75377298Sobrien } 75477298Sobrien else 75577298Sobrien { 75677298Sobrien catchar (&out, at (tos, idx)); 75777298Sobrien if (on && at (tos, idx) == '\n' 75877298Sobrien && at (tos, idx + 1) == '\n' 75977298Sobrien && at (tos, idx + 2) != 'o') 76033965Sjdp { 76177298Sobrien cattext (&out, "@end itemize"); 76277298Sobrien on = 0; 76333965Sjdp } 76477298Sobrien idx++; 76577298Sobrien 76633965Sjdp } 76777298Sobrien } 76877298Sobrien if (on) 76933965Sjdp { 77077298Sobrien cattext (&out, "@end itemize\n"); 77177298Sobrien } 77233965Sjdp 77377298Sobrien delete_string (tos); 77477298Sobrien *tos = out; 77577298Sobrien pc++; 77633965Sjdp} 77733965Sjdp 77833965Sjdp/* Turn <<foo>> into @code{foo} in place at TOS*/ 77933965Sjdp 78091041Sobrienstatic void 78191041Sobriendo_fancy_stuff () 78233965Sjdp{ 78377298Sobrien unsigned int idx = 0; 78477298Sobrien string_type out; 78577298Sobrien init_string (&out); 78677298Sobrien while (at (tos, idx)) 78733965Sjdp { 78877298Sobrien if (at (tos, idx) == '<' 78977298Sobrien && at (tos, idx + 1) == '<' 79077298Sobrien && !isspace ((unsigned char) at (tos, idx + 2))) 79133965Sjdp { 79277298Sobrien /* This qualifies as a << startup. */ 79377298Sobrien idx += 2; 79477298Sobrien cattext (&out, "@code{"); 79577298Sobrien while (at (tos, idx) 79677298Sobrien && at (tos, idx) != '>' ) 79733965Sjdp { 79877298Sobrien catchar (&out, at (tos, idx)); 79977298Sobrien idx++; 80077298Sobrien 80133965Sjdp } 80277298Sobrien cattext (&out, "}"); 80377298Sobrien idx += 2; 80433965Sjdp } 80577298Sobrien else 80633965Sjdp { 80777298Sobrien catchar (&out, at (tos, idx)); 80877298Sobrien idx++; 80933965Sjdp } 81033965Sjdp } 81177298Sobrien delete_string (tos); 81277298Sobrien *tos = out; 81377298Sobrien pc++; 81477298Sobrien 81533965Sjdp} 81677298Sobrien 81777298Sobrien/* A command is all upper case,and alone on a line. */ 81877298Sobrien 81977298Sobrienstatic int 82077298Sobrieniscommand (ptr, idx) 82177298Sobrien string_type *ptr; 82277298Sobrien unsigned int idx; 82333965Sjdp{ 82477298Sobrien unsigned int len = 0; 82577298Sobrien while (at (ptr, idx)) 82677298Sobrien { 82777298Sobrien if (isupper ((unsigned char) at (ptr, idx)) 82877298Sobrien || at (ptr, idx) == ' ' || at (ptr, idx) == '_') 82977298Sobrien { 83077298Sobrien len++; 83177298Sobrien idx++; 83233965Sjdp } 83377298Sobrien else if (at (ptr, idx) == '\n') 83477298Sobrien { 83577298Sobrien if (len > 3) 83677298Sobrien return 1; 83777298Sobrien return 0; 83877298Sobrien } 83977298Sobrien else 84077298Sobrien return 0; 84177298Sobrien } 84277298Sobrien return 0; 84333965Sjdp} 84433965Sjdp 84538889Sjdpstatic int 84677298Sobriencopy_past_newline (ptr, idx, dst) 84777298Sobrien string_type *ptr; 84877298Sobrien unsigned int idx; 84977298Sobrien string_type *dst; 85033965Sjdp{ 85177298Sobrien int column = 0; 85238889Sjdp 85377298Sobrien while (at (ptr, idx) && at (ptr, idx) != '\n') 85433965Sjdp { 85577298Sobrien if (at (ptr, idx) == '\t') 85677298Sobrien { 85777298Sobrien /* Expand tabs. Neither makeinfo nor TeX can cope well with 85877298Sobrien them. */ 85977298Sobrien do 86077298Sobrien catchar (dst, ' '); 86177298Sobrien while (++column & 7); 86277298Sobrien } 86377298Sobrien else 86477298Sobrien { 86577298Sobrien catchar (dst, at (ptr, idx)); 86677298Sobrien column++; 86777298Sobrien } 86877298Sobrien idx++; 86933965Sjdp 87077298Sobrien } 87177298Sobrien catchar (dst, at (ptr, idx)); 87277298Sobrien idx++; 87377298Sobrien return idx; 87477298Sobrien 87533965Sjdp} 87633965Sjdp 87791041Sobrienstatic void 87891041Sobrienicopy_past_newline () 87933965Sjdp{ 88077298Sobrien tos++; 88177298Sobrien check_range (); 88277298Sobrien init_string (tos); 88377298Sobrien idx = copy_past_newline (ptr, idx, tos); 88477298Sobrien pc++; 88533965Sjdp} 88633965Sjdp 88733965Sjdp/* indent 88877298Sobrien Take the string at the top of the stack, do some prettying. */ 88933965Sjdp 89091041Sobrienstatic void 89191041Sobrienkill_bogus_lines () 89277298Sobrien{ 89377298Sobrien int sl; 89433965Sjdp 89577298Sobrien int idx = 0; 89677298Sobrien int c; 89777298Sobrien int dot = 0; 89877298Sobrien 89977298Sobrien string_type out; 90077298Sobrien init_string (&out); 90177298Sobrien /* Drop leading nl. */ 90277298Sobrien while (at (tos, idx) == '\n') 90333965Sjdp { 90477298Sobrien idx++; 90533965Sjdp } 90677298Sobrien c = idx; 90738889Sjdp 90877298Sobrien /* If the first char is a '.' prepend a newline so that it is 90977298Sobrien recognized properly later. */ 91077298Sobrien if (at (tos, idx) == '.') 91177298Sobrien catchar (&out, '\n'); 91277298Sobrien 91377298Sobrien /* Find the last char. */ 91477298Sobrien while (at (tos, idx)) 91533965Sjdp { 91677298Sobrien idx++; 91733965Sjdp } 91877298Sobrien 91977298Sobrien /* Find the last non white before the nl. */ 92077298Sobrien idx--; 92177298Sobrien 92277298Sobrien while (idx && isspace ((unsigned char) at (tos, idx))) 92333965Sjdp idx--; 92477298Sobrien idx++; 92533965Sjdp 92677298Sobrien /* Copy buffer upto last char, but blank lines before and after 92777298Sobrien dots don't count. */ 92877298Sobrien sl = 1; 92977298Sobrien 93077298Sobrien while (c < idx) 93133965Sjdp { 93277298Sobrien if (at (tos, c) == '\n' 93377298Sobrien && at (tos, c + 1) == '\n' 93477298Sobrien && at (tos, c + 2) == '.') 93533965Sjdp { 93677298Sobrien /* Ignore two newlines before a dot. */ 93777298Sobrien c++; 93833965Sjdp } 93977298Sobrien else if (at (tos, c) == '.' && sl) 94033965Sjdp { 94177298Sobrien /* remember that this line started with a dot. */ 94277298Sobrien dot = 2; 94333965Sjdp } 94477298Sobrien else if (at (tos, c) == '\n' 94577298Sobrien && at (tos, c + 1) == '\n' 94677298Sobrien && dot) 94733965Sjdp { 94877298Sobrien c++; 94977298Sobrien /* Ignore two newlines when last line was dot. */ 95033965Sjdp } 95133965Sjdp 95277298Sobrien catchar (&out, at (tos, c)); 95377298Sobrien if (at (tos, c) == '\n') 95433965Sjdp { 95577298Sobrien sl = 1; 95677298Sobrien 95777298Sobrien if (dot == 2) 95877298Sobrien dot = 1; 95977298Sobrien else 96077298Sobrien dot = 0; 96133965Sjdp } 96277298Sobrien else 96377298Sobrien sl = 0; 96433965Sjdp 96577298Sobrien c++; 96677298Sobrien 96733965Sjdp } 96877298Sobrien 96977298Sobrien /* Append nl. */ 97077298Sobrien catchar (&out, '\n'); 97177298Sobrien pc++; 97277298Sobrien delete_string (tos); 97377298Sobrien *tos = out; 97477298Sobrien 97533965Sjdp} 97633965Sjdp 97791041Sobrienstatic void 97891041Sobrienindent () 97933965Sjdp{ 98077298Sobrien string_type out; 98177298Sobrien int tab = 0; 98277298Sobrien int idx = 0; 98377298Sobrien int ol = 0; 98477298Sobrien init_string (&out); 98577298Sobrien while (at (tos, idx)) 98677298Sobrien { 98777298Sobrien switch (at (tos, idx)) 98877298Sobrien { 98977298Sobrien case '\n': 99077298Sobrien cattext (&out, "\n"); 99177298Sobrien idx++; 99277298Sobrien if (tab && at (tos, idx)) 99333965Sjdp { 99477298Sobrien cattext (&out, " "); 99533965Sjdp } 99677298Sobrien ol = 0; 99777298Sobrien break; 99877298Sobrien case '(': 99977298Sobrien tab++; 100077298Sobrien if (ol == 0) 100177298Sobrien cattext (&out, " "); 100277298Sobrien idx++; 100377298Sobrien cattext (&out, "("); 100477298Sobrien ol = 1; 100577298Sobrien break; 100677298Sobrien case ')': 100777298Sobrien tab--; 100877298Sobrien cattext (&out, ")"); 100977298Sobrien idx++; 101077298Sobrien ol = 1; 101133965Sjdp 101277298Sobrien break; 101377298Sobrien default: 101477298Sobrien catchar (&out, at (tos, idx)); 101577298Sobrien ol = 1; 101633965Sjdp 101777298Sobrien idx++; 101877298Sobrien break; 101977298Sobrien } 102077298Sobrien } 102177298Sobrien 102277298Sobrien pc++; 102377298Sobrien delete_string (tos); 102477298Sobrien *tos = out; 102577298Sobrien 102633965Sjdp} 102733965Sjdp 102891041Sobrienstatic void 102991041Sobrienget_stuff_in_command () 103033965Sjdp{ 103177298Sobrien tos++; 103277298Sobrien check_range (); 103377298Sobrien init_string (tos); 103433965Sjdp 103577298Sobrien while (at (ptr, idx)) 103677298Sobrien { 103777298Sobrien if (iscommand (ptr, idx)) 103877298Sobrien break; 103977298Sobrien idx = copy_past_newline (ptr, idx, tos); 104077298Sobrien } 104177298Sobrien pc++; 104233965Sjdp} 104333965Sjdp 104491041Sobrienstatic void 104591041Sobrienswap () 104633965Sjdp{ 104777298Sobrien string_type t; 104877298Sobrien 104977298Sobrien t = tos[0]; 105077298Sobrien tos[0] = tos[-1]; 105177298Sobrien tos[-1] = t; 105277298Sobrien pc++; 105333965Sjdp} 105433965Sjdp 105591041Sobrienstatic void 105691041Sobrienother_dup () 105733965Sjdp{ 105877298Sobrien tos++; 105977298Sobrien check_range (); 106077298Sobrien init_string (tos); 106177298Sobrien catstr (tos, tos - 1); 106277298Sobrien pc++; 106333965Sjdp} 106433965Sjdp 106591041Sobrienstatic void 106691041Sobriendrop () 106733965Sjdp{ 106833965Sjdp tos--; 106933965Sjdp check_range (); 107033965Sjdp pc++; 107133965Sjdp} 107233965Sjdp 107391041Sobrienstatic void 107491041Sobrienidrop () 107533965Sjdp{ 107633965Sjdp isp--; 107733965Sjdp icheck_range (); 107833965Sjdp pc++; 107933965Sjdp} 108033965Sjdp 108191041Sobrienstatic void 108291041Sobrienicatstr () 108333965Sjdp{ 108477298Sobrien tos--; 108577298Sobrien check_range (); 108677298Sobrien catstr (tos, tos + 1); 108777298Sobrien delete_string (tos + 1); 108877298Sobrien pc++; 108933965Sjdp} 109033965Sjdp 109191041Sobrienstatic void 109291041Sobrienskip_past_newline () 109333965Sjdp{ 109477298Sobrien while (at (ptr, idx) 109577298Sobrien && at (ptr, idx) != '\n') 109633965Sjdp idx++; 109777298Sobrien idx++; 109877298Sobrien pc++; 109933965Sjdp} 110033965Sjdp 110191041Sobrienstatic void 110291041Sobrieninternalmode () 110333965Sjdp{ 110477298Sobrien internal_mode = *(isp); 110577298Sobrien isp--; 110677298Sobrien icheck_range (); 110777298Sobrien pc++; 110833965Sjdp} 110933965Sjdp 111091041Sobrienstatic void 111191041Sobrienmaybecatstr () 111233965Sjdp{ 111377298Sobrien if (internal_wanted == internal_mode) 111433965Sjdp { 111577298Sobrien catstr (tos - 1, tos); 111633965Sjdp } 111777298Sobrien delete_string (tos); 111877298Sobrien tos--; 111977298Sobrien check_range (); 112077298Sobrien pc++; 112133965Sjdp} 112233965Sjdp 112333965Sjdpchar * 112477298Sobriennextword (string, word) 112577298Sobrien char *string; 112677298Sobrien char **word; 112733965Sjdp{ 112877298Sobrien char *word_start; 112977298Sobrien int idx; 113077298Sobrien char *dst; 113177298Sobrien char *src; 113277298Sobrien 113377298Sobrien int length = 0; 113477298Sobrien 113577298Sobrien while (isspace ((unsigned char) *string) || *string == '-') 113677298Sobrien { 113777298Sobrien if (*string == '-') 113833965Sjdp { 113977298Sobrien while (*string && *string != '\n') 114033965Sjdp string++; 114177298Sobrien 114233965Sjdp } 114377298Sobrien else 114477298Sobrien { 114577298Sobrien string++; 114677298Sobrien } 114733965Sjdp } 114877298Sobrien if (!*string) 114977298Sobrien return 0; 115033965Sjdp 115177298Sobrien word_start = string; 115277298Sobrien if (*string == '"') 115377298Sobrien { 115477298Sobrien do 115577298Sobrien { 115677298Sobrien string++; 115777298Sobrien length++; 115877298Sobrien if (*string == '\\') 115933965Sjdp { 116077298Sobrien string += 2; 116177298Sobrien length += 2; 116233965Sjdp } 116377298Sobrien } 116477298Sobrien while (*string != '"'); 116533965Sjdp } 116677298Sobrien else 116777298Sobrien { 116877298Sobrien while (!isspace ((unsigned char) *string)) 116977298Sobrien { 117077298Sobrien string++; 117177298Sobrien length++; 117233965Sjdp 117377298Sobrien } 117477298Sobrien } 117533965Sjdp 117677298Sobrien *word = malloc (length + 1); 117733965Sjdp 117877298Sobrien dst = *word; 117977298Sobrien src = word_start; 118033965Sjdp 118177298Sobrien for (idx = 0; idx < length; idx++) 118277298Sobrien { 118377298Sobrien if (src[idx] == '\\') 118477298Sobrien switch (src[idx + 1]) 118577298Sobrien { 118677298Sobrien case 'n': 118777298Sobrien *dst++ = '\n'; 118877298Sobrien idx++; 118977298Sobrien break; 119077298Sobrien case '"': 119177298Sobrien case '\\': 119277298Sobrien *dst++ = src[idx + 1]; 119377298Sobrien idx++; 119477298Sobrien break; 119577298Sobrien default: 119677298Sobrien *dst++ = '\\'; 119777298Sobrien break; 119877298Sobrien } 119977298Sobrien else 120077298Sobrien *dst++ = src[idx]; 120177298Sobrien } 120277298Sobrien *dst++ = 0; 120333965Sjdp 120477298Sobrien if (*string) 120577298Sobrien return string + 1; 120677298Sobrien else 120777298Sobrien return 0; 120833965Sjdp} 120977298Sobrien 121033965Sjdpdict_type *root; 121177298Sobrien 121233965Sjdpdict_type * 121377298Sobrienlookup_word (word) 121477298Sobrien char *word; 121533965Sjdp{ 121633965Sjdp dict_type *ptr = root; 121777298Sobrien while (ptr) 121877298Sobrien { 121977298Sobrien if (strcmp (ptr->word, word) == 0) 122077298Sobrien return ptr; 122133965Sjdp ptr = ptr->next; 122233965Sjdp } 122333965Sjdp if (warning) 122477298Sobrien fprintf (stderr, "Can't find %s\n", word); 122533965Sjdp return 0; 122633965Sjdp} 122733965Sjdp 122877298Sobrienstatic void 1229104834Sobrienperform () 123033965Sjdp{ 123133965Sjdp tos = stack; 123233965Sjdp 123377298Sobrien while (at (ptr, idx)) 123477298Sobrien { 123577298Sobrien /* It's worth looking through the command list. */ 123677298Sobrien if (iscommand (ptr, idx)) 123777298Sobrien { 123877298Sobrien char *next; 123977298Sobrien dict_type *word; 124033965Sjdp 124177298Sobrien (void) nextword (addr (ptr, idx), &next); 124233965Sjdp 124377298Sobrien word = lookup_word (next); 124433965Sjdp 124577298Sobrien if (word) 124677298Sobrien { 124777298Sobrien exec (word); 124877298Sobrien } 124977298Sobrien else 125077298Sobrien { 125177298Sobrien if (warning) 125277298Sobrien fprintf (stderr, "warning, %s is not recognised\n", next); 125377298Sobrien skip_past_newline (); 125477298Sobrien } 125533965Sjdp 125633965Sjdp } 125777298Sobrien else 125877298Sobrien skip_past_newline (); 125933965Sjdp } 126033965Sjdp} 126133965Sjdp 126233965Sjdpdict_type * 126377298Sobriennewentry (word) 126477298Sobrien char *word; 126533965Sjdp{ 126677298Sobrien dict_type *new = (dict_type *) malloc (sizeof (dict_type)); 126777298Sobrien new->word = word; 126877298Sobrien new->next = root; 126977298Sobrien root = new; 127077298Sobrien new->code = (stinst_type *) malloc (sizeof (stinst_type)); 127177298Sobrien new->code_length = 1; 127277298Sobrien new->code_end = 0; 127377298Sobrien return new; 127433965Sjdp} 127533965Sjdp 127633965Sjdpunsigned int 127777298Sobrienadd_to_definition (entry, word) 127877298Sobrien dict_type *entry; 127977298Sobrien stinst_type word; 128033965Sjdp{ 128177298Sobrien if (entry->code_end == entry->code_length) 128233965Sjdp { 128377298Sobrien entry->code_length += 2; 128477298Sobrien entry->code = 128577298Sobrien (stinst_type *) realloc ((char *) (entry->code), 128677298Sobrien entry->code_length * sizeof (word_type)); 128733965Sjdp } 128877298Sobrien entry->code[entry->code_end] = word; 128977298Sobrien 129077298Sobrien return entry->code_end++; 129133965Sjdp} 129233965Sjdp 129333965Sjdpvoid 129477298Sobrienadd_intrinsic (name, func) 129577298Sobrien char *name; 129677298Sobrien void (*func) (); 129733965Sjdp{ 129877298Sobrien dict_type *new = newentry (name); 129977298Sobrien add_to_definition (new, func); 130077298Sobrien add_to_definition (new, 0); 130133965Sjdp} 130233965Sjdp 130333965Sjdpvoid 130477298Sobrienadd_var (name) 130577298Sobrien char *name; 130633965Sjdp{ 130777298Sobrien dict_type *new = newentry (name); 130877298Sobrien add_to_definition (new, push_number); 130977298Sobrien add_to_definition (new, (stinst_type) (&(new->var))); 131077298Sobrien add_to_definition (new, 0); 131133965Sjdp} 131233965Sjdp 131377298Sobrienvoid 131477298Sobriencompile (string) 131577298Sobrien char *string; 131633965Sjdp{ 131777298Sobrien /* Add words to the dictionary. */ 131877298Sobrien char *word; 131977298Sobrien string = nextword (string, &word); 132077298Sobrien while (string && *string && word[0]) 132133965Sjdp { 132277298Sobrien if (strcmp (word, "var") == 0) 132333965Sjdp { 132477298Sobrien string = nextword (string, &word); 132577298Sobrien 132677298Sobrien add_var (word); 132777298Sobrien string = nextword (string, &word); 132833965Sjdp } 132977298Sobrien else if (word[0] == ':') 133033965Sjdp { 133177298Sobrien dict_type *ptr; 133277298Sobrien /* Compile a word and add to dictionary. */ 133377298Sobrien string = nextword (string, &word); 133477298Sobrien 133577298Sobrien ptr = newentry (word); 133677298Sobrien string = nextword (string, &word); 133777298Sobrien while (word[0] != ';') 133833965Sjdp { 133977298Sobrien switch (word[0]) 134077298Sobrien { 134177298Sobrien case '"': 134277298Sobrien /* got a string, embed magic push string 134377298Sobrien function */ 134477298Sobrien add_to_definition (ptr, push_text); 134577298Sobrien add_to_definition (ptr, (stinst_type) (word + 1)); 134677298Sobrien break; 134777298Sobrien case '0': 134877298Sobrien case '1': 134977298Sobrien case '2': 135077298Sobrien case '3': 135177298Sobrien case '4': 135277298Sobrien case '5': 135377298Sobrien case '6': 135477298Sobrien case '7': 135577298Sobrien case '8': 135677298Sobrien case '9': 135777298Sobrien /* Got a number, embedd the magic push number 135877298Sobrien function */ 135977298Sobrien add_to_definition (ptr, push_number); 136077298Sobrien add_to_definition (ptr, (stinst_type) atol (word)); 136177298Sobrien break; 136277298Sobrien default: 136377298Sobrien add_to_definition (ptr, call); 136477298Sobrien add_to_definition (ptr, (stinst_type) lookup_word (word)); 136577298Sobrien } 136633965Sjdp 136777298Sobrien string = nextword (string, &word); 136833965Sjdp } 136977298Sobrien add_to_definition (ptr, 0); 137077298Sobrien string = nextword (string, &word); 137133965Sjdp } 137277298Sobrien else 137333965Sjdp { 137477298Sobrien fprintf (stderr, "syntax error at %s\n", string - 1); 137577298Sobrien } 137633965Sjdp } 137733965Sjdp} 137833965Sjdp 137977298Sobrienstatic void 1380104834Sobrienbang () 138133965Sjdp{ 138277298Sobrien *(long *) ((isp[0])) = isp[-1]; 138377298Sobrien isp -= 2; 138433965Sjdp icheck_range (); 138533965Sjdp pc++; 138633965Sjdp} 138733965Sjdp 138891041Sobrienstatic void 138991041Sobrienatsign () 139033965Sjdp{ 139177298Sobrien isp[0] = *(long *) (isp[0]); 139277298Sobrien pc++; 139333965Sjdp} 139433965Sjdp 139591041Sobrienstatic void 139691041Sobrienhello () 139733965Sjdp{ 139877298Sobrien printf ("hello\n"); 139977298Sobrien pc++; 140033965Sjdp} 140133965Sjdp 140291041Sobrienstatic void 140391041Sobrienstdout_ () 140433965Sjdp{ 140533965Sjdp isp++; 140633965Sjdp icheck_range (); 140733965Sjdp *isp = 1; 140833965Sjdp pc++; 140933965Sjdp} 141033965Sjdp 141191041Sobrienstatic void 141291041Sobrienstderr_ () 141333965Sjdp{ 141433965Sjdp isp++; 141533965Sjdp icheck_range (); 141633965Sjdp *isp = 2; 141733965Sjdp pc++; 141833965Sjdp} 141933965Sjdp 142091041Sobrienstatic void 142191041Sobrienprint () 142233965Sjdp{ 142333965Sjdp if (*isp == 1) 142433965Sjdp write_buffer (tos, stdout); 142533965Sjdp else if (*isp == 2) 142633965Sjdp write_buffer (tos, stderr); 142733965Sjdp else 142838889Sjdp fprintf (stderr, "print: illegal print destination `%ld'\n", *isp); 142933965Sjdp isp--; 143033965Sjdp tos--; 143133965Sjdp icheck_range (); 143233965Sjdp check_range (); 143333965Sjdp pc++; 143433965Sjdp} 143533965Sjdp 143677298Sobrienstatic void 143777298Sobrienread_in (str, file) 143877298Sobrien string_type *str; 143977298Sobrien FILE *file; 144033965Sjdp{ 144177298Sobrien char buff[10000]; 144277298Sobrien unsigned int r; 144377298Sobrien do 144433965Sjdp { 144577298Sobrien r = fread (buff, 1, sizeof (buff), file); 144677298Sobrien catbuf (str, buff, r); 144733965Sjdp } 144877298Sobrien while (r); 144977298Sobrien buff[0] = 0; 145077298Sobrien 145177298Sobrien catbuf (str, buff, 1); 145233965Sjdp} 145333965Sjdp 145477298Sobrienstatic void 1455104834Sobrienusage () 145633965Sjdp{ 145777298Sobrien fprintf (stderr, "usage: -[d|i|g] <file >file\n"); 145877298Sobrien exit (33); 145933965Sjdp} 146033965Sjdp 146133965Sjdp/* There is no reliable way to declare exit. Sometimes it returns 146233965Sjdp int, and sometimes it returns void. Sometimes it changes between 146333965Sjdp OS releases. Trying to get it declared correctly in the hosts file 146433965Sjdp is a pointless waste of time. */ 146533965Sjdp 146633965Sjdpstatic void 146733965Sjdpchew_exit () 146833965Sjdp{ 146933965Sjdp exit (0); 147033965Sjdp} 147133965Sjdp 147277298Sobrienint 147377298Sobrienmain (ac, av) 147477298Sobrien int ac; 147577298Sobrien char *av[]; 147633965Sjdp{ 147733965Sjdp unsigned int i; 147833965Sjdp string_type buffer; 147933965Sjdp string_type pptr; 148033965Sjdp 148177298Sobrien init_string (&buffer); 148277298Sobrien init_string (&pptr); 148377298Sobrien init_string (stack + 0); 148477298Sobrien tos = stack + 1; 148533965Sjdp ptr = &pptr; 148677298Sobrien 148777298Sobrien add_intrinsic ("push_text", push_text); 148877298Sobrien add_intrinsic ("!", bang); 148977298Sobrien add_intrinsic ("@", atsign); 149077298Sobrien add_intrinsic ("hello", hello); 149177298Sobrien add_intrinsic ("stdout", stdout_); 149277298Sobrien add_intrinsic ("stderr", stderr_); 149377298Sobrien add_intrinsic ("print", print); 149477298Sobrien add_intrinsic ("skip_past_newline", skip_past_newline); 149577298Sobrien add_intrinsic ("catstr", icatstr); 149677298Sobrien add_intrinsic ("copy_past_newline", icopy_past_newline); 149777298Sobrien add_intrinsic ("dup", other_dup); 149877298Sobrien add_intrinsic ("drop", drop); 149977298Sobrien add_intrinsic ("idrop", idrop); 150077298Sobrien add_intrinsic ("remchar", remchar); 150177298Sobrien add_intrinsic ("get_stuff_in_command", get_stuff_in_command); 150277298Sobrien add_intrinsic ("do_fancy_stuff", do_fancy_stuff); 150377298Sobrien add_intrinsic ("bulletize", bulletize); 150477298Sobrien add_intrinsic ("courierize", courierize); 150533965Sjdp /* If the following line gives an error, exit() is not declared in the 150633965Sjdp ../hosts/foo.h file for this host. Fix it there, not here! */ 150733965Sjdp /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */ 150877298Sobrien add_intrinsic ("exit", chew_exit); 150977298Sobrien add_intrinsic ("swap", swap); 151077298Sobrien add_intrinsic ("outputdots", outputdots); 151177298Sobrien add_intrinsic ("paramstuff", paramstuff); 151277298Sobrien add_intrinsic ("maybecatstr", maybecatstr); 151377298Sobrien add_intrinsic ("translatecomments", translatecomments); 151477298Sobrien add_intrinsic ("kill_bogus_lines", kill_bogus_lines); 151577298Sobrien add_intrinsic ("indent", indent); 151677298Sobrien add_intrinsic ("internalmode", internalmode); 151777298Sobrien add_intrinsic ("print_stack_level", print_stack_level); 151877298Sobrien add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines); 151933965Sjdp 152077298Sobrien /* Put a nl at the start. */ 152177298Sobrien catchar (&buffer, '\n'); 152277298Sobrien 152377298Sobrien read_in (&buffer, stdin); 152477298Sobrien remove_noncomments (&buffer, ptr); 152577298Sobrien for (i = 1; i < (unsigned int) ac; i++) 152633965Sjdp { 152777298Sobrien if (av[i][0] == '-') 152877298Sobrien { 152977298Sobrien if (av[i][1] == 'f') 153077298Sobrien { 153177298Sobrien string_type b; 153277298Sobrien FILE *f; 153377298Sobrien init_string (&b); 153433965Sjdp 153577298Sobrien f = fopen (av[i + 1], "r"); 153677298Sobrien if (!f) 153777298Sobrien { 153877298Sobrien fprintf (stderr, "Can't open the input file %s\n", 153977298Sobrien av[i + 1]); 154077298Sobrien return 33; 154177298Sobrien } 154277298Sobrien 154377298Sobrien read_in (&b, f); 154477298Sobrien compile (b.ptr); 154577298Sobrien perform (); 154677298Sobrien } 154777298Sobrien else if (av[i][1] == 'i') 154877298Sobrien { 154977298Sobrien internal_wanted = 1; 155077298Sobrien } 155177298Sobrien else if (av[i][1] == 'w') 155277298Sobrien { 155377298Sobrien warning = 1; 155477298Sobrien } 155577298Sobrien else 155677298Sobrien usage (); 155733965Sjdp } 155833965Sjdp } 155977298Sobrien write_buffer (stack + 0, stdout); 156033965Sjdp if (tos != stack) 156133965Sjdp { 156277298Sobrien fprintf (stderr, "finishing with current stack level %d\n", 156377298Sobrien tos - stack); 156433965Sjdp return 1; 156533965Sjdp } 156633965Sjdp return 0; 156733965Sjdp} 1568