2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Contributed by steve chamberlain @cygnus
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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
28 Basically, this is a sort of string forth, maybe we should call it
31 You define new words thus:
32 : <newword> <oldwords> ;
51 /* Here is a string type ... */
56 unsigned int write_idx
;
66 static void DEFUN(init_string_with_size
,(buffer
, size
),
67 string_type
*buffer AND
70 buffer
->write_idx
= 0;
72 buffer
->ptr
= malloc(size
);
75 static void DEFUN(init_string
,(buffer
),
78 init_string_with_size(buffer
, DEF_SIZE
);
82 static int DEFUN(find
, (str
, what
),
89 for (i
= 0; i
< str
->write_idx
&& *p
; i
++)
91 if (*p
== str
->ptr
[i
])
100 static void DEFUN(write_buffer
,(buffer
),
103 fwrite(buffer
->ptr
, buffer
->write_idx
, 1, stdout
);
107 static void DEFUN(delete_string
,(buffer
),
114 static char *DEFUN(addr
, (buffer
, idx
),
115 string_type
*buffer AND
118 return buffer
->ptr
+ idx
;
121 static char DEFUN(at
,(buffer
, pos
),
122 string_type
*buffer AND
125 if ( pos
>= buffer
->write_idx
)
129 return buffer
->ptr
[pos
];
132 static void DEFUN(catchar
,(buffer
, ch
),
133 string_type
*buffer AND
136 if (buffer
->write_idx
== buffer
->size
)
139 buffer
->ptr
= realloc(buffer
->ptr
, buffer
->size
);
142 buffer
->ptr
[buffer
->write_idx
++ ] = ch
;
146 static void DEFUN(overwrite_string
,(dst
, src
),
151 dst
->size
= src
->size
;
152 dst
->write_idx
= src
->write_idx
;
156 static void DEFUN(catstr
,(dst
, src
),
161 for (i
= 0; i
< src
->write_idx
; i
++)
163 catchar(dst
, src
->ptr
[i
]);
168 static void DEFUN(cattext
,(buffer
, string
),
169 string_type
*buffer AND
175 catchar(buffer
, *string
);
180 static void DEFUN(catbuf
,(buffer
, buf
, len
),
181 string_type
*buffer AND
188 catchar(buffer
, *buf
);
196 DEFUN(skip_white_and_stars
,(src
, idx
),
200 while (isspace(at(src
,idx
))
201 || (at(src
,idx
) == '*' && at(src
,idx
+1) !='/'))
207 /***********************************************************************/
210 string_type stack
[STACK
];
213 unsigned int idx
= 0; /* Pos in input buffer */
214 string_type
*ptr
; /* and the buffer */
215 typedef void (*stinst_type
)();
217 stinst_type sstack
[STACK
];
218 stinst_type
*ssp
= &sstack
[0];
220 int *isp
= &istack
[0];
222 typedef int *word_type
;
229 struct dict_struct
*next
;
236 typedef struct dict_struct dict_type
;
237 #define WORD(x) static void x()
239 static void DEFUN(exec
,(word
),
251 stinst_type
*oldpc
= pc
;
253 e
= (dict_type
*)(pc
[1]);
284 cattext(tos
,*((char **)pc
));
291 /* This function removes everything not inside comments starting on
292 the first char of the line from the string, also when copying
293 comments, removes blank space and leading *'s
294 Blank lines are turned into one blank line
298 DEFUN(remove_noncomments
,(src
,dst
),
302 unsigned int idx
= 0;
306 /* Now see if we have a comment at the start of the line */
307 if (at(src
,idx
) == '\n'
308 && at(src
,idx
+1) == '/'
309 && at(src
,idx
+2) == '*')
313 idx
= skip_white_and_stars(src
,idx
);
315 /* Remove leading dot */
316 if (at(src
, idx
) == '.')
319 /* Copy to the end of the line, or till the end of the
323 if (at(src
, idx
) == '\n')
325 /* end of line, echo and scrape of leading blanks */
326 if (at(src
,idx
+1) == '\n')
330 idx
= skip_white_and_stars(src
, idx
);
332 else if (at(src
, idx
) == '*' && at(src
,idx
+1) == '/')
335 cattext(dst
,"\nENDDD\n");
340 catchar(dst
, at(src
, idx
));
348 /* turn foobar name(stuff); into foobar EXFUN(name,(stuff));
353 DEFUN_VOID(exfunstuff
)
362 /* make sure that it's not already exfuned */
363 if(find(tos
,"EXFUN") || find(tos
,"PROTO") || !find(tos
,"(")) {
369 /*Find the open paren*/
370 for (openp
= 0; at(tos
, openp
) != '(' && at(tos
,openp
); openp
++)
374 /* Step back to the fname */
376 while (fname
&& isspace(at(tos
, fname
)))
378 while (fname
&& !isspace(at(tos
,fname
)) && at(tos
,fname
) != '*')
383 for (idx
= 0; idx
< fname
; idx
++)
385 catchar(&out
, at(tos
,idx
));
388 cattext(&out
,"EXFUN(");
389 for (idx
= fname
; idx
< openp
; idx
++)
391 catchar(&out
, at(tos
,idx
));
394 while (at(tos
,idx
) && at(tos
,idx
) !=';')
396 catchar(&out
, at(tos
, idx
));
399 cattext(&out
,");\n");
401 overwrite_string(tos
, &out
);
409 and *} into comments */
411 WORD(translatecomments
)
413 unsigned int idx
= 0;
419 if (at(tos
,idx
) == '{' && at(tos
,idx
+1) =='*')
424 else if (at(tos
,idx
) == '*' && at(tos
,idx
+1) =='}')
431 catchar(&out
, at(tos
, idx
));
437 overwrite_string(tos
, &out
);
443 /* turn everything not starting with a . into a comment */
447 unsigned int idx
= 0;
453 if (at(tos
,idx
) == '\n' && at(tos
,idx
+1) =='*')
458 else if (at(tos
,idx
) == '*' && at(tos
,idx
+1) =='}')
465 catchar(&out
, at(tos
, idx
));
471 overwrite_string(tos
, &out
);
477 /* Mod tos so that only lines with leading dots remain */
479 DEFUN_VOID(outputdots
)
481 unsigned int idx
= 0;
487 if (at(tos
, idx
) == '\n' && at(tos
, idx
+1) == '.')
491 while (at(tos
, idx
) && at(tos
, idx
)!='\n')
493 if (at(tos
,idx
) == '{' && at(tos
,idx
+1) =='*')
498 else if (at(tos
,idx
) == '*' && at(tos
,idx
+1) =='}')
505 catchar(&out
, at(tos
, idx
));
517 overwrite_string(tos
, &out
);
522 /* Find lines starting with . and | and put example around them on tos */
526 unsigned int idx
= 0;
532 if (at(tos
, idx
) == '\n'
533 && (at(tos
, idx
+1 ) == '.'
534 || at(tos
,idx
+1) == '|'))
536 cattext(&out
,"\n@example\n");
541 while (at(tos
, idx
) && at(tos
, idx
)!='\n')
543 if (at(tos
,idx
)=='{' && at(tos
,idx
+1) =='*')
548 else if (at(tos
,idx
)=='*' && at(tos
,idx
+1) =='}')
553 else if (at(tos
,idx
) == '{')
558 else if (at(tos
,idx
) == '}')
565 catchar(&out
, at(tos
, idx
));
572 while (at(tos
, idx
) == '\n'
573 && (at(tos
, idx
+1) == '.')
574 || (at(tos
,idx
+1) == '|'));
575 cattext(&out
,"@end example");
579 catchar(&out
, at(tos
, idx
));
584 overwrite_string(tos
, &out
);
590 /* Finds any lines starting with "o ", if there are any, then turns
591 on @itemize @bullet, and @items each of them. Then ends with @end
592 itemize, inplace at TOS*/
597 unsigned int idx
= 0;
602 while (at(tos
, idx
)) {
603 if (at(tos
, idx
) == '@' &&
604 at(tos
, idx
+1) == '*')
611 if (at(tos
, idx
) == '\n' &&
612 at(tos
, idx
+1) == 'o' &&
613 isspace(at(tos
, idx
+2)))
617 cattext(&out
,"\n@itemize @bullet\n");
621 cattext(&out
,"@item ");
626 catchar(&out
, at(tos
, idx
));
633 cattext(&out
,"@end itemize\n");
642 /* Turn <<foo>> into @code{foo} in place at TOS*/
647 unsigned int idx
= 0;
652 if (at(tos
, idx
) == '<'
653 && at(tos
, idx
+1) == '<'
654 && !isspace(at(tos
,idx
+ 2)))
656 /* This qualifies as a << startup */
658 cattext(&out
,"@code{");
662 catchar(&out
, at(tos
, idx
));
671 catchar(&out
, at(tos
, idx
));
680 /* A command is all upper case,and alone on a line */
682 DEFUN( iscommand
,(ptr
, idx
),
686 unsigned int len
= 0;
687 while (at(ptr
,idx
)) {
688 if (isupper(at(ptr
,idx
)) || at(ptr
,idx
) == ' ' ||
694 else if(at(ptr
,idx
) == '\n')
696 if (len
>4) return 1;
706 DEFUN(copy_past_newline
,(ptr
, idx
, dst
),
711 while (at(ptr
, idx
) && at(ptr
, idx
) != '\n')
713 catchar(dst
, at(ptr
, idx
));
717 catchar(dst
, at(ptr
, idx
));
723 WORD(icopy_past_newline
)
727 idx
= copy_past_newline(ptr
, idx
, tos
);
732 Take the string at the top of the stack, do some prettying */
737 WORD(kill_bogus_lines
)
748 /* Drop leading nl */
749 while (at(tos
,idx
) == '\n')
755 /* Find the last char */
761 /* find the last non white before the nl */
764 while (idx
&& isspace(at(tos
,idx
)))
768 /* Copy buffer upto last char, but blank lines before and after
774 if (at(tos
,c
) == '\n'
775 && at(tos
,c
+1) == '\n'
776 && at(tos
,c
+2) == '.')
778 /* Ignore two linelines before a dot*/
781 else if (at(tos
,c
) == '.' && sl
)
783 /* remember that this line started with a dot */
786 else if (at(tos
,c
) == '\n'
787 && at(tos
,c
+1) == '\n'
791 /* Ignore two newlines when last line was dot */
794 catchar(&out
, at(tos
,c
));
795 if (at(tos
,c
) == '\n')
799 if (dot
== 2)dot
=1;else dot
= 0;
822 while (at(tos
,idx
)) {
850 catchar(&out
,at(tos
,idx
));
865 WORD(get_stuff_in_command
)
870 while (at(ptr
, idx
)) {
871 if (iscommand(ptr
, idx
)) break;
872 idx
= copy_past_newline(ptr
, idx
, tos
);
908 WORD(skip_past_newline
)
911 && at(ptr
,idx
) != '\n')
920 internal_mode
= *(isp
);
927 if (internal_wanted
== internal_mode
)
938 DEFUN(nextword
,(string
, word
),
949 while (isspace(*string
) || *string
== '-') {
952 while (*string
&& *string
!= '\n')
960 if (!*string
) return 0;
968 while (*string
!= '"')
978 while (!isspace(*string
))
986 *word
= malloc(length
+ 1);
992 for (idx
= 0; idx
< length
; idx
++)
995 if (src
[idx
] == '\\' && src
[idx
+1] == 'n')
1001 else *dst
++ = src
[idx
];
1017 DEFUN(lookup_word
,(word
),
1020 dict_type
*ptr
= root
;
1022 if (strcmp(ptr
->word
, word
) == 0) return ptr
;
1027 fprintf(stderr
,"Can't find %s\n",word
);
1033 static void DEFUN_VOID(perform
)
1037 while (at(ptr
, idx
)) {
1038 /* It's worth looking through the command list */
1039 if (iscommand(ptr
, idx
))
1047 (void) nextword(addr(ptr
, idx
), &next
);
1050 word
= lookup_word(next
);
1062 fprintf(stderr
,"warning, %s is not recognised\n", next
);
1063 skip_past_newline();
1067 else skip_past_newline();
1073 DEFUN(newentry
,(word
),
1076 dict_type
*new = (dict_type
*)malloc(sizeof(dict_type
));
1080 new->code
= (stinst_type
*)malloc(sizeof(stinst_type
));
1081 new->code_length
= 1;
1089 DEFUN(add_to_definition
,(entry
, word
),
1090 dict_type
*entry AND
1093 if (entry
->code_end
== entry
->code_length
)
1095 entry
->code_length
+= 2;
1097 (stinst_type
*) realloc((char *)(entry
->code
),
1098 entry
->code_length
*sizeof(word_type
));
1100 entry
->code
[entry
->code_end
] = word
;
1102 return entry
->code_end
++;
1112 DEFUN(add_intrinsic
,(name
, func
),
1116 dict_type
*new = newentry(name
);
1117 add_to_definition(new, func
);
1118 add_to_definition(new, 0);
1128 DEFUN(add_var
,(name
),
1131 dict_type
*new = newentry(name
);
1132 add_to_definition(new, push_number
);
1133 add_to_definition(new, (stinst_type
)(&(new->var
)));
1134 add_to_definition(new,0);
1142 DEFUN(compile
, (string
),
1148 /* add words to the dictionary */
1150 string
= nextword(string
, &word
);
1151 while (string
&& *string
&& word
[0])
1153 if (strcmp(word
,"var")==0)
1155 string
=nextword(string
, &word
);
1158 string
=nextword(string
, &word
);
1165 /* Compile a word and add to dictionary */
1166 string
= nextword(string
, &word
);
1168 ptr
= newentry(word
);
1169 string
= nextword(string
, &word
);
1170 while (word
[0] != ';' )
1177 /* got a string, embed magic push string
1179 add_to_definition(ptr
, push_text
);
1180 add_to_definition(ptr
, (stinst_type
)(word
+1));
1192 /* Got a number, embedd the magic push number
1194 add_to_definition(ptr
, push_number
);
1195 add_to_definition(ptr
, atol(word
));
1198 add_to_definition(ptr
, call
);
1199 add_to_definition(ptr
, lookup_word(word
));
1202 string
= nextword(string
, &word
);
1204 add_to_definition(ptr
,0);
1205 string
= nextword(string
, &word
);
1209 fprintf(stderr
,"syntax error at %s\n",string
-1);
1216 static void DEFUN_VOID(bang
)
1218 *(int *)((isp
[0])) = isp
[-1];
1226 isp
[0] = *(int *)(isp
[0]);
1239 static void DEFUN(read_in
, (str
, file
),
1240 string_type
*str AND
1247 r
= fread(buff
, 1, sizeof(buff
), file
);
1248 catbuf(str
, buff
, r
);
1253 catbuf(str
, buff
,1);
1258 static void DEFUN_VOID(usage
)
1260 fprintf(stderr
,"usage: -[d|i|g] <file >file\n");
1264 int DEFUN(main
,(ac
,av
),
1275 init_string(&buffer
);
1277 init_string(stack
+0);
1281 add_intrinsic("push_text", push_text
);
1282 add_intrinsic("!", bang
);
1283 add_intrinsic("@", atsign
);
1284 add_intrinsic("hello",hello
);
1285 add_intrinsic("skip_past_newline", skip_past_newline
);
1286 add_intrinsic("catstr", icatstr
);
1287 add_intrinsic("copy_past_newline", icopy_past_newline
);
1288 add_intrinsic("dup", other_dup
);
1289 add_intrinsic("remchar", remchar
);
1290 add_intrinsic("get_stuff_in_command", get_stuff_in_command
);
1291 add_intrinsic("do_fancy_stuff", do_fancy_stuff
);
1292 add_intrinsic("bulletize", bulletize
);
1293 add_intrinsic("courierize", courierize
);
1294 add_intrinsic("exit", exit
);
1295 add_intrinsic("swap", swap
);
1296 add_intrinsic("outputdots", outputdots
);
1297 add_intrinsic("exfunstuff", exfunstuff
);
1298 add_intrinsic("maybecatstr", maybecatstr
);
1299 add_intrinsic("translatecomments", translatecomments
);
1300 add_intrinsic("kill_bogus_lines", kill_bogus_lines
);
1301 add_intrinsic("indent", indent
);
1302 add_intrinsic("internalmode", internalmode
);
1304 /* Put a nl at the start */
1305 catchar(&buffer
,'\n');
1307 read_in(&buffer
, stdin
);
1308 remove_noncomments(&buffer
, ptr
);
1309 for (i
= 1; i
< ac
; i
++)
1311 if (av
[i
][0] == '-')
1313 if (av
[i
][1] == 'f')
1319 f
= fopen(av
[i
+1],"r");
1322 fprintf(stderr
,"Can't open the input file %s\n",av
[i
+1]);
1331 else if (av
[i
][1] == 'i')
1333 internal_wanted
= 1;
1335 else if (av
[i
][1] == 'w')
1342 write_buffer(stack
+0);
This page took 0.067596 seconds and 4 git commands to generate.