home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / bfd / doc / chew.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-07  |  21.5 KB  |  1,348 lines

  1. /* chew
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Contributed by steve chamberlain @cygnus
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /*
  22.  Yet another way of extracting documentation from source.
  23.  No, I haven't finished it yet, but I hope you people like it better
  24.  that the old way
  25.   
  26.  sac
  27.  
  28. Basically, this is a sort of string forth, maybe we should call it
  29. struth?
  30.  
  31. You define new words thus:
  32. : <newword> <oldwords> ;
  33. There is  no
  34.  
  35. */
  36.  
  37.  
  38.  
  39. #include <ansidecl.h>
  40. #include "sysdep.h"
  41.  
  42. #define DEF_SIZE 5000
  43. #define STACK 50
  44.  
  45. int internal_wanted;
  46. int internal_mode;
  47.  
  48. int warning;
  49.  
  50.  
  51. /* Here is a string type ... */
  52.  
  53. typedef struct buffer 
  54. {
  55.     char *ptr;
  56.     unsigned int write_idx;
  57.     unsigned int size;
  58. } string_type;
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. static void DEFUN(init_string_with_size,(buffer, size),
  67.        string_type *buffer AND
  68.        unsigned int size )
  69. {
  70.     buffer->write_idx = 0;
  71.     buffer->size = size;
  72.     buffer->ptr = malloc(size);
  73. }
  74.  
  75. static void DEFUN(init_string,(buffer),
  76.        string_type *buffer)
  77. {
  78.     init_string_with_size(buffer, DEF_SIZE);
  79.  
  80. }
  81.  
  82. static int DEFUN(find, (str, what),
  83.       string_type *str AND
  84.       char *what)
  85. {
  86.     unsigned int i;
  87.     char *p;
  88.     p = what;
  89.     for (i = 0; i < str->write_idx && *p; i++) 
  90.     {
  91.     if (*p == str->ptr[i])
  92.      p++;
  93.     else
  94.      p = what;
  95.     }
  96.     return (*p == 0);
  97.     
  98. }
  99.  
  100. static void DEFUN(write_buffer,(buffer),
  101.        string_type *buffer)
  102. {
  103.     fwrite(buffer->ptr, buffer->write_idx, 1, stdout);
  104. }
  105.  
  106.  
  107. static void DEFUN(delete_string,(buffer),
  108.        string_type *buffer)
  109. {
  110.     free(buffer->ptr);
  111. }
  112.  
  113.  
  114. static char *DEFUN(addr, (buffer, idx),
  115.         string_type *buffer AND
  116.         unsigned int idx)
  117. {
  118.     return buffer->ptr + idx;
  119. }
  120.  
  121. static char DEFUN(at,(buffer, pos),
  122.        string_type *buffer AND
  123.        unsigned int pos) 
  124. {
  125.     if ( pos >= buffer->write_idx) 
  126.     {
  127.     return 0;
  128.     }
  129.     return buffer->ptr[pos];
  130. }
  131.  
  132. static void DEFUN(catchar,(buffer, ch), 
  133.        string_type *buffer AND
  134.        char ch)
  135. {
  136.     if (buffer->write_idx == buffer->size) 
  137.     {
  138.     buffer->size *=2;
  139.     buffer->ptr = realloc(buffer->ptr, buffer->size);
  140.     }
  141.  
  142.     buffer->ptr[buffer->write_idx ++ ] = ch;
  143. }
  144.  
  145.  
  146. static void DEFUN(overwrite_string,(dst,   src),
  147.        string_type *dst AND
  148.        string_type *src)
  149. {
  150.     free(dst->ptr);
  151.     dst->size = src->size;
  152.     dst->write_idx = src->write_idx;
  153.     dst->ptr = src->ptr;
  154. }
  155.  
  156. static void DEFUN(catstr,(dst, src),
  157.        string_type *dst AND
  158.        string_type *src)
  159. {
  160.     unsigned int i;
  161.     for (i = 0; i < src->write_idx; i++) 
  162.     {
  163.     catchar(dst, src->ptr[i]);
  164.     }
  165. }
  166.  
  167.  
  168. static void DEFUN(cattext,(buffer, string),
  169.        string_type *buffer AND
  170.        char *string)
  171. {
  172.     
  173.     while (*string) 
  174.     {
  175.     catchar(buffer, *string);
  176.     string++;
  177.     }
  178. }
  179.  
  180. static void DEFUN(catbuf,(buffer, buf, len),
  181.        string_type *buffer AND
  182.        char *buf AND
  183.        unsigned int len)
  184. {
  185.     
  186.     while (len--) 
  187.     {
  188.     catchar(buffer, *buf);
  189.     buf++;
  190.     }
  191. }
  192.  
  193.  
  194.  
  195. static unsigned int 
  196. DEFUN(skip_white_and_stars,(src, idx),
  197.       string_type *src AND
  198.       unsigned int idx)
  199. {
  200.     while (isspace(at(src,idx)) 
  201.        || (at(src,idx) == '*' && at(src,idx +1) !='/')) 
  202.      idx++;
  203.     return idx;
  204.     
  205.  
  206. }
  207. /***********************************************************************/
  208.  
  209.  
  210. string_type stack[STACK];
  211. string_type *tos;
  212.  
  213. unsigned int idx = 0; /* Pos in input buffer */
  214. string_type *ptr; /* and the buffer */
  215. typedef void (*stinst_type)();
  216. stinst_type *pc;
  217. stinst_type sstack[STACK];
  218. stinst_type *ssp = &sstack[0];
  219. int istack[STACK];
  220. int *isp = &istack[0];
  221.  
  222. typedef int *word_type;
  223.  
  224.  
  225.  
  226. struct dict_struct
  227. {
  228.     char *word;
  229.     struct dict_struct *next;
  230.    stinst_type *code;
  231.     int code_length;
  232.     int code_end;
  233.     int var;
  234.     
  235. };
  236. typedef struct dict_struct dict_type;
  237. #define WORD(x) static void x()
  238.  
  239. static void DEFUN(exec,(word),
  240.           dict_type *word)
  241. {
  242.     pc = word->code;
  243.     while (*pc) 
  244.     {
  245.     (*pc)();
  246.     }
  247.     
  248. }
  249. WORD(call)
  250. {
  251. stinst_type *oldpc = pc;
  252.     dict_type *e;
  253.     e =  (dict_type *)(pc [1]);
  254.     exec(e);
  255.     pc = oldpc + 2;
  256.     
  257. }
  258.  
  259. WORD(remchar)
  260. {
  261.     tos->write_idx--;    
  262.     pc++;
  263.     
  264. }
  265.  
  266. WORD(push_number)
  267. {
  268.     isp++;
  269.     pc++;
  270.     *isp = (int)(*pc);
  271.     pc++;
  272.     
  273. }
  274.  
  275.  
  276.  
  277.  
  278. WORD(push_text)
  279. {
  280.     
  281.     tos++;
  282.     init_string(tos);
  283.     pc++;
  284.     cattext(tos,*((char **)pc));
  285.     pc++;
  286.     
  287. }
  288.  
  289.  
  290.    
  291. /* This function removes everything not inside comments starting on
  292.    the first char of the line from the  string, also when copying
  293.    comments, removes blank space and leading *'s 
  294.    Blank lines are turned into one blank line
  295.  */
  296.  
  297. static void 
  298. DEFUN(remove_noncomments,(src,dst),
  299.        string_type *src AND
  300.        string_type *dst)
  301. {
  302.     unsigned int idx = 0;
  303.     
  304.     while (at(src,idx)) 
  305.     {
  306.     /* Now see if we have a comment at the start of the line */
  307.     if (at(src,idx) == '\n' 
  308.         && at(src,idx+1) ==  '/' 
  309.         && at(src,idx+2) == '*') 
  310.     {
  311.         idx+=3;
  312.         
  313.         idx = skip_white_and_stars(src,idx);
  314.  
  315.         /* Remove leading dot */
  316.         if (at(src, idx) == '.')
  317.          idx++;
  318.         
  319.         /* Copy to the end of the line, or till the end of the
  320.            comment */
  321.         while (at(src, idx))
  322.         {
  323.         if (at(src, idx) == '\n') 
  324.         {
  325.             /* end of line, echo and scrape of leading blanks  */
  326.             if (at(src,idx +1) == '\n')
  327.              catchar(dst,'\n');
  328.             catchar(dst,'\n');
  329.             idx++;
  330.             idx =   skip_white_and_stars(src, idx);
  331.         }
  332.         else if (at(src, idx) == '*' && at(src,idx+1) == '/') 
  333.         {
  334.             idx +=2 ;
  335.             cattext(dst,"\nENDDD\n");
  336.             break;
  337.         }
  338.         else 
  339.         {
  340.             catchar(dst, at(src, idx));
  341.             idx++;
  342.         }
  343.         }
  344.     }
  345.     else idx++;
  346.     }
  347. }
  348. /* turn foobar name(stuff); into foobar EXFUN(name,(stuff));
  349.  
  350.  */
  351.  
  352. static void
  353. DEFUN_VOID(exfunstuff)
  354. {
  355.     unsigned int openp;
  356.     unsigned int fname;
  357.     unsigned int idx;
  358.     string_type out;
  359.     init_string(&out);
  360.     
  361.  
  362.     /* make sure that it's not already exfuned */
  363.     if(find(tos,"EXFUN") || find(tos,"PROTO") || !find(tos,"(")) {
  364.         catstr(&out,tos);
  365.     }
  366.     else 
  367.     {
  368.     
  369.     /*Find the open paren*/
  370.     for (openp = 0; at(tos, openp) != '('  && at(tos,openp); openp++)
  371.      ;
  372.  
  373.     fname = openp;
  374.     /* Step back to the fname */
  375.     fname--;
  376.     while (fname && isspace(at(tos, fname)))
  377.      fname --;
  378.     while (fname && !isspace(at(tos,fname)) && at(tos,fname) != '*')
  379.      fname--;
  380.  
  381.     fname++;
  382.     
  383.     for (idx = 0; idx < fname; idx++) 
  384.     {
  385.         catchar(&out, at(tos,idx));
  386.     }
  387.     
  388.     cattext(&out,"EXFUN(");
  389.     for (idx = fname; idx < openp; idx++) 
  390.     {
  391.         catchar(&out, at(tos,idx));
  392.     }
  393.     cattext(&out,", ");
  394.     while (at(tos,idx) && at(tos,idx) !=';') 
  395.     {
  396.         catchar(&out, at(tos, idx));
  397.         idx++;
  398.     }
  399.     cattext(&out,");\n");
  400.     }
  401.     overwrite_string(tos, &out);    
  402.     pc++;
  403.     
  404. }
  405.  
  406.  
  407.  
  408. /* turn {*
  409.    and *} into comments */
  410.  
  411. WORD(translatecomments)
  412. {
  413.     unsigned int idx = 0;
  414.     string_type out;
  415.     init_string(&out);
  416.     
  417.     while (at(tos, idx)) 
  418.     {
  419.     if (at(tos,idx) == '{' && at(tos,idx+1) =='*') 
  420.     {
  421.         cattext(&out,"    /*");
  422.         idx+=2;
  423.     }
  424.     else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  425.     {
  426.         cattext(&out,"*/");
  427.         idx+=2;
  428.     }
  429.     else  
  430.     {
  431.         catchar(&out, at(tos, idx));
  432.         idx++;
  433.     }
  434.     }
  435.  
  436.  
  437.     overwrite_string(tos, &out);
  438.     
  439.     pc++;
  440.     
  441. }
  442.  
  443. /* turn everything not starting with a . into a comment */
  444.  
  445. WORD(manglecomments)
  446. {
  447.     unsigned int idx = 0;
  448.     string_type out;
  449.     init_string(&out);
  450.     
  451.     while (at(tos, idx)) 
  452.     {
  453.     if (at(tos,idx) == '\n' && at(tos,idx+1) =='*') 
  454.     {
  455.         cattext(&out,"    /*");
  456.         idx+=2;
  457.     }
  458.     else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  459.     {
  460.         cattext(&out,"*/");
  461.         idx+=2;
  462.     }
  463.     else  
  464.     {
  465.         catchar(&out, at(tos, idx));
  466.         idx++;
  467.     }
  468.     }
  469.  
  470.  
  471.     overwrite_string(tos, &out);
  472.     
  473.     pc++;
  474.     
  475. }
  476.  
  477. /* Mod tos so that only lines with leading dots remain */
  478. static void
  479. DEFUN_VOID(outputdots)
  480. {
  481.     unsigned int idx = 0;
  482.     string_type out;
  483.     init_string(&out);
  484.     
  485.     while (at(tos, idx)) 
  486.     {
  487.     if (at(tos, idx) == '\n' && at(tos, idx+1) == '.') 
  488.     {
  489.         idx += 2;
  490.         
  491.         while (at(tos, idx) && at(tos, idx)!='\n')
  492.         {
  493.         if (at(tos,idx) == '{' && at(tos,idx+1) =='*') 
  494.         {
  495.             cattext(&out," /*");
  496.             idx+=2;
  497.         }
  498.         else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  499.         {
  500.             cattext(&out,"*/");
  501.             idx+=2;
  502.         }
  503.         else  
  504.         {
  505.             catchar(&out, at(tos, idx));
  506.             idx++;
  507.         }
  508.         }
  509.         catchar(&out,'\n');
  510.     }
  511.     else 
  512.     {
  513.         idx++;
  514.     }
  515.     }    
  516.  
  517.     overwrite_string(tos, &out);
  518.     pc++;
  519.     
  520. }
  521.  
  522. /* Find lines starting with . and | and put example around them on tos */
  523. WORD(courierize)
  524. {
  525.     string_type out;
  526.     unsigned int idx = 0;
  527.     
  528.     init_string(&out);
  529.     
  530.     while (at(tos, idx)) 
  531.     {
  532.     if (at(tos, idx) == '\n' 
  533.         && (at(tos, idx +1 ) == '.'
  534.         || at(tos,idx+1) == '|')) 
  535.     {
  536.         cattext(&out,"\n@example\n");
  537.         do 
  538.         {
  539.         idx += 2;
  540.         
  541.         while (at(tos, idx) && at(tos, idx)!='\n')
  542.         {
  543.             if (at(tos,idx)=='{' && at(tos,idx+1) =='*') 
  544.             {
  545.             cattext(&out," /*");
  546.             idx+=2;
  547.             }
  548.             else if (at(tos,idx)=='*' && at(tos,idx+1) =='}') 
  549.             {
  550.             cattext(&out,"*/");
  551.             idx+=2;
  552.             }
  553.                 else if (at(tos,idx) == '{')
  554.             {
  555.             cattext(&out,"@{");
  556.             idx++;
  557.             }
  558.                 else if (at(tos,idx) == '}')
  559.             {
  560.             cattext(&out,"@}");
  561.             idx++;
  562.             }
  563.             else 
  564.             {
  565.             catchar(&out, at(tos, idx));
  566.             idx++;
  567.             }
  568.             
  569.         }
  570.         catchar(&out,'\n');
  571.         }  
  572.         while (at(tos, idx) == '\n' 
  573.            && (at(tos, idx+1) == '.')
  574.            || (at(tos,idx+1) == '|'));
  575.         cattext(&out,"@end example");
  576.     }
  577.     else 
  578.     {    
  579.         catchar(&out, at(tos, idx));
  580.         idx++;
  581.     }
  582.     }    
  583.  
  584.     overwrite_string(tos, &out);
  585.     pc++;
  586.  
  587.     
  588. }
  589.  
  590. /* Finds any lines starting with "o ", if there are any, then turns
  591.    on @itemize @bullet, and @items each of them. Then ends with @end
  592.    itemize, inplace at TOS*/
  593.  
  594.  
  595. WORD(bulletize)
  596. {
  597.     unsigned int idx = 0;
  598.     int on = 0;
  599.     string_type out;
  600.     init_string(&out);
  601.     
  602.     while (at(tos, idx)) {
  603.     if (at(tos, idx) == '@' &&
  604.         at(tos, idx+1) == '*') 
  605.     {
  606.       cattext(&out,"*");
  607.       idx+=2;
  608.     }
  609.     
  610. else
  611.         if (at(tos, idx) == '\n' &&
  612.         at(tos, idx+1) == 'o' &&
  613.         isspace(at(tos, idx +2)))
  614.         {
  615.         if (!on) 
  616.         {
  617.             cattext(&out,"\n@itemize @bullet\n");
  618.             on = 1;
  619.             
  620.         }
  621.         cattext(&out,"@item ");
  622.         idx+=3;
  623.         }
  624.         else 
  625.         {
  626.         catchar(&out, at(tos, idx));
  627.         idx++;
  628.         
  629.         }
  630.     }
  631.     if (on) 
  632.     {
  633.     cattext(&out,"@end itemize\n");
  634.     }    
  635.  
  636.     delete_string(tos);
  637.     *tos = out;
  638.     pc++;
  639.     
  640. }
  641.  
  642. /* Turn <<foo>> into @code{foo} in place at TOS*/
  643.    
  644.  
  645. WORD(do_fancy_stuff)
  646. {
  647.     unsigned int idx = 0;
  648.     string_type out;
  649.     init_string(&out);
  650.     while (at(tos, idx)) 
  651.     {
  652.     if (at(tos, idx) == '<' 
  653.         && at(tos, idx+1) == '<'
  654.         && !isspace(at(tos,idx + 2))) 
  655.     {
  656.         /* This qualifies as a << startup */
  657.         idx +=2;
  658.         cattext(&out,"@code{");
  659.         while(at(tos,idx) &&
  660.           at(tos,idx) != '>' )
  661.         {
  662.         catchar(&out, at(tos, idx));
  663.         idx++;
  664.         
  665.         }
  666.         cattext(&out,"}");
  667.         idx+=2;
  668.     }
  669.     else 
  670.     {
  671.         catchar(&out, at(tos, idx));
  672.         idx++;
  673.     }
  674.     }
  675.     delete_string(tos);
  676.     *tos = out;
  677.     pc++;
  678.     
  679. }
  680. /* A command is all upper case,and alone on a line */
  681. static int 
  682. DEFUN( iscommand,(ptr, idx),
  683.       string_type *ptr AND
  684.       unsigned int idx)
  685. {
  686.     unsigned int len = 0;
  687.     while (at(ptr,idx)) {
  688.         if (isupper(at(ptr,idx)) || at(ptr,idx) == ' ' ||
  689.         at(ptr,idx) == '_') 
  690.         {
  691.          len++;
  692.          idx++;
  693.      }
  694.         else if(at(ptr,idx) == '\n')
  695.         {
  696.         if (len >4) return 1;
  697.         return 0;
  698.         }
  699.         else return 0;
  700.     }
  701.     return 0;
  702.  
  703. }
  704.  
  705.  
  706. DEFUN(copy_past_newline,(ptr, idx, dst),
  707.       string_type *ptr AND
  708.       unsigned int idx AND
  709.       string_type *dst)
  710. {
  711.     while (at(ptr, idx) && at(ptr, idx) != '\n') 
  712.     {
  713.     catchar(dst, at(ptr, idx));
  714.     idx++;
  715.     
  716.     }    
  717.     catchar(dst, at(ptr, idx));
  718.     idx++;
  719.     return idx;
  720.  
  721. }
  722.  
  723. WORD(icopy_past_newline)
  724. {
  725.     tos++;
  726.     init_string(tos);
  727.     idx = copy_past_newline(ptr, idx, tos);
  728.     pc++;    
  729. }
  730.  
  731. /* indent
  732.    Take the string at the top of the stack, do some prettying */
  733.  
  734.  
  735.  
  736.  
  737. WORD(kill_bogus_lines)
  738. {
  739.     int sl ;
  740.     
  741.     int nl = 0;
  742.     int idx = 0;
  743.     int c;
  744.     int dot = 0    ;
  745.     
  746.     string_type out;    
  747.     init_string(&out);
  748.     /* Drop leading nl */
  749.     while (at(tos,idx) == '\n')
  750.     {
  751.     idx++;
  752.     }
  753.     c = idx;
  754.     
  755.     /* Find the last char */
  756.     while (at(tos,idx))
  757.     {
  758.     idx++;
  759.     }
  760.     
  761.     /* find the last non white before the nl */
  762.     idx--;
  763.     
  764.     while (idx && isspace(at(tos,idx)))
  765.      idx--;
  766.     idx++;
  767.     
  768.     /* Copy buffer upto last char, but blank lines before and after
  769.        dots don't count */
  770.     sl = 1;
  771.  
  772.     while (c < idx)
  773.     {
  774.     if (at(tos,c) == '\n' 
  775.         && at(tos,c+1) == '\n'
  776.         && at(tos,c+2) == '.') 
  777.     {
  778.         /* Ignore two linelines before  a dot*/
  779.         c++;
  780.     }
  781.     else if (at(tos,c) == '.' && sl)
  782.     {
  783.         /* remember that this line started with a dot */
  784.         dot=2;
  785.     }
  786.     else if (at(tos,c) == '\n' 
  787.          && at(tos,c+1) == '\n'
  788.          && dot)
  789.     {
  790.         c++;
  791.         /* Ignore two newlines when last line was dot */
  792.     }
  793.  
  794.     catchar(&out, at(tos,c));
  795.     if (at(tos,c) == '\n')
  796.     {
  797.         sl = 1;
  798.         
  799.         if (dot == 2)dot=1;else dot = 0;
  800.     }
  801.     
  802.     c++;    
  803.  
  804.     }
  805.     
  806.     /* Append nl*/
  807.     catchar(&out, '\n');
  808.     pc++;
  809.     delete_string(tos);
  810.     *tos = out;
  811.     
  812.     
  813. }
  814.  
  815. WORD(indent)
  816. {
  817.     string_type out;
  818.     int tab = 0;
  819.     int idx = 0;
  820.     int ol =0;
  821.     init_string(&out);
  822.     while (at(tos,idx)) {
  823.         switch (at(tos,idx)) 
  824.         {
  825.           case '\n':
  826.         cattext(&out,"\n");
  827.         idx++;
  828.         if (tab) 
  829.         {
  830.             cattext(&out,"    ");
  831.         }
  832.         ol = 0;
  833.         break;
  834.           case '(':
  835.         tab++;
  836.         if (ol == 0)
  837.             cattext(&out,"   ");
  838.         idx++;
  839.         cattext(&out,"(");
  840.         ol = 1;
  841.         break;
  842.           case ')':
  843.         tab--;
  844.         cattext(&out,")");
  845.         idx++;
  846.         ol=1;
  847.         
  848.         break;
  849.           default:
  850.         catchar(&out,at(tos,idx));
  851.         ol=1;
  852.         
  853.         idx++;
  854.         break;
  855.         }
  856.     }    
  857.  
  858.     pc++;
  859.     delete_string(tos);
  860.     *tos = out;
  861.  
  862. }
  863.  
  864.  
  865. WORD(get_stuff_in_command)
  866. {
  867.     tos++;
  868.     init_string(tos);
  869.  
  870.     while (at(ptr, idx)) {
  871.         if (iscommand(ptr, idx))  break;
  872.         idx =   copy_past_newline(ptr, idx, tos);
  873.     }
  874. pc++;    
  875. }
  876.  
  877. WORD(swap)
  878. {
  879.     string_type t;
  880.     
  881.     t = tos[0];
  882.     tos[0] = tos[-1];
  883.     tos[-1] =t; 
  884.     pc++;
  885.     
  886. }
  887.  
  888. WORD(dup)
  889. {
  890.     tos++;
  891.     init_string(tos);
  892.     catstr(tos, tos-1);
  893.     pc++;
  894.     
  895. }
  896.  
  897.  
  898.  
  899. WORD(icatstr)
  900. {
  901.     catstr(tos-1, tos);
  902.     delete_string(tos);
  903.     tos--;
  904.     pc++;
  905.     
  906. }
  907.  
  908. WORD(skip_past_newline)
  909. {
  910.     while (at(ptr,idx) 
  911.        && at(ptr,idx) != '\n')
  912.      idx++;
  913.     idx++;
  914.     pc++;
  915. }
  916.  
  917.  
  918. WORD(internalmode)
  919. {
  920.     internal_mode = *(isp);
  921.     isp--;
  922.     pc++;
  923. }
  924.  
  925. WORD(maybecatstr)
  926. {
  927.     if (internal_wanted == internal_mode) 
  928.     {
  929.     catstr(tos-1, tos);
  930.     }
  931.     delete_string(tos);
  932.     tos--;
  933.     pc++;
  934.     
  935. }
  936.  
  937. char *
  938. DEFUN(nextword,(string, word),
  939.       char *string AND
  940.       char **word)
  941. {
  942.     char *word_start;
  943.     int idx;
  944.     char *dst;
  945.     char *src;
  946.     
  947.     int length = 0;
  948.     
  949.     while (isspace(*string) || *string == '-') {
  950.         if (*string == '-') 
  951.         {
  952.         while (*string && *string != '\n') 
  953.          string++;
  954.         
  955.         }
  956.         else {
  957.             string++;
  958.         }
  959.     }
  960.     if (!*string) return 0;
  961.     
  962.     word_start = string;        
  963.     if (*string == '"') 
  964.     {
  965.     string++;
  966.     length++;
  967.     
  968.     while (*string != '"') 
  969.     {
  970.         string++;
  971.         length++;
  972.     }
  973.     }
  974.     else     
  975.     {
  976.     
  977.  
  978.     while (!isspace(*string)) 
  979.     {
  980.         string++;
  981.         length++;
  982.     
  983.     }
  984.     }
  985.     
  986.     *word = malloc(length + 1);
  987.  
  988.     dst = *word;
  989.     src = word_start;
  990.  
  991.  
  992.     for (idx= 0; idx < length; idx++) 
  993.     {
  994.     
  995.     if (src[idx] == '\\' && src[idx+1] == 'n') 
  996.     {
  997.         *dst++ = '\n';
  998.         idx++;
  999.     
  1000.     }
  1001.     else *dst++ = src[idx];
  1002.     }
  1003.     *dst++ = 0;
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.     if(*string)    
  1010.      return string + 1;
  1011.     else 
  1012.      return 0;
  1013.     
  1014. }
  1015. dict_type *root;
  1016. dict_type *
  1017. DEFUN(lookup_word,(word),
  1018.       char *word)
  1019. {
  1020.   dict_type *ptr = root;
  1021.   while (ptr) {
  1022.       if (strcmp(ptr->word, word) == 0) return ptr;
  1023.       ptr = ptr->next;
  1024.         
  1025.     }
  1026.   if (warning)
  1027.    fprintf(stderr,"Can't find %s\n",word);
  1028.   return 0;
  1029.     
  1030.     
  1031. }
  1032.  
  1033. static void DEFUN_VOID(perform)
  1034. {
  1035.   tos = stack;
  1036.     
  1037.   while (at(ptr, idx)) {
  1038.       /* It's worth looking through the command list */
  1039.       if (iscommand(ptr, idx))
  1040.       {
  1041.     unsigned int i;
  1042.     int found = 0;
  1043.  
  1044.     char *next;
  1045.     dict_type *word ;
  1046.         
  1047.     (void)        nextword(addr(ptr, idx), &next);
  1048.  
  1049.  
  1050.     word = lookup_word(next);
  1051.  
  1052.  
  1053.         
  1054.  
  1055.     if (word) 
  1056.     {
  1057.       exec(word);
  1058.     }
  1059.     else
  1060.     {
  1061.       if (warning)
  1062.        fprintf(stderr,"warning, %s is not recognised\n",  next);
  1063.       skip_past_newline();
  1064.     }
  1065.         
  1066.       }
  1067.       else skip_past_newline();
  1068.  
  1069.     }
  1070. }
  1071.  
  1072. dict_type *
  1073. DEFUN(newentry,(word),
  1074.       char *word)
  1075. {
  1076.     dict_type *new = (dict_type *)malloc(sizeof(dict_type));
  1077.     new->word = word;
  1078.     new->next = root;
  1079.     root = new;
  1080.     new->code = (stinst_type *)malloc(sizeof(stinst_type ));
  1081.     new->code_length = 1;
  1082.     new->code_end = 0;
  1083.     return new;
  1084.     
  1085. }
  1086.  
  1087.  
  1088. unsigned int
  1089. DEFUN(add_to_definition,(entry, word), 
  1090.       dict_type *entry AND
  1091.       stinst_type word)
  1092. {
  1093.     if (entry->code_end == entry->code_length) 
  1094.     {
  1095.     entry->code_length += 2;
  1096.     entry->code =
  1097.      (stinst_type *) realloc((char *)(entry->code),
  1098.                    entry->code_length *sizeof(word_type));
  1099.     }
  1100.     entry->code[entry->code_end] = word;
  1101.     
  1102. return     entry->code_end++;  
  1103. }
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111. void
  1112. DEFUN(add_intrinsic,(name, func),
  1113.       char *name AND
  1114.       void (*func)())
  1115. {
  1116.     dict_type *new = newentry(name);
  1117.     add_to_definition(new, func);
  1118.     add_to_definition(new, 0);
  1119. }
  1120.  
  1121. WORD(push_addr)
  1122. {
  1123.     
  1124.  
  1125. }
  1126.  
  1127. void
  1128. DEFUN(add_var,(name),
  1129.       char *name)
  1130. {
  1131.     dict_type *new = newentry(name);
  1132.     add_to_definition(new, push_number);
  1133.     add_to_definition(new, (stinst_type)(&(new->var)));
  1134.     add_to_definition(new,0);
  1135.     
  1136. }
  1137.       
  1138.  
  1139.  
  1140.  
  1141. void 
  1142. DEFUN(compile, (string), 
  1143.       char *string)
  1144.  
  1145. {
  1146.     int jstack[STACK];
  1147.     int *jptr = jstack;
  1148.     /* add words to the dictionary */
  1149.     char *word;
  1150.     string = nextword(string, &word);
  1151.     while (string && *string && word[0]) 
  1152.     {
  1153.     if (strcmp(word,"var")==0) 
  1154.     {
  1155.  string=nextword(string, &word);
  1156.       
  1157.       add_var(word);
  1158.  string=nextword(string, &word);
  1159.     }
  1160. else    
  1161.         
  1162.     if (word[0] == ':')
  1163.     {
  1164.         dict_type *ptr;
  1165.         /* Compile a word and add to dictionary */
  1166.         string = nextword(string, &word);
  1167.         
  1168.         ptr = newentry(word);
  1169.         string = nextword(string, &word);
  1170.         while (word[0] != ';' ) 
  1171.         {
  1172.          switch (word[0]) 
  1173.          {
  1174.             
  1175.             
  1176.            case '"':
  1177.              /* got a string, embed magic push string
  1178.             function */
  1179.              add_to_definition(ptr, push_text);
  1180.              add_to_definition(ptr, (stinst_type)(word+1));
  1181.              break;
  1182.            case '0':
  1183.            case '1':
  1184.            case '2':
  1185.            case '3':
  1186.            case '4':
  1187.            case '5':
  1188.            case '6':
  1189.            case '7':
  1190.            case '8':
  1191.            case '9':
  1192.              /* Got a number, embedd the magic push number
  1193.             function */
  1194.              add_to_definition(ptr, push_number);
  1195.              add_to_definition(ptr, atol(word));
  1196.              break;
  1197.            default:
  1198.              add_to_definition(ptr, call);
  1199.              add_to_definition(ptr, lookup_word(word));
  1200.          }
  1201.  
  1202.         string = nextword(string, &word);             
  1203.         }
  1204.         add_to_definition(ptr,0);
  1205.         string = nextword(string, &word);
  1206.     }
  1207.     else 
  1208.     {
  1209.         fprintf(stderr,"syntax error at %s\n",string-1);
  1210.     }        
  1211.     }
  1212.  
  1213. }
  1214.  
  1215.  
  1216. static void DEFUN_VOID(bang)
  1217. {
  1218. *(int *)((isp[0])) = isp[-1];
  1219. isp-=2;
  1220. pc++;
  1221.  
  1222. }
  1223.  
  1224. WORD(atsign)
  1225. {
  1226.     isp[0] = *(int *)(isp[0]);
  1227.     pc++;
  1228. }
  1229.  
  1230. WORD(hello)
  1231. {
  1232.     
  1233.     printf("hello\n");
  1234.     pc++;    
  1235. }
  1236.  
  1237.  
  1238.  
  1239. static void DEFUN(read_in, (str, file), 
  1240.        string_type *str AND
  1241.           FILE *file)
  1242. {
  1243.     char buff[10000];    
  1244.     unsigned int r;
  1245.     do 
  1246.     {
  1247.     r = fread(buff, 1, sizeof(buff), file);
  1248.     catbuf(str, buff, r);
  1249.     }
  1250.     while (r);
  1251.     buff[0] = 0;
  1252.     
  1253.     catbuf(str, buff,1);
  1254.     
  1255. }
  1256.  
  1257.  
  1258. static void DEFUN_VOID(usage)
  1259. {
  1260.     fprintf(stderr,"usage: -[d|i|g] <file >file\n");
  1261.     exit(33);    
  1262. }
  1263.  
  1264. int DEFUN(main,(ac,av),
  1265. int ac AND
  1266. char *av[])
  1267. {
  1268.   unsigned int i;
  1269.     
  1270.  
  1271.   string_type buffer;
  1272.   string_type pptr;
  1273.     
  1274.  
  1275.   init_string(&buffer);
  1276.   init_string(&pptr);
  1277.   init_string(stack+0);
  1278.   tos=stack+1;
  1279.   ptr = &pptr;
  1280.     
  1281.   add_intrinsic("push_text", push_text);
  1282.   add_intrinsic("!", bang);
  1283.   add_intrinsic("@", atsign);
  1284.   add_intrinsic("hello",hello);    
  1285.   add_intrinsic("skip_past_newline", skip_past_newline );
  1286.   add_intrinsic("catstr", icatstr );
  1287.   add_intrinsic("copy_past_newline", icopy_past_newline );
  1288.   add_intrinsic("dup", dup );
  1289.   add_intrinsic("remchar", remchar );
  1290.   add_intrinsic("get_stuff_in_command", get_stuff_in_command );
  1291.   add_intrinsic("do_fancy_stuff", do_fancy_stuff );
  1292.   add_intrinsic("bulletize", bulletize );
  1293.   add_intrinsic("courierize", courierize );
  1294.   add_intrinsic("exit", exit );
  1295.   add_intrinsic("swap", swap );
  1296.   add_intrinsic("outputdots", outputdots );
  1297.   add_intrinsic("exfunstuff", exfunstuff );
  1298.   add_intrinsic("maybecatstr", maybecatstr );
  1299.   add_intrinsic("translatecomments", translatecomments );
  1300.   add_intrinsic("kill_bogus_lines", kill_bogus_lines);
  1301.   add_intrinsic("indent", indent);
  1302.   add_intrinsic("internalmode", internalmode);
  1303.     
  1304.   /* Put a nl at the start */
  1305.   catchar(&buffer,'\n');
  1306.  
  1307.   read_in(&buffer, stdin); 
  1308.   remove_noncomments(&buffer, ptr);
  1309.   for (i= 1; i < ac; i++) 
  1310.   {
  1311.     if (av[i][0] == '-')
  1312.     {
  1313.       if (av[i][1] == 'f')
  1314.       {
  1315.     string_type b;
  1316.     FILE *f;
  1317.     init_string(&b);
  1318.  
  1319.     f  = fopen(av[i+1],"r");
  1320.     if (!f) 
  1321.     {
  1322.       fprintf(stderr,"Can't open the input file %s\n",av[i+1]);
  1323.       return 33;
  1324.     }
  1325.         
  1326.           
  1327.     read_in(&b, f);
  1328.     compile(b.ptr);
  1329.     perform();    
  1330.       }
  1331.       else if (av[i][1] == 'i') 
  1332.       {
  1333.     internal_wanted = 1;
  1334.       }
  1335.       else if (av[i][1] == 'w') 
  1336.       {
  1337.     warning = 1;
  1338.       }
  1339.     }
  1340.  
  1341.   }      
  1342.   write_buffer(stack+0);
  1343.   return 0;
  1344. }
  1345.  
  1346.  
  1347.  
  1348.