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