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