OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [bfd/] [doc/] [chew.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.