os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/man2tcl.c
First public contribution.
4 * This file contains a program that turns a man page of the
5 * form used for Tcl and Tk into a Tcl script that invokes
6 * a Tcl command for each construct in the man page. The
7 * script can then be eval'ed to translate the manual entry
8 * into some other format such as MIF or HTML.
14 * Copyright (c) 1995 Sun Microsystems, Inc.
16 * See the file "license.terms" for information on usage and redistribution
17 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
19 * RCS: @(#) $Id: man2tcl.c,v 1.7.2.1 2003/12/09 15:32:20 dkf Exp $
22 static char sccsid[] = "@(#) man2tcl.c 1.3 95/08/12 17:34:08";
32 * Imported things that aren't defined in header files:
36 * Some <errno.h> define errno to be something complex and
37 * thread-aware; in that case we definitely do not want to declare
45 * Current line number, used for error messages.
48 static int lineNumber;
51 * The variable below is set to 1 if an error occurs anywhere
52 * while reading in the file.
58 * The variable below is set to 1 if output should be generated.
59 * If it's 0, it means we're doing a pre-pass to make sure that
60 * the file can be properly parsed.
63 static int writeOutput;
66 * Prototypes for procedures defined in this file:
69 static void DoMacro(char *line);
70 static void DoText(char *line);
71 static void QuoteText(char *string, int count);
74 *----------------------------------------------------------------------
78 * This procedure is the main program, which does all of the work
82 * None: exits with a 0 return status to indicate success, or
83 * 1 to indicate that there were problems in the translation.
86 * A Tcl script is output to standard output. Error messages may
87 * be output on standard error.
89 *----------------------------------------------------------------------
94 int argc; /* Number of command-line arguments. */
95 char **argv; /* Values of command-line arguments. */
98 #define MAX_LINE_SIZE 1000
99 char line[MAX_LINE_SIZE];
103 * Find the file to read, and open it if it isn't stdin.
108 } else if (argc == 2) {
109 f = fopen(argv[1], "r");
111 fprintf(stderr, "Couldn't read \"%s\": %s\n", argv[1],
116 fprintf(stderr, "Usage: %s ?fileName?\n", argv[0]);
120 * Make two passes over the file. In the first pass, just check
121 * to make sure we can handle everything. If there are problems,
122 * generate output and stop. If everything is OK, make a second
123 * pass to actually generate output.
126 for (writeOutput = 0; writeOutput < 2; writeOutput++) {
129 while (fgets(line, MAX_LINE_SIZE, f) != NULL) {
130 for (p = line; *p != 0; p++) {
138 if ((line[0] == '\'') && (line[1] == '\\') && (line[2] == '\"')) {
140 * This line is a comment. Ignore it.
146 if (strlen(line) >= MAX_LINE_SIZE -1) {
147 fprintf(stderr, "Too long line. Max is %d chars.\n",
152 if ((line[0] == '.') || (line[0] == '\'')) {
154 * This line is a macro invocation.
160 * This line is text, possibly with formatting characters
170 fseek(f, 0, SEEK_SET);
176 *----------------------------------------------------------------------
180 * This procedure is called to handle a macro invocation.
181 * It parses the arguments to the macro and generates a
182 * Tcl command to handle the invocation.
188 * A Tcl command is written to stdout.
190 *----------------------------------------------------------------------
195 char *line; /* The line of text that contains the
196 * macro invocation. */
201 * If there is no macro name, then just skip the whole line.
204 if ((line[1] == 0) || (isspace(line[1]))) {
218 * Parse the arguments to the macro (including the name), in order.
228 * The argument is delimited by quotes.
231 for (end = p+1; *end != '"'; end++) {
234 "Unclosed quote in macro call on line %d.\n",
240 QuoteText(p+1, (end-(p+1)));
242 for (end = p+1; (*end != 0) && !isspace(*end); end++) {
243 /* Empty loop body. */
251 while (isspace(*p)) {
253 * Skip empty space before next argument.
268 *----------------------------------------------------------------------
272 * This procedure is called to handle a line of troff text.
273 * It parses the text, generating Tcl commands for text and
274 * for formatting stuff such as font changes.
280 * Tcl commands are written to stdout.
282 *----------------------------------------------------------------------
287 char *line; /* The line of text. */
292 * Divide the line up into pieces consisting of backslash sequences,
293 * tabs, and other text.
303 } else if (*p != '\\') {
308 for (end = p+1; (*end != '\\') && (*end != 0); end++) {
309 /* Empty loop body. */
321 * A backslash sequence. There are particular ones
322 * that we understand; output an error message for
323 * anything else and just ignore the backslash.
333 printf("font %c\n", p[1]);
336 } else if (*p == '-') {
341 } else if (*p == 'e') {
343 printf("text \\\\\n");
346 } else if (*p == '.') {
351 } else if (*p == '&') {
353 } else if (*p == '(') {
354 if ((p[1] == 0) || (p[2] == 0)) {
355 fprintf(stderr, "Bad \\( sequence on line %d.\n",
360 printf("char {\\(%c%c}\n", p[1], p[2]);
364 } else if (*p != 0) {
366 printf("char {\\%c}\n", *p);
378 *----------------------------------------------------------------------
382 * Copy the "string" argument to stdout, adding quote characters
383 * around any special Tcl characters so that they'll just be treated
390 * Text is written to stdout.
392 *----------------------------------------------------------------------
396 QuoteText(string, count)
397 char *string; /* The line of text. */
398 int count; /* Number of characters to write from string. */
406 for ( ; count > 0; string++, count--) {
407 if ((*string == '$') || (*string == '[') || (*string == '{')
408 || (*string == ' ') || (*string == ';') || (*string == '\\')
409 || (*string == '"') || (*string == '\t')) {
415 putc(*string, stdout);