os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/man2tcl.c
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 +}