source: trunk/libs/newlib/src/newlib/doc/makedoc.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

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