2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by steve chamberlain @cygnus
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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> ;
36 /* Primitives provided by the program:
38 Two stacks are provided, a string stack and an integer stack.
40 Internal state variables:
41 internal_wanted - indicates whether `-i' was passed
42 internal_mode - user-settable
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)
55 copy_past_newline - append input, up to and including newline into TOS
59 remchar - delete last character from TOS
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 {* *} { }
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
71 translatecomments - turn {* and *} into comment delimiters
72 kill_bogus_lines - get rid of extra newlines
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
80 A command must be all upper-case, and alone on a line.
98 /* Here is a string type ... */
100 typedef struct buffer
103 unsigned long write_idx
;
108 static void init_string_with_size (string_type
*, unsigned int);
109 static void init_string (string_type
*);
110 static int find (string_type
*, char *);
111 static void write_buffer (string_type
*, FILE *);
112 static void delete_string (string_type
*);
113 static char *addr (string_type
*, unsigned int);
114 static char at (string_type
*, unsigned int);
115 static void catchar (string_type
*, int);
116 static void overwrite_string (string_type
*, string_type
*);
117 static void catbuf (string_type
*, char *, unsigned int);
118 static void cattext (string_type
*, char *);
119 static void catstr (string_type
*, string_type
*);
123 init_string_with_size (buffer
, size
)
127 buffer
->write_idx
= 0;
129 buffer
->ptr
= malloc (size
);
136 init_string_with_size (buffer
, DEF_SIZE
);
147 for (i
= 0; i
< str
->write_idx
&& *p
; i
++)
149 if (*p
== str
->ptr
[i
])
158 write_buffer (buffer
, f
)
162 fwrite (buffer
->ptr
, buffer
->write_idx
, 1, f
);
166 delete_string (buffer
)
177 return buffer
->ptr
+ idx
;
185 if (pos
>= buffer
->write_idx
)
187 return buffer
->ptr
[pos
];
195 if (buffer
->write_idx
== buffer
->size
)
198 buffer
->ptr
= realloc (buffer
->ptr
, buffer
->size
);
201 buffer
->ptr
[buffer
->write_idx
++] = ch
;
205 overwrite_string (dst
, src
)
210 dst
->size
= src
->size
;
211 dst
->write_idx
= src
->write_idx
;
216 catbuf (buffer
, buf
, len
)
221 if (buffer
->write_idx
+ len
>= buffer
->size
)
223 while (buffer
->write_idx
+ len
>= buffer
->size
)
225 buffer
->ptr
= realloc (buffer
->ptr
, buffer
->size
);
227 memcpy (buffer
->ptr
+ buffer
->write_idx
, buf
, len
);
228 buffer
->write_idx
+= len
;
232 cattext (buffer
, string
)
236 catbuf (buffer
, string
, (unsigned int) strlen (string
));
244 catbuf (dst
, src
->ptr
, src
->write_idx
);
248 skip_white_and_stars (src
, idx
)
253 while ((c
= at (src
, idx
)),
254 isspace ((unsigned char) c
)
256 /* Don't skip past end-of-comment or star as first
257 character on its line. */
258 && at (src
, idx
+1) != '/'
259 && at (src
, idx
-1) != '\n'))
264 /***********************************************************************/
266 string_type stack
[STACK
];
269 unsigned int idx
= 0; /* Pos in input buffer */
270 string_type
*ptr
; /* and the buffer */
271 typedef void (*stinst_type
)();
273 stinst_type sstack
[STACK
];
274 stinst_type
*ssp
= &sstack
[0];
276 long *isp
= &istack
[0];
278 typedef int *word_type
;
283 struct dict_struct
*next
;
290 typedef struct dict_struct dict_type
;
292 #define WORD(x) static void x()
298 fprintf (stderr
, "%s\n", msg
);
306 die ("underflow in string stack");
307 if (tos
>= stack
+ STACK
)
308 die ("overflow in string stack");
315 die ("underflow in integer stack");
316 if (isp
>= istack
+ STACK
)
317 die ("overflow in integer stack");
321 static void exec (dict_type
*);
322 static void call (void);
323 static void remchar (void), strip_trailing_newlines (void), push_number (void);
324 static void push_text (void);
325 static void remove_noncomments (string_type
*, string_type
*);
326 static void print_stack_level (void);
327 static void paramstuff (void), translatecomments (void);
328 static void outputdots (void), courierize (void), bulletize (void);
329 static void do_fancy_stuff (void);
330 static int iscommand (string_type
*, unsigned int);
331 static int copy_past_newline (string_type
*, unsigned int, string_type
*);
332 static void icopy_past_newline (void), kill_bogus_lines (void), indent (void);
333 static void get_stuff_in_command (void), swap (void), other_dup (void);
334 static void drop (void), idrop (void);
335 static void icatstr (void), skip_past_newline (void), internalmode (void);
336 static void maybecatstr (void);
337 static char *nextword (char *, char **);
338 dict_type
*lookup_word (char *);
339 static void perform (void);
340 dict_type
*newentry (char *);
341 unsigned int add_to_definition (dict_type
*, stinst_type
);
342 void add_intrinsic (char *, void (*)());
343 void add_var (char *);
344 void compile (char *);
345 static void bang (void);
346 static void atsign (void);
347 static void hello (void);
348 static void stdout_ (void);
349 static void stderr_ (void);
350 static void print (void);
351 static void read_in (string_type
*, FILE *);
352 static void usage (void);
353 static void chew_exit (void);
367 stinst_type
*oldpc
= pc
;
369 e
= (dict_type
*) (pc
[1]);
382 strip_trailing_newlines ()
384 while ((isspace ((unsigned char) at (tos
, tos
->write_idx
- 1))
385 || at (tos
, tos
->write_idx
- 1) == '\n')
386 && tos
->write_idx
> 0)
406 cattext (tos
, *((char **) pc
));
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. */
416 remove_noncomments (src
, dst
)
420 unsigned int idx
= 0;
422 while (at (src
, idx
))
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) == '*')
431 idx
= skip_white_and_stars (src
, idx
);
433 /* Remove leading dot */
434 if (at (src
, idx
) == '.')
437 /* Copy to the end of the line, or till the end of the
439 while (at (src
, idx
))
441 if (at (src
, idx
) == '\n')
443 /* end of line, echo and scrape of leading blanks */
444 if (at (src
, idx
+ 1) == '\n')
448 idx
= skip_white_and_stars (src
, idx
);
450 else if (at (src
, idx
) == '*' && at (src
, idx
+ 1) == '/')
453 cattext (dst
, "\nENDDD\n");
458 catchar (dst
, at (src
, idx
));
471 fprintf (stderr
, "current string stack depth = %d, ", tos
- stack
);
472 fprintf (stderr
, "current integer stack depth = %d\n", isp
- istack
);
480 name PARAMS ((stuff));
494 /* Make sure that it's not already param'd or proto'd. */
495 if (find (tos
, "PARAMS") || find (tos
, "PROTO") || !find (tos
, "("))
501 /* Find the open paren. */
502 for (openp
= 0; at (tos
, openp
) != '(' && at (tos
, openp
); openp
++)
506 /* Step back to the fname. */
508 while (fname
&& isspace ((unsigned char) at (tos
, fname
)))
511 && !isspace ((unsigned char) at (tos
,fname
))
512 && at (tos
,fname
) != '*')
517 /* Output type, omitting trailing whitespace character(s), if
519 for (len
= fname
; 0 < len
; len
--)
521 if (!isspace ((unsigned char) at (tos
, len
- 1)))
524 for (idx
= 0; idx
< len
; idx
++)
525 catchar (&out
, at (tos
, idx
));
527 cattext (&out
, "\n"); /* Insert a newline between type and fnname */
529 /* Output function name, omitting trailing whitespace
530 character(s), if any. */
531 for (len
= openp
; 0 < len
; len
--)
533 if (!isspace ((unsigned char) at (tos
, len
- 1)))
536 for (idx
= fname
; idx
< len
; idx
++)
537 catchar (&out
, at (tos
, idx
));
539 cattext (&out
, " PARAMS (");
541 for (idx
= openp
; at (tos
, idx
) && at (tos
, idx
) != ';'; idx
++)
542 catchar (&out
, at (tos
, idx
));
544 cattext (&out
, ");\n\n");
546 overwrite_string (tos
, &out
);
552 and *} into comments */
554 WORD (translatecomments
)
556 unsigned int idx
= 0;
560 while (at (tos
, idx
))
562 if (at (tos
, idx
) == '{' && at (tos
, idx
+ 1) == '*')
564 cattext (&out
, "/*");
567 else if (at (tos
, idx
) == '*' && at (tos
, idx
+ 1) == '}')
569 cattext (&out
, "*/");
574 catchar (&out
, at (tos
, idx
));
579 overwrite_string (tos
, &out
);
586 /* This is not currently used. */
588 /* turn everything not starting with a . into a comment */
590 WORD (manglecomments
)
592 unsigned int idx
= 0;
596 while (at (tos
, idx
))
598 if (at (tos
, idx
) == '\n' && at (tos
, idx
+ 1) == '*')
600 cattext (&out
, " /*");
603 else if (at (tos
, idx
) == '*' && at (tos
, idx
+ 1) == '}')
605 cattext (&out
, "*/");
610 catchar (&out
, at (tos
, idx
));
615 overwrite_string (tos
, &out
);
622 /* Mod tos so that only lines with leading dots remain */
626 unsigned int idx
= 0;
630 while (at (tos
, idx
))
632 if (at (tos
, idx
) == '\n' && at (tos
, idx
+ 1) == '.')
637 while ((c
= at (tos
, idx
)) && c
!= '\n')
639 if (c
== '{' && at (tos
, idx
+ 1) == '*')
641 cattext (&out
, "/*");
644 else if (c
== '*' && at (tos
, idx
+ 1) == '}')
646 cattext (&out
, "*/");
655 catchar (&out
, '\n');
663 overwrite_string (tos
, &out
);
667 /* Find lines starting with . and | and put example around them on tos */
671 unsigned int idx
= 0;
676 while (at (tos
, idx
))
678 if (at (tos
, idx
) == '\n'
679 && (at (tos
, idx
+1 ) == '.'
680 || at (tos
, idx
+ 1) == '|'))
682 cattext (&out
, "\n@example\n");
687 while (at (tos
, idx
) && at (tos
, idx
) != '\n')
691 /* We are inside {} parameters of some command;
692 Just pass through until matching brace. */
693 if (at (tos
, idx
) == '{')
695 else if (at (tos
, idx
) == '}')
698 else if (command
!= 0)
700 if (at (tos
, idx
) == '{')
702 else if (!islower ((unsigned char) at (tos
, idx
)))
705 else if (at (tos
, idx
) == '@'
706 && islower ((unsigned char) at (tos
, idx
+ 1)))
710 else if (at (tos
, idx
) == '{' && at (tos
, idx
+ 1) == '*')
712 cattext (&out
, "/*");
716 else if (at (tos
, idx
) == '*' && at (tos
, idx
+ 1) == '}')
718 cattext (&out
, "*/");
722 else if (at (tos
, idx
) == '{'
723 || at (tos
, idx
) == '}')
728 catchar (&out
, at (tos
, idx
));
731 catchar (&out
, '\n');
733 while (at (tos
, idx
) == '\n'
734 && ((at (tos
, idx
+ 1) == '.')
735 || (at (tos
, idx
+ 1) == '|')))
737 cattext (&out
, "@end example");
741 catchar (&out
, at (tos
, idx
));
746 overwrite_string (tos
, &out
);
750 /* Finds any lines starting with "o ", if there are any, then turns
751 on @itemize @bullet, and @items each of them. Then ends with @end
752 itemize, inplace at TOS*/
756 unsigned int idx
= 0;
761 while (at (tos
, idx
))
763 if (at (tos
, idx
) == '@'
764 && at (tos
, idx
+ 1) == '*')
769 else if (at (tos
, idx
) == '\n'
770 && at (tos
, idx
+ 1) == 'o'
771 && isspace ((unsigned char) at (tos
, idx
+ 2)))
775 cattext (&out
, "\n@itemize @bullet\n");
779 cattext (&out
, "\n@item\n");
784 catchar (&out
, at (tos
, idx
));
785 if (on
&& at (tos
, idx
) == '\n'
786 && at (tos
, idx
+ 1) == '\n'
787 && at (tos
, idx
+ 2) != 'o')
789 cattext (&out
, "@end itemize");
798 cattext (&out
, "@end itemize\n");
806 /* Turn <<foo>> into @code{foo} in place at TOS*/
808 WORD (do_fancy_stuff
)
810 unsigned int idx
= 0;
813 while (at (tos
, idx
))
815 if (at (tos
, idx
) == '<'
816 && at (tos
, idx
+ 1) == '<'
817 && !isspace ((unsigned char) at (tos
, idx
+ 2)))
819 /* This qualifies as a << startup. */
821 cattext (&out
, "@code{");
823 && at (tos
, idx
) != '>' )
825 catchar (&out
, at (tos
, idx
));
834 catchar (&out
, at (tos
, idx
));
844 /* A command is all upper case,and alone on a line. */
851 unsigned int len
= 0;
852 while (at (ptr
, idx
))
854 if (isupper ((unsigned char) at (ptr
, idx
))
855 || at (ptr
, idx
) == ' ' || at (ptr
, idx
) == '_')
860 else if (at (ptr
, idx
) == '\n')
873 copy_past_newline (ptr
, idx
, dst
)
880 while (at (ptr
, idx
) && at (ptr
, idx
) != '\n')
882 if (at (ptr
, idx
) == '\t')
884 /* Expand tabs. Neither makeinfo nor TeX can cope well with
888 while (++column
& 7);
892 catchar (dst
, at (ptr
, idx
));
898 catchar (dst
, at (ptr
, idx
));
904 WORD (icopy_past_newline
)
909 idx
= copy_past_newline (ptr
, idx
, tos
);
914 Take the string at the top of the stack, do some prettying. */
916 WORD (kill_bogus_lines
)
926 /* Drop leading nl. */
927 while (at (tos
, idx
) == '\n')
933 /* If the first char is a '.' prepend a newline so that it is
934 recognized properly later. */
935 if (at (tos
, idx
) == '.')
936 catchar (&out
, '\n');
938 /* Find the last char. */
939 while (at (tos
, idx
))
944 /* Find the last non white before the nl. */
947 while (idx
&& isspace ((unsigned char) at (tos
, idx
)))
951 /* Copy buffer upto last char, but blank lines before and after
957 if (at (tos
, c
) == '\n'
958 && at (tos
, c
+ 1) == '\n'
959 && at (tos
, c
+ 2) == '.')
961 /* Ignore two newlines before a dot. */
964 else if (at (tos
, c
) == '.' && sl
)
966 /* remember that this line started with a dot. */
969 else if (at (tos
, c
) == '\n'
970 && at (tos
, c
+ 1) == '\n'
974 /* Ignore two newlines when last line was dot. */
977 catchar (&out
, at (tos
, c
));
978 if (at (tos
, c
) == '\n')
995 catchar (&out
, '\n');
1009 while (at (tos
, idx
))
1011 switch (at (tos
, idx
))
1014 cattext (&out
, "\n");
1016 if (tab
&& at (tos
, idx
))
1018 cattext (&out
, " ");
1025 cattext (&out
, " ");
1027 cattext (&out
, "(");
1032 cattext (&out
, ")");
1038 catchar (&out
, at (tos
, idx
));
1047 delete_string (tos
);
1052 WORD (get_stuff_in_command
)
1058 while (at (ptr
, idx
))
1060 if (iscommand (ptr
, idx
))
1062 idx
= copy_past_newline (ptr
, idx
, tos
);
1082 catstr (tos
, tos
- 1);
1104 catstr (tos
, tos
+ 1);
1105 delete_string (tos
+ 1);
1109 WORD (skip_past_newline
)
1111 while (at (ptr
, idx
)
1112 && at (ptr
, idx
) != '\n')
1120 internal_mode
= *(isp
);
1128 if (internal_wanted
== internal_mode
)
1130 catstr (tos
- 1, tos
);
1132 delete_string (tos
);
1139 nextword (string
, word
)
1150 while (isspace ((unsigned char) *string
) || *string
== '-')
1154 while (*string
&& *string
!= '\n')
1166 word_start
= string
;
1173 if (*string
== '\\')
1179 while (*string
!= '"');
1183 while (!isspace ((unsigned char) *string
))
1191 *word
= malloc (length
+ 1);
1196 for (idx
= 0; idx
< length
; idx
++)
1198 if (src
[idx
] == '\\')
1199 switch (src
[idx
+ 1])
1207 *dst
++ = src
[idx
+ 1];
1231 dict_type
*ptr
= root
;
1234 if (strcmp (ptr
->word
, word
) == 0)
1239 fprintf (stderr
, "Can't find %s\n", word
);
1248 while (at (ptr
, idx
))
1250 /* It's worth looking through the command list. */
1251 if (iscommand (ptr
, idx
))
1256 (void) nextword (addr (ptr
, idx
), &next
);
1258 word
= lookup_word (next
);
1267 fprintf (stderr
, "warning, %s is not recognised\n", next
);
1268 skip_past_newline ();
1273 skip_past_newline ();
1281 dict_type
*new = (dict_type
*) malloc (sizeof (dict_type
));
1285 new->code
= (stinst_type
*) malloc (sizeof (stinst_type
));
1286 new->code_length
= 1;
1292 add_to_definition (entry
, word
)
1296 if (entry
->code_end
== entry
->code_length
)
1298 entry
->code_length
+= 2;
1300 (stinst_type
*) realloc ((char *) (entry
->code
),
1301 entry
->code_length
* sizeof (word_type
));
1303 entry
->code
[entry
->code_end
] = word
;
1305 return entry
->code_end
++;
1309 add_intrinsic (name
, func
)
1313 dict_type
*new = newentry (name
);
1314 add_to_definition (new, func
);
1315 add_to_definition (new, 0);
1322 dict_type
*new = newentry (name
);
1323 add_to_definition (new, push_number
);
1324 add_to_definition (new, (stinst_type
) (&(new->var
)));
1325 add_to_definition (new, 0);
1332 /* Add words to the dictionary. */
1334 string
= nextword (string
, &word
);
1335 while (string
&& *string
&& word
[0])
1337 if (strcmp (word
, "var") == 0)
1339 string
= nextword (string
, &word
);
1342 string
= nextword (string
, &word
);
1344 else if (word
[0] == ':')
1347 /* Compile a word and add to dictionary. */
1348 string
= nextword (string
, &word
);
1350 ptr
= newentry (word
);
1351 string
= nextword (string
, &word
);
1352 while (word
[0] != ';')
1357 /* got a string, embed magic push string
1359 add_to_definition (ptr
, push_text
);
1360 add_to_definition (ptr
, (stinst_type
) (word
+ 1));
1372 /* Got a number, embedd the magic push number
1374 add_to_definition (ptr
, push_number
);
1375 add_to_definition (ptr
, (stinst_type
) atol (word
));
1378 add_to_definition (ptr
, call
);
1379 add_to_definition (ptr
, (stinst_type
) lookup_word (word
));
1382 string
= nextword (string
, &word
);
1384 add_to_definition (ptr
, 0);
1385 string
= nextword (string
, &word
);
1389 fprintf (stderr
, "syntax error at %s\n", string
- 1);
1397 *(long *) ((isp
[0])) = isp
[-1];
1405 isp
[0] = *(long *) (isp
[0]);
1434 write_buffer (tos
, stdout
);
1436 write_buffer (tos
, stderr
);
1438 fprintf (stderr
, "print: illegal print destination `%ld'\n", *isp
);
1455 r
= fread (buff
, 1, sizeof (buff
), file
);
1456 catbuf (str
, buff
, r
);
1461 catbuf (str
, buff
, 1);
1467 fprintf (stderr
, "usage: -[d|i|g] <file >file\n");
1471 /* There is no reliable way to declare exit. Sometimes it returns
1472 int, and sometimes it returns void. Sometimes it changes between
1473 OS releases. Trying to get it declared correctly in the hosts file
1474 is a pointless waste of time. */
1491 init_string (&buffer
);
1492 init_string (&pptr
);
1493 init_string (stack
+ 0);
1497 add_intrinsic ("push_text", push_text
);
1498 add_intrinsic ("!", bang
);
1499 add_intrinsic ("@", atsign
);
1500 add_intrinsic ("hello", hello
);
1501 add_intrinsic ("stdout", stdout_
);
1502 add_intrinsic ("stderr", stderr_
);
1503 add_intrinsic ("print", print
);
1504 add_intrinsic ("skip_past_newline", skip_past_newline
);
1505 add_intrinsic ("catstr", icatstr
);
1506 add_intrinsic ("copy_past_newline", icopy_past_newline
);
1507 add_intrinsic ("dup", other_dup
);
1508 add_intrinsic ("drop", drop
);
1509 add_intrinsic ("idrop", idrop
);
1510 add_intrinsic ("remchar", remchar
);
1511 add_intrinsic ("get_stuff_in_command", get_stuff_in_command
);
1512 add_intrinsic ("do_fancy_stuff", do_fancy_stuff
);
1513 add_intrinsic ("bulletize", bulletize
);
1514 add_intrinsic ("courierize", courierize
);
1515 /* If the following line gives an error, exit() is not declared in the
1516 ../hosts/foo.h file for this host. Fix it there, not here! */
1517 /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */
1518 add_intrinsic ("exit", chew_exit
);
1519 add_intrinsic ("swap", swap
);
1520 add_intrinsic ("outputdots", outputdots
);
1521 add_intrinsic ("paramstuff", paramstuff
);
1522 add_intrinsic ("maybecatstr", maybecatstr
);
1523 add_intrinsic ("translatecomments", translatecomments
);
1524 add_intrinsic ("kill_bogus_lines", kill_bogus_lines
);
1525 add_intrinsic ("indent", indent
);
1526 add_intrinsic ("internalmode", internalmode
);
1527 add_intrinsic ("print_stack_level", print_stack_level
);
1528 add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines
);
1530 /* Put a nl at the start. */
1531 catchar (&buffer
, '\n');
1533 read_in (&buffer
, stdin
);
1534 remove_noncomments (&buffer
, ptr
);
1535 for (i
= 1; i
< (unsigned int) ac
; i
++)
1537 if (av
[i
][0] == '-')
1539 if (av
[i
][1] == 'f')
1545 f
= fopen (av
[i
+ 1], "r");
1548 fprintf (stderr
, "Can't open the input file %s\n",
1557 else if (av
[i
][1] == 'i')
1559 internal_wanted
= 1;
1561 else if (av
[i
][1] == 'w')
1569 write_buffer (stack
+ 0, stdout
);
1572 fprintf (stderr
, "finishing with current stack level %d\n",
This page took 0.06185 seconds and 4 git commands to generate.