os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/man2tcl.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/man2tcl.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,418 @@
     1.4 +/* 
     1.5 + * man2tcl.c --
     1.6 + *
     1.7 + *	This file contains a program that turns a man page of the
     1.8 + *	form used for Tcl and Tk into a Tcl script that invokes
     1.9 + *	a Tcl command for each construct in the man page.  The
    1.10 + *	script can then be eval'ed to translate the manual entry
    1.11 + *	into some other format such as MIF or HTML.
    1.12 + *
    1.13 + * Usage:
    1.14 + *
    1.15 + *	man2tcl ?fileName?
    1.16 + *
    1.17 + * Copyright (c) 1995 Sun Microsystems, Inc.
    1.18 + *
    1.19 + * See the file "license.terms" for information on usage and redistribution
    1.20 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    1.21 + *
    1.22 + * RCS: @(#) $Id: man2tcl.c,v 1.7.2.1 2003/12/09 15:32:20 dkf Exp $
    1.23 + */
    1.24 +
    1.25 +static char sccsid[] = "@(#) man2tcl.c 1.3 95/08/12 17:34:08";
    1.26 +
    1.27 +#include <stdio.h>
    1.28 +#include <string.h>
    1.29 +#include <ctype.h>
    1.30 +#ifndef NO_ERRNO_H
    1.31 +#include <errno.h>
    1.32 +#endif
    1.33 +
    1.34 +/*
    1.35 + * Imported things that aren't defined in header files:
    1.36 + */
    1.37 +
    1.38 +/*
    1.39 + * Some <errno.h> define errno to be something complex and
    1.40 + * thread-aware; in that case we definitely do not want to declare
    1.41 + * errno ourselves!
    1.42 + */
    1.43 +#ifndef errno
    1.44 +extern int errno;
    1.45 +#endif
    1.46 +
    1.47 +/*
    1.48 + * Current line number, used for error messages.
    1.49 + */
    1.50 +
    1.51 +static int lineNumber;
    1.52 +
    1.53 +/*
    1.54 + * The variable below is set to 1 if an error occurs anywhere
    1.55 + * while reading in the file.
    1.56 + */
    1.57 +
    1.58 +static int status;
    1.59 +
    1.60 +/*
    1.61 + * The variable below is set to 1 if output should be generated.
    1.62 + * If it's 0, it means we're doing a pre-pass to make sure that
    1.63 + * the file can be properly parsed.
    1.64 + */
    1.65 +
    1.66 +static int writeOutput;
    1.67 +
    1.68 +/*
    1.69 + * Prototypes for procedures defined in this file:
    1.70 + */
    1.71 +
    1.72 +static void		DoMacro(char *line);
    1.73 +static void		DoText(char *line);
    1.74 +static void		QuoteText(char *string, int count);
    1.75 +
    1.76 +/*
    1.77 + *----------------------------------------------------------------------
    1.78 + *
    1.79 + * main --
    1.80 + *
    1.81 + *	This procedure is the main program, which does all of the work
    1.82 + *	of the program.
    1.83 + *
    1.84 + * Results:
    1.85 + *	None: exits with a 0 return status to indicate success, or
    1.86 + *	1 to indicate that there were problems in the translation.
    1.87 + *
    1.88 + * Side effects:
    1.89 + *	A Tcl script is output to standard output.  Error messages may
    1.90 + *	be output on standard error.
    1.91 + *
    1.92 + *----------------------------------------------------------------------
    1.93 + */
    1.94 +
    1.95 +int
    1.96 +main(argc, argv)
    1.97 +    int argc;			/* Number of command-line arguments. */
    1.98 +    char **argv;		/* Values of command-line arguments. */
    1.99 +{
   1.100 +    FILE *f;
   1.101 +#define MAX_LINE_SIZE 1000
   1.102 +    char line[MAX_LINE_SIZE];
   1.103 +    char *p;
   1.104 +
   1.105 +    /*
   1.106 +     * Find the file to read, and open it if it isn't stdin.
   1.107 +     */
   1.108 +
   1.109 +    if (argc == 1) {
   1.110 +	f = stdin;
   1.111 +    } else if (argc == 2) {
   1.112 +	f = fopen(argv[1], "r");
   1.113 +	if (f == NULL) {
   1.114 +	    fprintf(stderr, "Couldn't read \"%s\": %s\n", argv[1],
   1.115 +		    strerror(errno));
   1.116 +	    exit(1);
   1.117 +	}
   1.118 +    } else {
   1.119 +	fprintf(stderr, "Usage: %s ?fileName?\n", argv[0]);
   1.120 +    }
   1.121 +
   1.122 +    /*
   1.123 +     * Make two passes over the file.  In the first pass, just check
   1.124 +     * to make sure we can handle everything.  If there are problems,
   1.125 +     * generate output and stop.  If everything is OK, make a second
   1.126 +     * pass to actually generate output.
   1.127 +     */
   1.128 +
   1.129 +    for (writeOutput = 0; writeOutput < 2; writeOutput++) {
   1.130 +	lineNumber = 0;
   1.131 +	status = 0;
   1.132 +	while (fgets(line, MAX_LINE_SIZE, f) != NULL) {
   1.133 +	    for (p = line; *p != 0; p++) {
   1.134 +		if (*p == '\n') {
   1.135 +		    *p = 0;
   1.136 +		    break;
   1.137 +		}
   1.138 +	    }
   1.139 +	    lineNumber++;
   1.140 +    
   1.141 +	    if ((line[0] == '\'') && (line[1] == '\\') && (line[2] == '\"')) {
   1.142 +		/* 
   1.143 +		 * This line is a comment.  Ignore it.
   1.144 +		 */
   1.145 +    
   1.146 +		continue;
   1.147 +	    }
   1.148 +    
   1.149 +	    if (strlen(line) >= MAX_LINE_SIZE -1) {
   1.150 +		fprintf(stderr, "Too long line. Max is %d chars.\n",
   1.151 +			MAX_LINE_SIZE - 1);
   1.152 +		exit(1);
   1.153 +	    }
   1.154 +
   1.155 +	    if ((line[0] == '.') || (line[0] == '\'')) {
   1.156 +		/*
   1.157 +		 * This line is a macro invocation.
   1.158 +		 */
   1.159 +    
   1.160 +		DoMacro(line);
   1.161 +	    } else {
   1.162 +		/*
   1.163 +		 * This line is text, possibly with formatting characters
   1.164 +		 * embedded in it.
   1.165 +		 */
   1.166 +    
   1.167 +		DoText(line);
   1.168 +	    }
   1.169 +	}
   1.170 +	if (status != 0) {
   1.171 +	    break;
   1.172 +	}
   1.173 +	fseek(f, 0, SEEK_SET);
   1.174 +    }
   1.175 +    exit(status);
   1.176 +}
   1.177 +
   1.178 +/*
   1.179 + *----------------------------------------------------------------------
   1.180 + *
   1.181 + * DoMacro --
   1.182 + *
   1.183 + *	This procedure is called to handle a macro invocation.
   1.184 + *	It parses the arguments to the macro and generates a
   1.185 + *	Tcl command to handle the invocation.
   1.186 + *
   1.187 + * Results:
   1.188 + *	None.
   1.189 + *
   1.190 + * Side effects:
   1.191 + *	A Tcl command is written to stdout.
   1.192 + *
   1.193 + *----------------------------------------------------------------------
   1.194 + */
   1.195 +
   1.196 +static void
   1.197 +DoMacro(line)
   1.198 +    char *line;			/* The line of text that contains the
   1.199 +				 * macro invocation. */
   1.200 +{
   1.201 +    char *p, *end;
   1.202 +
   1.203 +    /*
   1.204 +     * If there is no macro name, then just skip the whole line.
   1.205 +     */
   1.206 +
   1.207 +    if ((line[1] == 0) || (isspace(line[1]))) {
   1.208 +	return;
   1.209 +    }
   1.210 +
   1.211 +    if (writeOutput) {
   1.212 +	printf("macro");
   1.213 +    }
   1.214 +    if (*line != '.') {
   1.215 +	if (writeOutput) {
   1.216 +	    printf("2");
   1.217 +	}
   1.218 +    }
   1.219 +
   1.220 +    /*
   1.221 +     * Parse the arguments to the macro (including the name), in order.
   1.222 +     */
   1.223 +
   1.224 +    p = line+1;
   1.225 +    while (1) {
   1.226 +	if (writeOutput) {
   1.227 +	    putc(' ', stdout);
   1.228 +	}
   1.229 +	if (*p == '"')  {
   1.230 +	    /*
   1.231 +	     * The argument is delimited by quotes.
   1.232 +	     */
   1.233 +
   1.234 +	    for (end = p+1; *end != '"'; end++) {
   1.235 +		if (*end == 0) {
   1.236 +		    fprintf(stderr,
   1.237 +			"Unclosed quote in macro call on line %d.\n",
   1.238 +			lineNumber);
   1.239 +		    status = 1;
   1.240 +		    break;
   1.241 +		}
   1.242 +	    }
   1.243 +	    QuoteText(p+1, (end-(p+1)));
   1.244 +	} else {
   1.245 +	    for (end = p+1;  (*end != 0) && !isspace(*end); end++) {
   1.246 +		/* Empty loop body. */
   1.247 +	    }
   1.248 +	    QuoteText(p, end-p);
   1.249 +	}
   1.250 +	if (*end == 0) {
   1.251 +	    break;
   1.252 +	}
   1.253 +	p = end+1;
   1.254 +	while (isspace(*p)) {
   1.255 +	    /*
   1.256 +	     * Skip empty space before next argument.
   1.257 +	     */
   1.258 +
   1.259 +	    p++;
   1.260 +	}
   1.261 +	if (*p == 0) {
   1.262 +	    break;
   1.263 +	}
   1.264 +    }
   1.265 +    if (writeOutput) {
   1.266 +	putc('\n', stdout);
   1.267 +    }
   1.268 +}
   1.269 +
   1.270 +/*
   1.271 + *----------------------------------------------------------------------
   1.272 + *
   1.273 + * DoText --
   1.274 + *
   1.275 + *	This procedure is called to handle a line of troff text.
   1.276 + *	It parses the text, generating Tcl commands for text and
   1.277 + *	for formatting stuff such as font changes.
   1.278 + *
   1.279 + * Results:
   1.280 + *	None.
   1.281 + *
   1.282 + * Side effects:
   1.283 + *	Tcl commands are written to stdout.
   1.284 + *
   1.285 + *----------------------------------------------------------------------
   1.286 + */
   1.287 +
   1.288 +static void
   1.289 +DoText(line)
   1.290 +    char *line;			/* The line of text. */
   1.291 +{
   1.292 +    char *p, *end;
   1.293 +
   1.294 +    /*
   1.295 +     * Divide the line up into pieces consisting of backslash sequences,
   1.296 +     * tabs, and other text.
   1.297 +     */
   1.298 +
   1.299 +    p = line;
   1.300 +    while (*p != 0) {
   1.301 +	if (*p == '\t') {
   1.302 +	    if (writeOutput) {
   1.303 +		printf("tab\n");
   1.304 +	    }
   1.305 +	    p++;
   1.306 +	} else if (*p != '\\') {
   1.307 +	    /*
   1.308 +	     * Ordinary text.
   1.309 +	     */
   1.310 +
   1.311 +	    for (end = p+1; (*end != '\\') && (*end != 0); end++) {
   1.312 +		/* Empty loop body. */
   1.313 +	    }
   1.314 +	    if (writeOutput) {
   1.315 +		printf("text ");
   1.316 +	    }
   1.317 +	    QuoteText(p, end-p);
   1.318 +	    if (writeOutput) {
   1.319 +		putc('\n', stdout);
   1.320 +	    }
   1.321 +	    p = end;
   1.322 +	} else {
   1.323 +	    /*
   1.324 +	     * A backslash sequence.  There are particular ones
   1.325 +	     * that we understand;  output an error message for
   1.326 +	     * anything else and just ignore the backslash.
   1.327 +	     */
   1.328 +
   1.329 +	    p++;
   1.330 +	    if (*p == 'f') {
   1.331 +		/*
   1.332 +		 * Font change.
   1.333 +		 */
   1.334 +
   1.335 +		if (writeOutput) {
   1.336 +		    printf("font %c\n", p[1]);
   1.337 +		}
   1.338 +		p += 2;
   1.339 +	    } else if (*p == '-') {
   1.340 +		if (writeOutput) {
   1.341 +		    printf("dash\n");
   1.342 +		}
   1.343 +		p++;
   1.344 +	    } else if (*p == 'e') {
   1.345 +		if (writeOutput) {
   1.346 +		    printf("text \\\\\n");
   1.347 +		}
   1.348 +		p++;
   1.349 +	    } else if (*p == '.') {
   1.350 +		if (writeOutput) {
   1.351 +		    printf("text .\n");
   1.352 +		}
   1.353 +		p++;
   1.354 +	    } else if (*p == '&') {
   1.355 +		p++;
   1.356 +	    } else if (*p == '(') {
   1.357 +		if ((p[1] == 0) || (p[2] == 0)) {
   1.358 +		    fprintf(stderr, "Bad \\( sequence on line %d.\n",
   1.359 +			    lineNumber);
   1.360 +		    status = 1;
   1.361 +		} else {
   1.362 +		    if (writeOutput) {
   1.363 +			printf("char {\\(%c%c}\n", p[1], p[2]);
   1.364 +		    }
   1.365 +		    p += 3;
   1.366 +		}
   1.367 +	    } else if (*p != 0) {
   1.368 +		if (writeOutput) {
   1.369 +		    printf("char {\\%c}\n", *p);
   1.370 +		}
   1.371 +		p++;
   1.372 +	    }
   1.373 +	}
   1.374 +    }
   1.375 +    if (writeOutput) {
   1.376 +	printf("newline\n");
   1.377 +    }
   1.378 +}
   1.379 +
   1.380 +/*
   1.381 + *----------------------------------------------------------------------
   1.382 + *
   1.383 + * QuoteText --
   1.384 + *
   1.385 + *	Copy the "string" argument to stdout, adding quote characters
   1.386 + *	around any special Tcl characters so that they'll just be treated
   1.387 + *	as ordinary text.
   1.388 + *
   1.389 + * Results:
   1.390 + *	None.
   1.391 + *
   1.392 + * Side effects:
   1.393 + *	Text is written to stdout.
   1.394 + *
   1.395 + *----------------------------------------------------------------------
   1.396 + */
   1.397 +
   1.398 +static void
   1.399 +QuoteText(string, count)
   1.400 +    char *string;		/* The line of text. */
   1.401 +    int count;			/* Number of characters to write from string. */
   1.402 +{
   1.403 +    if (count == 0) {
   1.404 +	if (writeOutput) {
   1.405 +	    printf("{}");
   1.406 +	}
   1.407 +	return;
   1.408 +    }
   1.409 +    for ( ; count > 0; string++, count--) {
   1.410 +	if ((*string == '$') || (*string == '[') || (*string == '{')
   1.411 +		|| (*string == ' ') || (*string == ';') || (*string == '\\')
   1.412 +		|| (*string == '"') || (*string == '\t')) {
   1.413 +	    if (writeOutput) {
   1.414 +		putc('\\', stdout);
   1.415 +	    }
   1.416 +	}
   1.417 +	if (writeOutput) {
   1.418 +	    putc(*string, stdout);
   1.419 +	}
   1.420 +    }
   1.421 +}