aboutsummaryrefslogtreecommitdiffstats
path: root/developer_cmds
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
commit5fd83771641d15c418f747bd343ba6738d3875f7 (patch)
tree5abf0f78f680d9837dbd93d4d4c3933bb7509599 /developer_cmds
downloadapple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip
Import macOS userland
adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106
Diffstat (limited to 'developer_cmds')
-rw-r--r--developer_cmds/asa/asa.185
-rw-r--r--developer_cmds/asa/asa.c131
-rw-r--r--developer_cmds/ctags/C.c555
-rw-r--r--developer_cmds/ctags/ctags.1221
-rw-r--r--developer_cmds/ctags/ctags.c282
-rw-r--r--developer_cmds/ctags/ctags.h92
-rw-r--r--developer_cmds/ctags/fortran.c175
-rw-r--r--developer_cmds/ctags/lisp.c112
-rw-r--r--developer_cmds/ctags/print.c122
-rw-r--r--developer_cmds/ctags/test/ctags.test69
-rw-r--r--developer_cmds/ctags/tree.c142
-rw-r--r--developer_cmds/ctags/yacc.c158
-rw-r--r--developer_cmds/developer_cmds.xcodeproj/project.pbxproj787
-rw-r--r--developer_cmds/developer_cmds.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--developer_cmds/indent/args.c327
-rw-r--r--developer_cmds/indent/indent.1559
-rw-r--r--developer_cmds/indent/indent.c1234
-rw-r--r--developer_cmds/indent/indent.h47
-rw-r--r--developer_cmds/indent/indent_codes.h70
-rw-r--r--developer_cmds/indent/indent_globs.h329
-rw-r--r--developer_cmds/indent/io.c667
-rw-r--r--developer_cmds/indent/lexi.c608
-rw-r--r--developer_cmds/indent/parse.c332
-rw-r--r--developer_cmds/indent/pr_comment.c429
-rw-r--r--developer_cmds/lorder/lorder.175
-rw-r--r--developer_cmds/lorder/lorder.sh104
-rw-r--r--developer_cmds/rpcgen/rpc_clntout.c230
-rw-r--r--developer_cmds/rpcgen/rpc_cout.c741
-rw-r--r--developer_cmds/rpcgen/rpc_hout.c534
-rw-r--r--developer_cmds/rpcgen/rpc_main.c1170
-rw-r--r--developer_cmds/rpcgen/rpc_parse.c643
-rw-r--r--developer_cmds/rpcgen/rpc_parse.h168
-rw-r--r--developer_cmds/rpcgen/rpc_sample.c261
-rw-r--r--developer_cmds/rpcgen/rpc_scan.c521
-rw-r--r--developer_cmds/rpcgen/rpc_scan.h104
-rw-r--r--developer_cmds/rpcgen/rpc_svcout.c980
-rw-r--r--developer_cmds/rpcgen/rpc_tblout.c179
-rw-r--r--developer_cmds/rpcgen/rpc_util.c513
-rw-r--r--developer_cmds/rpcgen/rpc_util.h178
-rw-r--r--developer_cmds/rpcgen/rpcgen.1452
-rw-r--r--developer_cmds/unifdef/unifdef.1415
-rw-r--r--developer_cmds/unifdef/unifdef.c1235
-rw-r--r--developer_cmds/unifdef/unifdefall.sh79
-rw-r--r--developer_cmds/xcodescripts/install-lorder.sh7
-rw-r--r--developer_cmds/xcodescripts/install-unifdefall.sh9
45 files changed, 16138 insertions, 0 deletions
diff --git a/developer_cmds/asa/asa.1 b/developer_cmds/asa/asa.1
new file mode 100644
index 0000000..4c388a0
--- /dev/null
+++ b/developer_cmds/asa/asa.1
@@ -0,0 +1,85 @@
+.\" $NetBSD: asa.1,v 1.5 1997/09/20 14:55:00 lukem Exp $
+.\"
+.\" Copyright (c) 1993 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd September 23, 1993
+.Dt ASA 1
+.Os
+.Sh NAME
+.Nm asa
+.Nd interpret carriage-control characters.
+.Sh SYNOPSIS
+.Nm
+.Op Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility reads files sequentially, mapping
+.Tn FORTRAN
+carriage-control characters to line-printer control sequences,
+and writes them to the standard output.
+.Pp
+The first character of each line is interpreted as a carriage-control
+character. The following characters are interpreted as follows:
+.Bl -tag -width "<space>"
+.It <space>
+Output the rest of the line without change.
+.It 0
+Output a <newline> character before printing the rest of the line.
+.It 1
+Output a <formfeed> character before printing the rest of the line.
+.It +
+The trailing <newline> of the previous line is replaced by a <carriage-return>
+before printing the rest of the line.
+.El
+.Pp
+Lines beginning with characters other than the above are treated as if they
+begin with <space>.
+.Sh EXAMPLES
+To view a file containing the output of a
+.Tn FORTRAN program:
+.Dl asa file
+.Pp
+To format the output of a
+.Tn FORTRAN
+program and redirect it to a line-printer.
+.Dl a.out | asa | lpr
+.Sh DIAGNOSTICS
+The
+.Nm
+utility exit 0 on success, and >0 if an error occurs.
+.Sh SEE ALSO
+.Xr f77 1
+.Sh STANDARDS
+The
+.Nm
+utility conforms to
+.St -p1003.2-92 .
+.Sh AUTHORS
+J.T. Conklin, Winning Strategies, Inc.
diff --git a/developer_cmds/asa/asa.c b/developer_cmds/asa/asa.c
new file mode 100644
index 0000000..9516a45
--- /dev/null
+++ b/developer_cmds/asa/asa.c
@@ -0,0 +1,131 @@
+/* $NetBSD: asa.c,v 1.11 1997/09/20 14:55:00 lukem Exp $ */
+
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: asa.c,v 1.11 1997/09/20 14:55:00 lukem Exp $");
+#endif
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void asa __P((FILE *));
+int main __P((int, char *[]));
+
+int main(int argc, char **argv)
+{
+ FILE *fp;
+ int exit_val = 0;
+ /* skip progname */
+ argv++;
+
+ if (*argv && !strcmp(*argv, "--")) {
+ argv++;
+ argc--;
+ }
+
+ if (argc == 1) {
+ asa(stdin);
+ exit(exit_val);
+ }
+
+ do {
+ if (*argv) {
+ if (!(fp = fopen(*argv, "r"))) {
+ warn ("%s", *argv);
+ exit_val = 1;
+ continue;
+ } else {
+ asa(fp);
+ (void)fclose(fp);
+ }
+ }
+ } while (*argv++);
+
+ exit (exit_val);
+}
+
+static void
+asa(f)
+ FILE *f;
+{
+ char *buf;
+ size_t len;
+
+ if ((buf = fgetln (f, &len)) != NULL) {
+ if (buf[len - 1] == '\n')
+ buf[--len] = '\0';
+ /* special case the first line */
+ switch (buf[0]) {
+ case '0':
+ putchar ('\n');
+ break;
+ case '1':
+ putchar ('\f');
+ break;
+ }
+
+ if (len > 1 && buf[0] && buf[1]) {
+ printf("%.*s", (int)(len - 1), buf + 1);
+ }
+
+ while ((buf = fgetln(f, &len)) != NULL) {
+ if (buf[len - 1] == '\n')
+ buf[--len] = '\0';
+ switch (buf[0]) {
+ default:
+ case ' ':
+ putchar ('\n');
+ break;
+ case '0':
+ putchar ('\n');
+ putchar ('\n');
+ break;
+ case '1':
+ putchar ('\n');
+ putchar ('\f');
+ break;
+ case '+':
+ putchar ('\r');
+ break;
+ }
+
+ if (len > 1 && buf[0] && buf[1]) {
+ printf("%.*s", (int)(len - 1), buf + 1);
+ }
+ }
+
+ putchar ('\n');
+ }
+}
diff --git a/developer_cmds/ctags/C.c b/developer_cmds/ctags/C.c
new file mode 100644
index 0000000..c99d617
--- /dev/null
+++ b/developer_cmds/ctags/C.c
@@ -0,0 +1,555 @@
+/* $NetBSD: C.c,v 1.5 1998/07/24 07:30:08 ross Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)C.c 8.4 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: C.c,v 1.5 1998/07/24 07:30:08 ross Exp $");
+#endif
+#endif /* not lint */
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctags.h"
+
+static int func_entry __P((void));
+static void hash_entry __P((void));
+static void skip_string __P((int));
+static int str_entry __P((int));
+
+/*
+ * c_entries --
+ * read .c and .h files and call appropriate routines
+ */
+void
+c_entries()
+{
+ int c; /* current character */
+ int level; /* brace level */
+ int token; /* if reading a token */
+ int t_def; /* if reading a typedef */
+ int t_level; /* typedef's brace level */
+ char *sp; /* buffer pointer */
+ char tok[MAXTOKEN]; /* token buffer */
+
+ lineftell = ftell(inf);
+ sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1;
+ while (GETC(!=, EOF)) {
+ switch (c) {
+ /*
+ * Here's where it DOESN'T handle: {
+ * foo(a)
+ * {
+ * #ifdef notdef
+ * }
+ * #endif
+ * if (a)
+ * puts("hello, world");
+ * }
+ */
+ case '{':
+ ++level;
+ goto endtok;
+ case '}':
+ /*
+ * if level goes below zero, try and fix
+ * it, even though we've already messed up
+ */
+ if (--level < 0)
+ level = 0;
+ goto endtok;
+
+ case '\n':
+ SETLINE;
+ /*
+ * the above 3 cases are similar in that they
+ * are special characters that also end tokens.
+ */
+ endtok: if (sp > tok) {
+ *sp = EOS;
+ token = YES;
+ sp = tok;
+ }
+ else
+ token = NO;
+ continue;
+
+ /*
+ * We ignore quoted strings and character constants
+ * completely.
+ */
+ case '"':
+ case '\'':
+ (void)skip_string(c);
+ break;
+
+ /*
+ * comments can be fun; note the state is unchanged after
+ * return, in case we found:
+ * "foo() XX comment XX { int bar; }"
+ */
+ case '/':
+ if (GETC(==, '*')) {
+ skip_comment();
+ continue;
+ }
+ (void)ungetc(c, inf);
+ c = '/';
+ goto storec;
+
+ /* hash marks flag #define's. */
+ case '#':
+ if (sp == tok) {
+ hash_entry();
+ break;
+ }
+ goto storec;
+
+ /*
+ * if we have a current token, parenthesis on
+ * level zero indicates a function.
+ */
+ case '(':
+ if (!level && token) {
+ int curline;
+
+ if (sp != tok)
+ *sp = EOS;
+ /*
+ * grab the line immediately, we may
+ * already be wrong, for example,
+ * foo\n
+ * (arg1,
+ */
+ ct_getline();
+ curline = lineno;
+ if (func_entry()) {
+ ++level;
+ pfnote(tok, curline);
+ }
+ break;
+ }
+ goto storec;
+
+ /*
+ * semi-colons indicate the end of a typedef; if we find a
+ * typedef we search for the next semi-colon of the same
+ * level as the typedef. Ignoring "structs", they are
+ * tricky, since you can find:
+ *
+ * "typedef long time_t;"
+ * "typedef unsigned int u_int;"
+ * "typedef unsigned int u_int [10];"
+ *
+ * If looking at a typedef, we save a copy of the last token
+ * found. Then, when we find the ';' we take the current
+ * token if it starts with a valid token name, else we take
+ * the one we saved. There's probably some reasonable
+ * alternative to this...
+ */
+ case ';':
+ if (t_def && level == t_level) {
+ t_def = NO;
+ ct_getline();
+ if (sp != tok)
+ *sp = EOS;
+ pfnote(tok, lineno);
+ break;
+ }
+ goto storec;
+
+ /*
+ * store characters until one that can't be part of a token
+ * comes along; check the current token against certain
+ * reserved words.
+ */
+ default:
+ storec: if (!intoken(c)) {
+ if (sp == tok)
+ break;
+ *sp = EOS;
+ if (tflag) {
+ /* no typedefs inside typedefs */
+ if (!t_def &&
+ !memcmp(tok, "typedef",8)) {
+ t_def = YES;
+ t_level = level;
+ break;
+ }
+ /* catch "typedef struct" */
+ if ((!t_def || t_level < level)
+ && (!memcmp(tok, "struct", 7)
+ || !memcmp(tok, "union", 6)
+ || !memcmp(tok, "enum", 5))) {
+ /*
+ * get line immediately;
+ * may change before '{'
+ */
+ ct_getline();
+ if (str_entry(c))
+ ++level;
+ break;
+ /* } */
+ }
+ }
+ sp = tok;
+ }
+ else if (sp != tok || begtoken(c)) {
+ *sp++ = c;
+ token = YES;
+ }
+ continue;
+ }
+
+ sp = tok;
+ token = NO;
+ }
+}
+
+/*
+ * func_entry --
+ * handle a function reference
+ */
+static int
+func_entry()
+{
+ int c; /* current character */
+ int level = 0; /* for matching '()' */
+ static char attribute[] = "__attribute__";
+ char maybe_attribute[sizeof attribute + 1],
+ *anext;
+
+ /*
+ * Find the end of the assumed function declaration.
+ * Note that ANSI C functions can have type definitions so keep
+ * track of the parentheses nesting level.
+ */
+ while (GETC(!=, EOF)) {
+ switch (c) {
+ case '\'':
+ case '"':
+ /* skip strings and character constants */
+ skip_string(c);
+ break;
+ case '/':
+ /* skip comments */
+ if (GETC(==, '*'))
+ skip_comment();
+ break;
+ case '(':
+ level++;
+ break;
+ case ')':
+ if (level == 0)
+ goto fnd;
+ level--;
+ break;
+ case '\n':
+ SETLINE;
+ }
+ }
+ return (NO);
+fnd:
+ /*
+ * we assume that the character after a function's right paren
+ * is a token character if it's a function and a non-token
+ * character if it's a declaration. Comments don't count...
+ */
+ for (anext = maybe_attribute;;) {
+ while (GETC(!=, EOF) && iswhite(c))
+ if (c == '\n')
+ SETLINE;
+ if (c == EOF)
+ return NO;
+ /*
+ * Recognize the gnu __attribute__ extension, which would
+ * otherwise make the heuristic test DTWT
+ */
+ if (anext == maybe_attribute) {
+ if (intoken(c)) {
+ *anext++ = c;
+ continue;
+ }
+ } else {
+ if (intoken(c)) {
+ if (anext - maybe_attribute
+ < (int)(sizeof attribute - 1))
+ *anext++ = c;
+ else break;
+ continue;
+ } else {
+ *anext++ = '\0';
+ if (strcmp(maybe_attribute, attribute) == 0) {
+ (void)ungetc(c, inf);
+ return NO;
+ }
+ break;
+ }
+ }
+ if (intoken(c) || c == '{')
+ break;
+ if (c == '/' && GETC(==, '*'))
+ skip_comment();
+ else { /* don't ever "read" '/' */
+ (void)ungetc(c, inf);
+ return (NO);
+ }
+ }
+ if (c != '{')
+ (void)skip_key('{');
+ return (YES);
+}
+
+/*
+ * hash_entry --
+ * handle a line starting with a '#'
+ */
+static void
+hash_entry()
+{
+ int c; /* character read */
+ int curline; /* line started on */
+ char *sp; /* buffer pointer */
+ char tok[MAXTOKEN]; /* storage buffer */
+
+ curline = lineno;
+ for (sp = tok;;) { /* get next token */
+ if (GETC(==, EOF))
+ return;
+ if (iswhite(c))
+ break;
+ *sp++ = c;
+ }
+ *sp = EOS;
+ if (memcmp(tok, "define", 6)) /* only interested in #define's */
+ goto skip;
+ for (;;) { /* this doesn't handle "#define \n" */
+ if (GETC(==, EOF))
+ return;
+ if (!iswhite(c))
+ break;
+ }
+ for (sp = tok;;) { /* get next token */
+ *sp++ = c;
+ if (GETC(==, EOF))
+ return;
+ /*
+ * this is where it DOESN'T handle
+ * "#define \n"
+ */
+ if (!intoken(c))
+ break;
+ }
+ *sp = EOS;
+ if (dflag || c == '(') { /* only want macros */
+ ct_getline();
+ pfnote(tok, curline);
+ }
+skip: if (c == '\n') { /* get rid of rest of define */
+ SETLINE
+ if (*(sp - 1) != '\\')
+ return;
+ }
+ (void)skip_key('\n');
+}
+
+/*
+ * str_entry --
+ * handle a struct, union or enum entry
+ */
+static int
+str_entry(c)
+ int c; /* current character */
+{
+ int curline; /* line started on */
+ char *sp; /* buffer pointer */
+ char tok[LINE_MAX]; /* storage buffer */
+
+ curline = lineno;
+ while (iswhite(c))
+ if (GETC(==, EOF))
+ return (NO);
+ if (c == '{') /* it was "struct {" */
+ return (YES);
+ for (sp = tok;;) { /* get next token */
+ *sp++ = c;
+ if (GETC(==, EOF))
+ return (NO);
+ if (!intoken(c))
+ break;
+ }
+
+ switch (c) {
+ case '{': /* it was "struct foo{" */
+ --sp;
+ break;
+ case '\n': /* it was "struct foo\n" */
+ SETLINE;
+ if(GETC(!=, '/'))
+ {
+ while (GETC(!=, EOF))
+ if (!iswhite(c))
+ break;
+ if (c != '{') {
+ (void)ungetc(c, inf);
+ return (NO);
+ }
+ break;
+ }
+ case '/':
+ /* skip comments */
+ if (GETC(==, '*')) {
+ skip_comment();
+ }
+ /*FALLTHROUGH*/
+ default: /* probably "struct foo " */
+ while (GETC(!=, EOF))
+ if (!iswhite(c))
+ break;
+ if (c != '{') {
+ (void)ungetc(c, inf);
+ return (NO);
+ }
+ }
+ *sp = EOS;
+ pfnote(tok, curline);
+ return (YES);
+}
+
+/*
+ * skip_comment --
+ * skip over comment
+ */
+void
+skip_comment()
+{
+ int c; /* character read */
+ int star; /* '*' flag */
+
+ for (star = 0; GETC(!=, EOF);)
+ switch(c) {
+ /* comments don't nest, nor can they be escaped. */
+ case '*':
+ star = YES;
+ break;
+ case '/':
+ if (star)
+ return;
+ break;
+ case '\n':
+ SETLINE;
+ /*FALLTHROUGH*/
+ default:
+ star = NO;
+ break;
+ }
+}
+
+/*
+ * skip_string --
+ * skip to the end of a string or character constant.
+ */
+void
+skip_string(key)
+ int key;
+{
+ int c,
+ skip;
+
+ for (skip = NO; GETC(!=, EOF); )
+ switch (c) {
+ case '\\': /* a backslash escapes anything */
+ skip = !skip; /* we toggle in case it's "\\" */
+ break;
+ case '\n':
+ SETLINE;
+ /*FALLTHROUGH*/
+ default:
+ if (c == key && !skip)
+ return;
+ skip = NO;
+ }
+}
+
+/*
+ * skip_key --
+ * skip to next char "key"
+ */
+int
+skip_key(key)
+ int key;
+{
+ int c,
+ skip,
+ retval;
+
+ for (skip = retval = NO; GETC(!=, EOF);)
+ switch(c) {
+ case '\\': /* a backslash escapes anything */
+ skip = !skip; /* we toggle in case it's "\\" */
+ break;
+ case ';': /* special case for yacc; if one */
+ case '|': /* of these chars occurs, we may */
+ retval = YES; /* have moved out of the rule */
+ break; /* not used by C */
+ case '\'':
+ case '"':
+ /* skip strings and character constants */
+ skip_string(c);
+ break;
+ case '/':
+ /* skip comments */
+ if (GETC(==, '*')) {
+ skip_comment();
+ break;
+ }
+ (void)ungetc(c, inf);
+ c = '/';
+ goto norm;
+ case '\n':
+ SETLINE;
+ /*FALLTHROUGH*/
+ default:
+ norm:
+ if (c == key && !skip)
+ return (retval);
+ skip = NO;
+ }
+ return (retval);
+}
diff --git a/developer_cmds/ctags/ctags.1 b/developer_cmds/ctags/ctags.1
new file mode 100644
index 0000000..353c990
--- /dev/null
+++ b/developer_cmds/ctags/ctags.1
@@ -0,0 +1,221 @@
+.\" $NetBSD: ctags.1,v 1.5 1997/10/18 13:18:24 lukem Exp $
+.\"
+.\" Copyright (c) 1987, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ctags.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt CTAGS 1
+.Os BSD 4
+.Sh NAME
+.Nm ctags
+.Nd create a tags file
+.Sh SYNOPSIS
+.Nm
+.Op Fl BFadtuwvx
+.Op Fl f Ar tags_file
+.Ar name ...
+.Sh DESCRIPTION
+.Nm
+makes a tags file for
+.Xr ex 1
+from the specified C,
+Pascal, Fortran,
+.Tn YACC ,
+lex, and lisp sources.
+A tags file gives the locations of specified objects in a group of files.
+Each line of the tags file contains the object name, the file in which it
+is defined, and a search pattern for the object definition, separated by
+white-space.
+.Pp
+Using the
+.Ar tags
+file,
+.Xr ex 1
+can quickly locate these object definitions.
+Depending upon the options provided to
+.Nm ,
+objects will consist of subroutines, typedefs, defines, structs,
+enums, and unions.
+.Bl -tag -width Ds
+.It Fl a
+append to
+.Ar tags
+file.
+.It Fl B
+use backward searching patterns
+.Pq Li ?...? .
+.It Fl d
+create tags for
+.Li #defines
+that don't take arguments;
+.Li #defines
+that take arguments are tagged automatically.
+.It Fl F
+use forward searching patterns
+.Pq Li /.../
+(the default).
+.It Fl f
+Places the tag descriptions in a file called
+.Ar tags_file .
+The default behavior is to place them in a file called
+.Ar tags .
+.It Fl t
+create tags for typedefs, structs, unions, and enums.
+.It Fl u
+update the specified files in the
+.Ar tags
+file, that is, all
+references to them are deleted, and the new values are appended to the
+file. (Beware: this option is implemented in a way which is rather
+slow; it is usually faster to simply rebuild the
+.Ar tags
+file.)
+.It Fl v
+An index of the form expected by
+.Xr vgrind 1
+is produced on the standard output. This listing
+contains the object name, file name, and page number (assuming 64-line pages).
+Because the output will be sorted into lexicographic order,
+it may be desirable to run the output through
+.Xr sort 1 .
+Sample use:
+.Bd -literal -offset indent
+ctags \-v files \&| sort \-f > index
+vgrind \-x index
+.Ed
+.It Fl w
+suppress warning diagnostics.
+.It Fl x
+.Nm
+produces a list of object
+names, the line number and file name on which each is defined, as well
+as the text of that line and prints this on the standard output. This
+is a simple function index which can be printed out for reading off-line.
+.El
+.Pp
+Files whose names end in
+.Sq \&.c
+or
+.Sq \&.h
+are assumed to be C
+source files and are searched for C style routine and macro definitions.
+Files whose names end in
+.Sq \&.y
+are assumed to be
+.Tn YACC
+source files.
+Files whose names end in
+.Sq \&.l
+are assumed to be lisp files if their
+first non-blank character is `;', `(', or `[',
+otherwise, they are treated
+as lex files. Other files are first examined to see if they
+contain any Pascal or Fortran routine definitions; if not, they are
+searched for C-style definitions.
+.Pp
+The tag
+.Li main
+is treated specially in C programs. The tag formed
+is created by prepending
+.Ar M
+to the name of the file, with the
+trailing
+.Sq \&.c
+and any leading pathname components removed. This
+makes use of
+.Nm
+practical in directories with more than one
+program.
+.Pp
+Yacc and lex files each have a special tag.
+.Ar Yyparse
+is the start
+of the second section of the yacc file, and
+.Ar yylex
+is the start of
+the second section of the lex file.
+.Sh FILES
+.Bl -tag -width tagsxxx -compact
+.It Pa tags
+default output tags file
+.El
+.Sh DIAGNOSTICS
+.Nm
+exits with a value of 1 if an error occurred, 0 otherwise.
+Duplicate objects are not considered to be errors.
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr ex 1 ,
+.Xr lex 1 ,
+.Xr sort 1 ,
+.\" .Xr vgrind 1 ,
+.Xr vi 1 ,
+.Xr yacc 1
+.Sh BUGS
+Recognition of
+.Em functions ,
+.Em subroutines ,
+and
+.Em procedures
+for
+.Tn FORTRAN
+and Pascal is done in a very simple-minded way. No attempt
+is made to deal with block structure; if you have Pascal procedures
+with the same name in different blocks, you lose.
+.Nm
+doesn't
+understand about Pascal types.
+.Pp
+The method of deciding whether to look for C, Pascal, or
+.Tn FORTRAN
+functions is a hack.
+.Pp
+.Nm
+relies on the input being well formed, so any syntactical
+errors will completely confuse it. It also finds some legal syntax
+to be confusing; for example, because it doesn't understand
+.Li #ifdef Ns 's
+(incidentally, that's a feature, not a bug), any code with unbalanced
+braces inside
+.Li #ifdef Ns 's
+will cause it to become somewhat disoriented.
+In a similar fashion, multiple line changes within a definition will
+cause it to enter the last line of the object, rather than the first, as
+the searching pattern. The last line of multiple line
+.Li typedef Ns 's
+will similarly be noted.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 3.0 .
diff --git a/developer_cmds/ctags/ctags.c b/developer_cmds/ctags/ctags.c
new file mode 100644
index 0000000..490f91d
--- /dev/null
+++ b/developer_cmds/ctags/ctags.c
@@ -0,0 +1,282 @@
+/* $NetBSD: ctags.c,v 1.6 1998/08/25 20:59:36 ross Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994, 1995\n\
+ The Regents of the University of California. All rights reserved.\n");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ctags.c 8.4 (Berkeley) 2/7/95";
+#endif
+__RCSID("$NetBSD: ctags.c,v 1.6 1998/08/25 20:59:36 ross Exp $");
+#endif /* not lint */
+
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "ctags.h"
+
+/*
+ * ctags: create a tags file
+ */
+
+NODE *head; /* head of the sorted binary tree */
+
+ /* boolean "func" (see init()) */
+bool _wht[256], _etk[256], _itk[256], _btk[256], _gd[256];
+
+FILE *inf; /* ioptr for current input file */
+FILE *outf; /* ioptr for tags file */
+
+long lineftell; /* ftell after getc( inf ) == '\n' */
+
+int lineno; /* line number of current line */
+int dflag; /* -d: non-macro defines */
+int tflag=1; /* -t: create tags for typedefs */
+int vflag; /* -v: vgrind style index output */
+int wflag; /* -w: suppress warnings */
+int xflag; /* -x: cxref style output */
+
+char *curfile; /* current input file name */
+char searchar = '/'; /* use /.../ searches by default */
+char lbuf[LINE_MAX];
+
+void init __P((void));
+int main __P((int, char **));
+void find_entries __P((char *));
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ static char *outfile = "tags"; /* output file */
+ int aflag; /* -a: append to tags */
+ int uflag; /* -u: update tags */
+ int exit_val; /* exit value */
+ int step; /* step through args */
+ int ch; /* getopts char */
+ char cmd[100]; /* too ugly to explain */
+
+ aflag = uflag = NO;
+ while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != -1)
+ switch(ch) {
+ case 'B':
+ searchar = '?';
+ break;
+ case 'F':
+ searchar = '/';
+ break;
+ case 'a':
+ aflag++;
+ break;
+ case 'd':
+ dflag++;
+ break;
+ case 'f':
+ outfile = optarg;
+ break;
+ case 't':
+ tflag++;
+ break;
+ case 'T':
+ tflag--;
+ break;
+ case 'u':
+ uflag++;
+ break;
+ case 'w':
+ wflag++;
+ break;
+ case 'v':
+ vflag++;
+ case 'x':
+ xflag++;
+ break;
+ case '?':
+ default:
+ goto usage;
+ }
+ argv += optind;
+ argc -= optind;
+ if (!argc) {
+usage: (void)fprintf(stderr,
+ "usage: ctags [-BFadtuwvx] [-f tagsfile] file ...\n");
+ exit(1);
+ }
+
+ init();
+
+ for (exit_val = step = 0; step < argc; ++step)
+ if (!(inf = fopen(argv[step], "r"))) {
+ warn("%s", argv[step]);
+ exit_val = 1;
+ }
+ else {
+ curfile = argv[step];
+ find_entries(argv[step]);
+ (void)fclose(inf);
+ }
+
+ if (head) {
+ if (xflag)
+ put_entries(head);
+ else {
+ if (uflag) {
+ for (step = 0; step < argc; step++) {
+ (void)sprintf(cmd,
+ "mv %s OTAGS; fgrep -v '\t%s\t' OTAGS >%s; rm OTAGS",
+ outfile, argv[step],
+ outfile);
+ system(cmd);
+ }
+ ++aflag;
+ }
+ if (!(outf = fopen(outfile, aflag ? "a" : "w")))
+ err(exit_val ? exit_val : 1, "%s", outfile);
+ put_entries(head);
+ (void)fclose(outf);
+ if (uflag) {
+ (void)sprintf(cmd, "sort -o %s %s",
+ outfile, outfile);
+ system(cmd);
+ }
+ }
+ }
+ exit(exit_val);
+}
+
+/*
+ * init --
+ * this routine sets up the boolean psuedo-functions which work by
+ * setting boolean flags dependent upon the corresponding character.
+ * Every char which is NOT in that string is false with respect to
+ * the pseudo-function. Therefore, all of the array "_wht" is NO
+ * by default and then the elements subscripted by the chars in
+ * CWHITE are set to YES. Thus, "_wht" of a char is YES if it is in
+ * the string CWHITE, else NO.
+ */
+void
+init()
+{
+ int i;
+ unsigned char *sp;
+
+ for (i = 0; i < 256; i++) {
+ _wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
+ _gd[i] = YES;
+ }
+#define CWHITE (unsigned char *)" \f\t\n"
+ for (sp = CWHITE; *sp; sp++) /* white space chars */
+ _wht[*sp] = YES;
+#define CTOKEN (unsigned char *)" \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
+ for (sp = CTOKEN; *sp; sp++) /* token ending chars */
+ _etk[*sp] = YES;
+#define CINTOK (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
+ for (sp = CINTOK; *sp; sp++) /* valid in-token chars */
+ _itk[*sp] = YES;
+#define CBEGIN (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+ for (sp = CBEGIN; *sp; sp++) /* token starting chars */
+ _btk[*sp] = YES;
+#define CNOTGD (unsigned char *)",;"
+ for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */
+ _gd[*sp] = NO;
+}
+
+/*
+ * find_entries --
+ * this routine opens the specified file and calls the function
+ * which searches the file.
+ */
+void
+find_entries(file)
+ char *file;
+{
+ char *cp;
+
+ lineno = 0; /* should be 1 ?? KB */
+ if ((cp = strrchr(file, '.')) != NULL) {
+ if (cp[1] == 'l' && !cp[2]) {
+ int c;
+
+ for (;;) {
+ if (GETC(==, EOF))
+ return;
+ if (!iswhite(c)) {
+ rewind(inf);
+ break;
+ }
+ }
+#define LISPCHR ";(["
+/* lisp */ if (strchr(LISPCHR, c)) {
+ l_entries();
+ return;
+ }
+/* lex */ else {
+ /*
+ * we search all 3 parts of a lex file
+ * for C references. This may be wrong.
+ */
+ toss_yysec();
+ (void)strcpy(lbuf, "%%$");
+ pfnote("yylex", lineno);
+ rewind(inf);
+ }
+ }
+/* yacc */ else if (cp[1] == 'y' && !cp[2]) {
+ /*
+ * we search only the 3rd part of a yacc file
+ * for C references. This may be wrong.
+ */
+ toss_yysec();
+ (void)strcpy(lbuf, "%%$");
+ pfnote("yyparse", lineno);
+ y_entries();
+ }
+/* fortran */ else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) {
+ if (PF_funcs())
+ return;
+ rewind(inf);
+ }
+ }
+/* C */ c_entries();
+}
diff --git a/developer_cmds/ctags/ctags.h b/developer_cmds/ctags/ctags.h
new file mode 100644
index 0000000..99ba934
--- /dev/null
+++ b/developer_cmds/ctags/ctags.h
@@ -0,0 +1,92 @@
+/* $NetBSD: ctags.h,v 1.3 1995/03/26 20:14:07 glass Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ctags.h 8.3 (Berkeley) 4/2/94
+ */
+
+#define bool char
+
+#define YES 1
+#define NO 0
+#define EOS '\0'
+
+#define ENDLINE 50 /* max length of pattern */
+#define MAXTOKEN 250 /* max size of single token */
+
+#define SETLINE {++lineno;lineftell = ftell(inf);}
+#define GETC(op,exp) ((c = getc(inf)) op (int)exp)
+
+#define iswhite(arg) (_wht[(unsigned)arg]) /* T if char is white */
+#define begtoken(arg) (_btk[(unsigned)arg]) /* T if char can start token */
+#define intoken(arg) (_itk[(unsigned)arg]) /* T if char can be in token */
+#define endtoken(arg) (_etk[(unsigned)arg]) /* T if char ends tokens */
+#define isgood(arg) (_gd[(unsigned)arg]) /* T if char can be after ')' */
+
+typedef struct nd_st { /* sorting structure */
+ struct nd_st *left,
+ *right; /* left and right sons */
+ char *entry, /* function or type name */
+ *file, /* file name */
+ *pat; /* search pattern */
+ int lno; /* for -x option */
+ bool been_warned; /* set if noticed dup */
+} NODE;
+
+extern char *curfile; /* current input file name */
+extern NODE *head; /* head of the sorted binary tree */
+extern FILE *inf; /* ioptr for current input file */
+extern FILE *outf; /* ioptr for current output file */
+extern long lineftell; /* ftell after getc( inf ) == '\n' */
+extern int lineno; /* line number of current line */
+extern int dflag; /* -d: non-macro defines */
+extern int tflag; /* -t: create tags for typedefs */
+extern int vflag; /* -v: vgrind style index output */
+extern int wflag; /* -w: suppress warnings */
+extern int xflag; /* -x: cxref style output */
+extern bool _wht[], _etk[], _itk[], _btk[], _gd[];
+extern char lbuf[LINE_MAX];
+extern char *lbp;
+extern char searchar; /* ex search character */
+
+extern int cicmp __P((char *));
+extern void ct_getline __P((void));
+extern void pfnote __P((char *, int));
+extern int skip_key __P((int));
+extern void put_entries __P((NODE *));
+extern void toss_yysec __P((void));
+extern void l_entries __P((void));
+extern void y_entries __P((void));
+extern int PF_funcs __P((void));
+extern void c_entries __P((void));
+extern void skip_comment __P((void));
diff --git a/developer_cmds/ctags/fortran.c b/developer_cmds/ctags/fortran.c
new file mode 100644
index 0000000..a4b4178
--- /dev/null
+++ b/developer_cmds/ctags/fortran.c
@@ -0,0 +1,175 @@
+/* $NetBSD: fortran.c,v 1.4 1997/10/18 13:18:37 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)fortran.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: fortran.c,v 1.4 1997/10/18 13:18:37 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctags.h"
+
+static void takeprec __P((void));
+
+char *lbp; /* line buffer pointer */
+
+int
+PF_funcs()
+{
+ bool pfcnt; /* pascal/fortran functions found */
+ char *cp;
+ char tok[MAXTOKEN];
+
+ for (pfcnt = NO;;) {
+ lineftell = ftell(inf);
+ if (!fgets(lbuf, sizeof(lbuf), inf))
+ return (pfcnt);
+ ++lineno;
+ lbp = lbuf;
+ if (*lbp == '%') /* Ratfor escape to fortran */
+ ++lbp;
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ if (!*lbp)
+ continue;
+ switch (*lbp | ' ') { /* convert to lower-case */
+ case 'c':
+ if (cicmp("complex") || cicmp("character"))
+ takeprec();
+ break;
+ case 'd':
+ if (cicmp("double")) {
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ if (!*lbp)
+ continue;
+ if (cicmp("precision"))
+ break;
+ continue;
+ }
+ break;
+ case 'i':
+ if (cicmp("integer"))
+ takeprec();
+ break;
+ case 'l':
+ if (cicmp("logical"))
+ takeprec();
+ break;
+ case 'r':
+ if (cicmp("real"))
+ takeprec();
+ break;
+ }
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ if (!*lbp)
+ continue;
+ switch (*lbp | ' ') {
+ case 'f':
+ if (cicmp("function"))
+ break;
+ continue;
+ case 'p':
+ if (cicmp("program") || cicmp("procedure"))
+ break;
+ continue;
+ case 's':
+ if (cicmp("subroutine"))
+ break;
+ default:
+ continue;
+ }
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ if (!*lbp)
+ continue;
+ for (cp = lbp + 1; *cp && intoken(*cp); ++cp)
+ continue;
+ if ((cp = lbp + 1) != NULL)
+ continue;
+ *cp = EOS;
+ (void)strcpy(tok, lbp);
+ ct_getline(); /* process line for ex(1) */
+ pfnote(tok, lineno);
+ pfcnt = YES;
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * cicmp --
+ * do case-independent strcmp
+ */
+int
+cicmp(cp)
+ char *cp;
+{
+ int len;
+ char *bp;
+
+ for (len = 0, bp = lbp; *cp && (*cp &~ ' ') == (*bp++ &~ ' ');
+ ++cp, ++len)
+ continue;
+ if (!*cp) {
+ lbp += len;
+ return (YES);
+ }
+ return (NO);
+}
+
+static void
+takeprec()
+{
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ if (*lbp == '*') {
+ for (++lbp; isspace(*lbp); ++lbp)
+ continue;
+ if (!isdigit(*lbp))
+ --lbp; /* force failure */
+ else
+ while (isdigit(*++lbp))
+ continue;
+ }
+}
diff --git a/developer_cmds/ctags/lisp.c b/developer_cmds/ctags/lisp.c
new file mode 100644
index 0000000..e925c1b
--- /dev/null
+++ b/developer_cmds/ctags/lisp.c
@@ -0,0 +1,112 @@
+/* $NetBSD: lisp.c,v 1.4 1997/10/18 13:18:45 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lisp.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: lisp.c,v 1.4 1997/10/18 13:18:45 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctags.h"
+
+/*
+ * lisp tag functions
+ * just look for (def or (DEF
+ */
+void
+l_entries()
+{
+ int special;
+ char *cp;
+ char savedc;
+ char tok[MAXTOKEN];
+
+ for (;;) {
+ lineftell = ftell(inf);
+ if (!fgets(lbuf, sizeof(lbuf), inf))
+ return;
+ ++lineno;
+ lbp = lbuf;
+ if (!cicmp("(def"))
+ continue;
+ special = NO;
+ switch(*lbp | ' ') {
+ case 'm':
+ if (cicmp("method"))
+ special = YES;
+ break;
+ case 'w':
+ if (cicmp("wrapper") || cicmp("whopper"))
+ special = YES;
+ }
+ for (; !isspace(*lbp); ++lbp)
+ continue;
+ for (; isspace(*lbp); ++lbp)
+ continue;
+ for (cp = lbp; *cp && *cp != '\n'; ++cp)
+ continue;
+ *cp = EOS;
+ if (special) {
+ if (!(cp = strchr(lbp, ')')))
+ continue;
+ for (; cp >= lbp && *cp != ':'; --cp)
+ continue;
+ if (cp < lbp)
+ continue;
+ lbp = cp;
+ for (; *cp && *cp != ')' && *cp != ' '; ++cp)
+ continue;
+ }
+ else
+ for (cp = lbp + 1;
+ *cp && *cp != '(' && *cp != ' '; ++cp)
+ continue;
+ savedc = *cp;
+ *cp = EOS;
+ (void)strcpy(tok, lbp);
+ *cp = savedc;
+ ct_getline();
+ pfnote(tok, lineno);
+ }
+ /*NOTREACHED*/
+}
diff --git a/developer_cmds/ctags/print.c b/developer_cmds/ctags/print.c
new file mode 100644
index 0000000..a6c4aaf
--- /dev/null
+++ b/developer_cmds/ctags/print.c
@@ -0,0 +1,122 @@
+/* $NetBSD: print.c,v 1.5 1997/10/18 13:18:52 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)print.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: print.c,v 1.5 1997/10/18 13:18:52 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ctags.h"
+
+/*
+ * ct_getline --
+ * get the line the token of interest occurred on,
+ * prepare it for printing.
+ */
+void
+ct_getline()
+{
+ long saveftell;
+ int c;
+ int cnt;
+ char *cp;
+
+ saveftell = ftell(inf);
+ (void)fseek(inf, lineftell, SEEK_SET);
+ if (xflag)
+ for (cp = lbuf; GETC(!=, '\n'); *cp++ = c)
+ continue;
+ /*
+ * do all processing here, so we don't step through the
+ * line more than once; means you don't call this routine
+ * unless you're sure you've got a keeper.
+ */
+ else for (cnt = 0, cp = lbuf; GETC(!=, EOF) && cnt < ENDLINE; ++cnt) {
+ if (c == '\\') { /* backslashes */
+ if (cnt > ENDLINE - 2)
+ break;
+ *cp++ = '\\'; *cp++ = '\\';
+ ++cnt;
+ }
+ else if (c == (int)searchar) { /* search character */
+ if (cnt > ENDLINE - 2)
+ break;
+ *cp++ = '\\'; *cp++ = c;
+ ++cnt;
+ }
+ else if (c == '\n') { /* end of keep */
+ *cp++ = '$'; /* can find whole line */
+ break;
+ }
+ else
+ *cp++ = c;
+ }
+ *cp = EOS;
+ (void)fseek(inf, saveftell, SEEK_SET);
+}
+
+/*
+ * put_entries --
+ * write out the tags
+ */
+void
+put_entries(node)
+ NODE *node;
+{
+
+ if (node->left)
+ put_entries(node->left);
+ if (vflag)
+ printf("%s %s %d\n",
+ node->entry, node->file, (node->lno + 63) / 64);
+ else if (xflag)
+ printf("%-16s%4d %-16s %s\n",
+ node->entry, node->lno, node->file, node->pat);
+ else
+ fprintf(outf, "%s\t%s\t%c^%s%c\n",
+ node->entry, node->file, searchar, node->pat, searchar);
+ if (node->right)
+ put_entries(node->right);
+}
diff --git a/developer_cmds/ctags/test/ctags.test b/developer_cmds/ctags/test/ctags.test
new file mode 100644
index 0000000..658a073
--- /dev/null
+++ b/developer_cmds/ctags/test/ctags.test
@@ -0,0 +1,69 @@
+/* $NetBSD: ctags.test,v 1.2 1995/03/26 20:14:14 glass Exp $ */
+
+int bar = (1 + 5);
+
+FOO("here is a #define test: ) {");
+char sysent[20];
+int nsysent = sizeof (sysent) / sizeof (sysent[0]);
+/*
+ * now is the time for a comment.
+ * four lines in length...
+ */struct struct_xtra{int list;};r4(x,y){};typedef struct{int bar;}struct_xxe;
+#define FOO BAR
+struct struct_three {
+ int list;
+};
+#define SINGLE
+int BAD();
+enum color {red, green, gold, brown};
+char qq[] = " quote(one,two) {int bar;} ";
+typedef struct {
+ int bar;
+ struct struct_two {
+ int foo;
+ union union_3 {
+ struct struct_three entry;
+ char size[25];
+ };
+ struct last {
+ struct struct_three xentry;
+ char list[34];
+ };
+ };
+} struct_one;
+#define TWOLINE ((MAXLIST + FUTURE + 15) \
+ / (time_to_live ? 3 : 4))
+#if (defined(BAR))
+int bar;
+#endif
+#define MULTIPLE {\
+ multiple(one,two); \
+ lineno++; \
+ callroute(one,two); \
+}
+#if defined(BAR)
+int bar;
+#endif
+union union_one {
+ struct struct_three s3;
+ char foo[25];
+};
+#define XYZ(A,B) (A + B / 2) * (3 - 26 + l_lineno)
+routine1(one,two) /* comments here are fun... */
+ struct {
+ int entry;
+ char bar[34];
+ } *one;
+ char two[10];
+{
+typedef unsigned char u_char;
+ register struct buf *bp;
+ five(one,two);
+}
+ routine2 (one,two) { puts("hello\n"); }
+ routine3
+(one,
+two) { puts("world\n"); }
+routine4(int one, char (*two)(void)) /* test ANSI arguments */
+{
+}
diff --git a/developer_cmds/ctags/tree.c b/developer_cmds/ctags/tree.c
new file mode 100644
index 0000000..c31975c
--- /dev/null
+++ b/developer_cmds/ctags/tree.c
@@ -0,0 +1,142 @@
+/* $NetBSD: tree.c,v 1.5 1997/10/18 13:18:58 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)tree.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: tree.c,v 1.5 1997/10/18 13:18:58 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ctags.h"
+
+static void add_node __P((NODE *, NODE *));
+static void free_tree __P((NODE *));
+
+/*
+ * pfnote --
+ * enter a new node in the tree
+ */
+void
+pfnote(name, ln)
+ char *name;
+ int ln;
+{
+ NODE *np;
+ char *fp;
+ char nbuf[MAXTOKEN];
+
+ /*NOSTRICT*/
+ if (!(np = (NODE *)malloc(sizeof(NODE)))) {
+ warnx("too many entries to sort");
+ put_entries(head);
+ free_tree(head);
+ /*NOSTRICT*/
+ if (!(head = np = (NODE *)malloc(sizeof(NODE))))
+ err(1, "out of space");
+ }
+ if (!xflag && !strcmp(name, "main")) {
+ if (!(fp = strrchr(curfile, '/')))
+ fp = curfile;
+ else
+ ++fp;
+ (void)sprintf(nbuf, "M%s", fp);
+ fp = strrchr(nbuf, '.');
+ if (fp && !fp[2])
+ *fp = EOS;
+ name = nbuf;
+ }
+ if (!(np->entry = strdup(name)))
+ err(1, "strdup");
+ np->file = curfile;
+ np->lno = ln;
+ np->left = np->right = 0;
+ if (!(np->pat = strdup(lbuf)))
+ err(1, "strdup");
+ if (!head)
+ head = np;
+ else
+ add_node(np, head);
+}
+
+static void
+add_node(node, cur_node)
+ NODE *node,
+ *cur_node;
+{
+ int dif;
+
+ dif = strcmp(node->entry, cur_node->entry);
+ if (!dif) {
+ if (node->file == cur_node->file) {
+ if (!wflag)
+ fprintf(stderr, "Duplicate entry in file %s, line %d: %s\nSecond entry ignored\n", node->file, lineno, node->entry);
+ return;
+ }
+ if (!cur_node->been_warned)
+ if (!wflag)
+ fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry);
+ cur_node->been_warned = YES;
+ }
+ else if (dif < 0)
+ if (cur_node->left)
+ add_node(node, cur_node->left);
+ else
+ cur_node->left = node;
+ else if (cur_node->right)
+ add_node(node, cur_node->right);
+ else
+ cur_node->right = node;
+}
+
+static void
+free_tree(node)
+ NODE *node;
+{
+ while (node) {
+ if (node->right)
+ free_tree(node->right);
+ free(node);
+ node = node->left;
+ }
+}
diff --git a/developer_cmds/ctags/yacc.c b/developer_cmds/ctags/yacc.c
new file mode 100644
index 0000000..17edfa6
--- /dev/null
+++ b/developer_cmds/ctags/yacc.c
@@ -0,0 +1,158 @@
+/* $NetBSD: yacc.c,v 1.4 1997/10/18 13:19:04 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)yacc.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: yacc.c,v 1.4 1997/10/18 13:19:04 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctags.h"
+
+/*
+ * y_entries:
+ * find the yacc tags and put them in.
+ */
+void
+y_entries()
+{
+ int c;
+ char *sp;
+ bool in_rule;
+ char tok[MAXTOKEN];
+
+ in_rule = NO;
+
+ while (GETC(!=, EOF))
+ switch (c) {
+ case '\n':
+ SETLINE;
+ /* FALLTHROUGH */
+ case ' ':
+ case '\f':
+ case '\r':
+ case '\t':
+ break;
+ case '{':
+ if (skip_key('}'))
+ in_rule = NO;
+ break;
+ case '\'':
+ case '"':
+ if (skip_key(c))
+ in_rule = NO;
+ break;
+ case '%':
+ if (GETC(==, '%'))
+ return;
+ (void)ungetc(c, inf);
+ break;
+ case '/':
+ if (GETC(==, '*'))
+ skip_comment();
+ else
+ (void)ungetc(c, inf);
+ break;
+ case '|':
+ case ';':
+ in_rule = NO;
+ break;
+ default:
+ if (in_rule || (!isalpha(c) && c != '.' && c != '_'))
+ break;
+ sp = tok;
+ *sp++ = c;
+ while (GETC(!=, EOF) && (intoken(c) || c == '.'))
+ *sp++ = c;
+ *sp = EOS;
+ ct_getline(); /* may change before ':' */
+ while (iswhite(c)) {
+ if (c == '\n')
+ SETLINE;
+ if (GETC(==, EOF))
+ return;
+ }
+ if (c == ':') {
+ pfnote(tok, lineno);
+ in_rule = YES;
+ }
+ else
+ (void)ungetc(c, inf);
+ }
+}
+
+/*
+ * toss_yysec --
+ * throw away lines up to the next "\n%%\n"
+ */
+void
+toss_yysec()
+{
+ int c; /* read character */
+ int state;
+
+ /*
+ * state == 0 : waiting
+ * state == 1 : received a newline
+ * state == 2 : received first %
+ * state == 3 : recieved second %
+ */
+ lineftell = ftell(inf);
+ for (state = 0; GETC(!=, EOF);)
+ switch (c) {
+ case '\n':
+ ++lineno;
+ lineftell = ftell(inf);
+ if (state == 3) /* done! */
+ return;
+ state = 1; /* start over */
+ break;
+ case '%':
+ if (state) /* if 1 or 2 */
+ ++state; /* goto 3 */
+ break;
+ default:
+ state = 0; /* reset */
+ break;
+ }
+}
diff --git a/developer_cmds/developer_cmds.xcodeproj/project.pbxproj b/developer_cmds/developer_cmds.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..e43393a
--- /dev/null
+++ b/developer_cmds/developer_cmds.xcodeproj/project.pbxproj
@@ -0,0 +1,787 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ FDA9C8500FD5E85100A6EA6E /* default */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = FDA9C85E0FD5E86100A6EA6E /* Build configuration list for PBXAggregateTarget "default" */;
+ buildPhases = (
+ );
+ dependencies = (
+ FDA9C8590FD5E85C00A6EA6E /* PBXTargetDependency */,
+ FDA9C85B0FD5E85E00A6EA6E /* PBXTargetDependency */,
+ FDA9C8B60FD5EAA500A6EA6E /* PBXTargetDependency */,
+ FDA9C9870FD5F06900A6EA6E /* PBXTargetDependency */,
+ FDA9C8DA0FD5EBB200A6EA6E /* PBXTargetDependency */,
+ FDA9C8FC0FD5EC3300A6EA6E /* PBXTargetDependency */,
+ );
+ name = default;
+ productName = Default;
+ };
+ FDA9C97F0FD5F05400A6EA6E /* lorder */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = FDA9C98B0FD5F08700A6EA6E /* Build configuration list for PBXAggregateTarget "lorder" */;
+ buildPhases = (
+ FDA9C97E0FD5F05400A6EA6E /* ShellScript */,
+ FDA9C9A20FD5F12200A6EA6E /* Install man1 */,
+ );
+ dependencies = (
+ );
+ name = lorder;
+ productName = lorder;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ FDA9C83F0FD5E7E300A6EA6E /* asa.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7E40FD5D90F00A6EA6E /* asa.c */; };
+ FDA9C84D0FD5E82800A6EA6E /* asa.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C7E30FD5D90F00A6EA6E /* asa.1 */; };
+ FDA9C85F0FD5E87200A6EA6E /* C.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7E70FD5D92800A6EA6E /* C.c */; };
+ FDA9C8600FD5E87200A6EA6E /* ctags.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7E90FD5D92800A6EA6E /* ctags.c */; };
+ FDA9C8610FD5E87200A6EA6E /* fortran.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7EB0FD5D92800A6EA6E /* fortran.c */; };
+ FDA9C8620FD5E87200A6EA6E /* lisp.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7EC0FD5D92800A6EA6E /* lisp.c */; };
+ FDA9C8630FD5E87200A6EA6E /* print.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7EE0FD5D92800A6EA6E /* print.c */; };
+ FDA9C8640FD5E87200A6EA6E /* tree.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7F10FD5D92800A6EA6E /* tree.c */; };
+ FDA9C8650FD5E87200A6EA6E /* yacc.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7F20FD5D92800A6EA6E /* yacc.c */; };
+ FDA9C86B0FD5E88900A6EA6E /* ctags.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C7E80FD5D92800A6EA6E /* ctags.1 */; };
+ FDA9C8BA0FD5EAD700A6EA6E /* args.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C7FF0FD5D92800A6EA6E /* args.c */; };
+ FDA9C8BB0FD5EAD700A6EA6E /* indent.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8010FD5D92800A6EA6E /* indent.c */; };
+ FDA9C8BC0FD5EAD700A6EA6E /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8040FD5D92800A6EA6E /* io.c */; };
+ FDA9C8BD0FD5EAD700A6EA6E /* lexi.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8050FD5D92800A6EA6E /* lexi.c */; };
+ FDA9C8BE0FD5EAD700A6EA6E /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8070FD5D92800A6EA6E /* parse.c */; };
+ FDA9C8BF0FD5EAD700A6EA6E /* pr_comment.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8080FD5D92800A6EA6E /* pr_comment.c */; };
+ FDA9C8C10FD5EAEA00A6EA6E /* indent.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C8000FD5D92800A6EA6E /* indent.1 */; };
+ FDA9C8DF0FD5EBE600A6EA6E /* rpc_clntout.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8180FD5D92800A6EA6E /* rpc_clntout.c */; };
+ FDA9C8E00FD5EBE600A6EA6E /* rpc_cout.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8190FD5D92800A6EA6E /* rpc_cout.c */; };
+ FDA9C8E10FD5EBE600A6EA6E /* rpc_hout.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C81A0FD5D92800A6EA6E /* rpc_hout.c */; };
+ FDA9C8E20FD5EBE600A6EA6E /* rpc_main.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C81B0FD5D92800A6EA6E /* rpc_main.c */; };
+ FDA9C8E30FD5EBE600A6EA6E /* rpc_parse.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C81C0FD5D92800A6EA6E /* rpc_parse.c */; };
+ FDA9C8E40FD5EBE600A6EA6E /* rpc_sample.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C81E0FD5D92800A6EA6E /* rpc_sample.c */; };
+ FDA9C8E50FD5EBE600A6EA6E /* rpc_scan.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C81F0FD5D92800A6EA6E /* rpc_scan.c */; };
+ FDA9C8E60FD5EBE600A6EA6E /* rpc_svcout.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8210FD5D92800A6EA6E /* rpc_svcout.c */; };
+ FDA9C8E70FD5EBE600A6EA6E /* rpc_tblout.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8220FD5D92800A6EA6E /* rpc_tblout.c */; };
+ FDA9C8E80FD5EBE600A6EA6E /* rpc_util.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8230FD5D92800A6EA6E /* rpc_util.c */; };
+ FDA9C8EA0FD5EBF600A6EA6E /* rpcgen.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C8250FD5D92800A6EA6E /* rpcgen.1 */; };
+ FDA9C9010FD5EC4800A6EA6E /* unifdef.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA9C8290FD5D92800A6EA6E /* unifdef.c */; };
+ FDA9C9030FD5EC5F00A6EA6E /* unifdef.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C8280FD5D92800A6EA6E /* unifdef.1 */; };
+ FDA9C9900FD5F10200A6EA6E /* lorder.1 in Install man1 */ = {isa = PBXBuildFile; fileRef = FDA9C80B0FD5D92800A6EA6E /* lorder.1 */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ FDA9C8580FD5E85C00A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C8390FD5E7DB00A6EA6E;
+ remoteInfo = asa;
+ };
+ FDA9C85A0FD5E85E00A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C8540FD5E85900A6EA6E;
+ remoteInfo = ctags;
+ };
+ FDA9C8B50FD5EAA500A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C8B10FD5EAA100A6EA6E;
+ remoteInfo = indent;
+ };
+ FDA9C8D90FD5EBB200A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C8D50FD5EBA400A6EA6E;
+ remoteInfo = rpcgen;
+ };
+ FDA9C8FB0FD5EC3300A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C8F70FD5EC2A00A6EA6E;
+ remoteInfo = unifdef;
+ };
+ FDA9C9860FD5F06900A6EA6E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = FDA9C97F0FD5F05400A6EA6E;
+ remoteInfo = lorder;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ FDA9C84F0FD5E82D00A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C84D0FD5E82800A6EA6E /* asa.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ FDA9C8730FD5E89700A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C86B0FD5E88900A6EA6E /* ctags.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ FDA9C8CA0FD5EAFC00A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C8C10FD5EAEA00A6EA6E /* indent.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ FDA9C8F40FD5EC0F00A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C8EA0FD5EBF600A6EA6E /* rpcgen.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ FDA9C9040FD5EC6800A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C9030FD5EC5F00A6EA6E /* unifdef.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ FDA9C9A20FD5F12200A6EA6E /* Install man1 */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(DT_TOOLCHAIN_DIR)/usr/share/man/man1";
+ dstSubfolderSpec = 0;
+ files = (
+ FDA9C9900FD5F10200A6EA6E /* lorder.1 in Install man1 */,
+ );
+ name = "Install man1";
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ FDA9C7E30FD5D90F00A6EA6E /* asa.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = asa.1; sourceTree = "<group>"; };
+ FDA9C7E40FD5D90F00A6EA6E /* asa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asa.c; sourceTree = "<group>"; };
+ FDA9C7E70FD5D92800A6EA6E /* C.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = C.c; sourceTree = "<group>"; };
+ FDA9C7E80FD5D92800A6EA6E /* ctags.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = ctags.1; sourceTree = "<group>"; };
+ FDA9C7E90FD5D92800A6EA6E /* ctags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ctags.c; sourceTree = "<group>"; };
+ FDA9C7EA0FD5D92800A6EA6E /* ctags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ctags.h; sourceTree = "<group>"; };
+ FDA9C7EB0FD5D92800A6EA6E /* fortran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fortran.c; sourceTree = "<group>"; };
+ FDA9C7EC0FD5D92800A6EA6E /* lisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lisp.c; sourceTree = "<group>"; };
+ FDA9C7EE0FD5D92800A6EA6E /* print.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = print.c; sourceTree = "<group>"; };
+ FDA9C7F00FD5D92800A6EA6E /* ctags.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ctags.test; sourceTree = "<group>"; };
+ FDA9C7F10FD5D92800A6EA6E /* tree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tree.c; sourceTree = "<group>"; };
+ FDA9C7F20FD5D92800A6EA6E /* yacc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yacc.c; sourceTree = "<group>"; };
+ FDA9C7FF0FD5D92800A6EA6E /* args.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = args.c; sourceTree = "<group>"; };
+ FDA9C8000FD5D92800A6EA6E /* indent.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = indent.1; sourceTree = "<group>"; };
+ FDA9C8010FD5D92800A6EA6E /* indent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = indent.c; sourceTree = "<group>"; };
+ FDA9C8020FD5D92800A6EA6E /* indent_codes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indent_codes.h; sourceTree = "<group>"; };
+ FDA9C8030FD5D92800A6EA6E /* indent_globs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indent_globs.h; sourceTree = "<group>"; };
+ FDA9C8040FD5D92800A6EA6E /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = "<group>"; };
+ FDA9C8050FD5D92800A6EA6E /* lexi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lexi.c; sourceTree = "<group>"; };
+ FDA9C8070FD5D92800A6EA6E /* parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = parse.c; sourceTree = "<group>"; };
+ FDA9C8080FD5D92800A6EA6E /* pr_comment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pr_comment.c; sourceTree = "<group>"; };
+ FDA9C8090FD5D92800A6EA6E /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+ FDA9C80B0FD5D92800A6EA6E /* lorder.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = lorder.1; sourceTree = "<group>"; };
+ FDA9C80C0FD5D92800A6EA6E /* lorder.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = lorder.sh; sourceTree = "<group>"; };
+ FDA9C8180FD5D92800A6EA6E /* rpc_clntout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_clntout.c; sourceTree = "<group>"; };
+ FDA9C8190FD5D92800A6EA6E /* rpc_cout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_cout.c; sourceTree = "<group>"; };
+ FDA9C81A0FD5D92800A6EA6E /* rpc_hout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_hout.c; sourceTree = "<group>"; };
+ FDA9C81B0FD5D92800A6EA6E /* rpc_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_main.c; sourceTree = "<group>"; };
+ FDA9C81C0FD5D92800A6EA6E /* rpc_parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_parse.c; sourceTree = "<group>"; };
+ FDA9C81D0FD5D92800A6EA6E /* rpc_parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpc_parse.h; sourceTree = "<group>"; };
+ FDA9C81E0FD5D92800A6EA6E /* rpc_sample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_sample.c; sourceTree = "<group>"; };
+ FDA9C81F0FD5D92800A6EA6E /* rpc_scan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_scan.c; sourceTree = "<group>"; };
+ FDA9C8200FD5D92800A6EA6E /* rpc_scan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpc_scan.h; sourceTree = "<group>"; };
+ FDA9C8210FD5D92800A6EA6E /* rpc_svcout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_svcout.c; sourceTree = "<group>"; };
+ FDA9C8220FD5D92800A6EA6E /* rpc_tblout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_tblout.c; sourceTree = "<group>"; };
+ FDA9C8230FD5D92800A6EA6E /* rpc_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_util.c; sourceTree = "<group>"; };
+ FDA9C8240FD5D92800A6EA6E /* rpc_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpc_util.h; sourceTree = "<group>"; };
+ FDA9C8250FD5D92800A6EA6E /* rpcgen.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = rpcgen.1; sourceTree = "<group>"; };
+ FDA9C8280FD5D92800A6EA6E /* unifdef.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = unifdef.1; sourceTree = "<group>"; };
+ FDA9C8290FD5D92800A6EA6E /* unifdef.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unifdef.c; sourceTree = "<group>"; };
+ FDA9C82A0FD5D92800A6EA6E /* unifdefall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = unifdefall.sh; sourceTree = "<group>"; };
+ FDA9C83A0FD5E7DB00A6EA6E /* asa */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = asa; sourceTree = BUILT_PRODUCTS_DIR; };
+ FDA9C8550FD5E85900A6EA6E /* ctags */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ctags; sourceTree = BUILT_PRODUCTS_DIR; };
+ FDA9C8B20FD5EAA100A6EA6E /* indent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = indent; sourceTree = BUILT_PRODUCTS_DIR; };
+ FDA9C8D60FD5EBA400A6EA6E /* rpcgen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = rpcgen; sourceTree = BUILT_PRODUCTS_DIR; };
+ FDA9C8F80FD5EC2A00A6EA6E /* unifdef */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = unifdef; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ FDA9C8380FD5E7DB00A6EA6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8530FD5E85900A6EA6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8B00FD5EAA100A6EA6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8D40FD5EBA400A6EA6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8F60FD5EC2A00A6EA6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ FDA9C7D50FD5D84000A6EA6E = {
+ isa = PBXGroup;
+ children = (
+ FDA9C9280FD5ED6700A6EA6E /* Source */,
+ FDA9C83B0FD5E7DB00A6EA6E /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ FDA9C7E20FD5D90F00A6EA6E /* asa */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C7E30FD5D90F00A6EA6E /* asa.1 */,
+ FDA9C7E40FD5D90F00A6EA6E /* asa.c */,
+ );
+ path = asa;
+ sourceTree = "<group>";
+ };
+ FDA9C7E60FD5D92800A6EA6E /* ctags */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C7E70FD5D92800A6EA6E /* C.c */,
+ FDA9C7E90FD5D92800A6EA6E /* ctags.c */,
+ FDA9C7EB0FD5D92800A6EA6E /* fortran.c */,
+ FDA9C7EC0FD5D92800A6EA6E /* lisp.c */,
+ FDA9C7EE0FD5D92800A6EA6E /* print.c */,
+ FDA9C7F10FD5D92800A6EA6E /* tree.c */,
+ FDA9C7F20FD5D92800A6EA6E /* yacc.c */,
+ FDA9C7EA0FD5D92800A6EA6E /* ctags.h */,
+ FDA9C7E80FD5D92800A6EA6E /* ctags.1 */,
+ FDA9C7EF0FD5D92800A6EA6E /* test */,
+ );
+ path = ctags;
+ sourceTree = "<group>";
+ };
+ FDA9C7EF0FD5D92800A6EA6E /* test */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C7F00FD5D92800A6EA6E /* ctags.test */,
+ );
+ path = test;
+ sourceTree = "<group>";
+ };
+ FDA9C7FE0FD5D92800A6EA6E /* indent */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C7FF0FD5D92800A6EA6E /* args.c */,
+ FDA9C8010FD5D92800A6EA6E /* indent.c */,
+ FDA9C8040FD5D92800A6EA6E /* io.c */,
+ FDA9C8050FD5D92800A6EA6E /* lexi.c */,
+ FDA9C8070FD5D92800A6EA6E /* parse.c */,
+ FDA9C8080FD5D92800A6EA6E /* pr_comment.c */,
+ FDA9C8020FD5D92800A6EA6E /* indent_codes.h */,
+ FDA9C8030FD5D92800A6EA6E /* indent_globs.h */,
+ FDA9C8000FD5D92800A6EA6E /* indent.1 */,
+ FDA9C8090FD5D92800A6EA6E /* README */,
+ );
+ path = indent;
+ sourceTree = "<group>";
+ };
+ FDA9C80A0FD5D92800A6EA6E /* lorder */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C80C0FD5D92800A6EA6E /* lorder.sh */,
+ FDA9C80B0FD5D92800A6EA6E /* lorder.1 */,
+ );
+ path = lorder;
+ sourceTree = "<group>";
+ };
+ FDA9C8160FD5D92800A6EA6E /* rpcgen */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C8180FD5D92800A6EA6E /* rpc_clntout.c */,
+ FDA9C8190FD5D92800A6EA6E /* rpc_cout.c */,
+ FDA9C81A0FD5D92800A6EA6E /* rpc_hout.c */,
+ FDA9C81B0FD5D92800A6EA6E /* rpc_main.c */,
+ FDA9C81C0FD5D92800A6EA6E /* rpc_parse.c */,
+ FDA9C81E0FD5D92800A6EA6E /* rpc_sample.c */,
+ FDA9C81F0FD5D92800A6EA6E /* rpc_scan.c */,
+ FDA9C8210FD5D92800A6EA6E /* rpc_svcout.c */,
+ FDA9C8220FD5D92800A6EA6E /* rpc_tblout.c */,
+ FDA9C8230FD5D92800A6EA6E /* rpc_util.c */,
+ FDA9C81D0FD5D92800A6EA6E /* rpc_parse.h */,
+ FDA9C8200FD5D92800A6EA6E /* rpc_scan.h */,
+ FDA9C8240FD5D92800A6EA6E /* rpc_util.h */,
+ FDA9C8250FD5D92800A6EA6E /* rpcgen.1 */,
+ );
+ path = rpcgen;
+ sourceTree = "<group>";
+ };
+ FDA9C8260FD5D92800A6EA6E /* unifdef */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C8290FD5D92800A6EA6E /* unifdef.c */,
+ FDA9C8280FD5D92800A6EA6E /* unifdef.1 */,
+ FDA9C82A0FD5D92800A6EA6E /* unifdefall.sh */,
+ );
+ path = unifdef;
+ sourceTree = "<group>";
+ };
+ FDA9C83B0FD5E7DB00A6EA6E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C83A0FD5E7DB00A6EA6E /* asa */,
+ FDA9C8550FD5E85900A6EA6E /* ctags */,
+ FDA9C8B20FD5EAA100A6EA6E /* indent */,
+ FDA9C8D60FD5EBA400A6EA6E /* rpcgen */,
+ FDA9C8F80FD5EC2A00A6EA6E /* unifdef */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FDA9C9280FD5ED6700A6EA6E /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ FDA9C7E20FD5D90F00A6EA6E /* asa */,
+ FDA9C7E60FD5D92800A6EA6E /* ctags */,
+ FDA9C7FE0FD5D92800A6EA6E /* indent */,
+ FDA9C80A0FD5D92800A6EA6E /* lorder */,
+ FDA9C8160FD5D92800A6EA6E /* rpcgen */,
+ FDA9C8260FD5D92800A6EA6E /* unifdef */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ FDA9C8390FD5E7DB00A6EA6E /* asa */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = FDA9C83E0FD5E7DC00A6EA6E /* Build configuration list for PBXNativeTarget "asa" */;
+ buildPhases = (
+ FDA9C8370FD5E7DB00A6EA6E /* Sources */,
+ FDA9C8380FD5E7DB00A6EA6E /* Frameworks */,
+ FDA9C84F0FD5E82D00A6EA6E /* Install man1 */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = asa;
+ productName = asa;
+ productReference = FDA9C83A0FD5E7DB00A6EA6E /* asa */;
+ productType = "com.apple.product-type.tool";
+ };
+ FDA9C8540FD5E85900A6EA6E /* ctags */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = FDA9C85D0FD5E86100A6EA6E /* Build configuration list for PBXNativeTarget "ctags" */;
+ buildPhases = (
+ FDA9C8520FD5E85900A6EA6E /* Sources */,
+ FDA9C8530FD5E85900A6EA6E /* Frameworks */,
+ FDA9C8730FD5E89700A6EA6E /* Install man1 */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ctags;
+ productName = ctags;
+ productReference = FDA9C8550FD5E85900A6EA6E /* ctags */;
+ productType = "com.apple.product-type.tool";
+ };
+ FDA9C8B10FD5EAA100A6EA6E /* indent */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = FDA9C8B90FD5EAAD00A6EA6E /* Build configuration list for PBXNativeTarget "indent" */;
+ buildPhases = (
+ FDA9C8AF0FD5EAA100A6EA6E /* Sources */,
+ FDA9C8B00FD5EAA100A6EA6E /* Frameworks */,
+ FDA9C8CA0FD5EAFC00A6EA6E /* Install man1 */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = indent;
+ productName = indent;
+ productReference = FDA9C8B20FD5EAA100A6EA6E /* indent */;
+ productType = "com.apple.product-type.tool";
+ };
+ FDA9C8D50FD5EBA400A6EA6E /* rpcgen */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = FDA9C8DE0FD5EBB300A6EA6E /* Build configuration list for PBXNativeTarget "rpcgen" */;
+ buildPhases = (
+ FDA9C8D30FD5EBA400A6EA6E /* Sources */,
+ FDA9C8D40FD5EBA400A6EA6E /* Frameworks */,
+ FDA9C8F40FD5EC0F00A6EA6E /* Install man1 */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = rpcgen;
+ productName = rpcgen;
+ productReference = FDA9C8D60FD5EBA400A6EA6E /* rpcgen */;
+ productType = "com.apple.product-type.tool";
+ };
+ FDA9C8F70FD5EC2A00A6EA6E /* unifdef */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = FDA9C9000FD5EC3B00A6EA6E /* Build configuration list for PBXNativeTarget "unifdef" */;
+ buildPhases = (
+ FDA9C8F50FD5EC2A00A6EA6E /* Sources */,
+ FDA9C8F60FD5EC2A00A6EA6E /* Frameworks */,
+ FDA9C9040FD5EC6800A6EA6E /* Install man1 */,
+ FDA9C9080FD5EC7500A6EA6E /* Install unifdefall */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = unifdef;
+ productName = unifdef;
+ productReference = FDA9C8F80FD5EC2A00A6EA6E /* unifdef */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ FDA9C7D70FD5D84000A6EA6E /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ };
+ buildConfigurationList = FDA9C7DA0FD5D84000A6EA6E /* Build configuration list for PBXProject "developer_cmds" */;
+ compatibilityVersion = "Xcode 2.4";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = FDA9C7D50FD5D84000A6EA6E;
+ productRefGroup = FDA9C83B0FD5E7DB00A6EA6E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ FDA9C8500FD5E85100A6EA6E /* default */,
+ FDA9C8390FD5E7DB00A6EA6E /* asa */,
+ FDA9C8540FD5E85900A6EA6E /* ctags */,
+ FDA9C8B10FD5EAA100A6EA6E /* indent */,
+ FDA9C97F0FD5F05400A6EA6E /* lorder */,
+ FDA9C8D50FD5EBA400A6EA6E /* rpcgen */,
+ FDA9C8F70FD5EC2A00A6EA6E /* unifdef */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ FDA9C9080FD5EC7500A6EA6E /* Install unifdefall */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 8;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Install unifdefall";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-unifdefall.sh";
+ showEnvVarsInLog = 0;
+ };
+ FDA9C97E0FD5F05400A6EA6E /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 8;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-lorder.sh";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ FDA9C8370FD5E7DB00A6EA6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FDA9C83F0FD5E7E300A6EA6E /* asa.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8520FD5E85900A6EA6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FDA9C85F0FD5E87200A6EA6E /* C.c in Sources */,
+ FDA9C8600FD5E87200A6EA6E /* ctags.c in Sources */,
+ FDA9C8610FD5E87200A6EA6E /* fortran.c in Sources */,
+ FDA9C8620FD5E87200A6EA6E /* lisp.c in Sources */,
+ FDA9C8630FD5E87200A6EA6E /* print.c in Sources */,
+ FDA9C8640FD5E87200A6EA6E /* tree.c in Sources */,
+ FDA9C8650FD5E87200A6EA6E /* yacc.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8AF0FD5EAA100A6EA6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FDA9C8BA0FD5EAD700A6EA6E /* args.c in Sources */,
+ FDA9C8BB0FD5EAD700A6EA6E /* indent.c in Sources */,
+ FDA9C8BC0FD5EAD700A6EA6E /* io.c in Sources */,
+ FDA9C8BD0FD5EAD700A6EA6E /* lexi.c in Sources */,
+ FDA9C8BE0FD5EAD700A6EA6E /* parse.c in Sources */,
+ FDA9C8BF0FD5EAD700A6EA6E /* pr_comment.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8D30FD5EBA400A6EA6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FDA9C8DF0FD5EBE600A6EA6E /* rpc_clntout.c in Sources */,
+ FDA9C8E00FD5EBE600A6EA6E /* rpc_cout.c in Sources */,
+ FDA9C8E10FD5EBE600A6EA6E /* rpc_hout.c in Sources */,
+ FDA9C8E20FD5EBE600A6EA6E /* rpc_main.c in Sources */,
+ FDA9C8E30FD5EBE600A6EA6E /* rpc_parse.c in Sources */,
+ FDA9C8E40FD5EBE600A6EA6E /* rpc_sample.c in Sources */,
+ FDA9C8E50FD5EBE600A6EA6E /* rpc_scan.c in Sources */,
+ FDA9C8E60FD5EBE600A6EA6E /* rpc_svcout.c in Sources */,
+ FDA9C8E70FD5EBE600A6EA6E /* rpc_tblout.c in Sources */,
+ FDA9C8E80FD5EBE600A6EA6E /* rpc_util.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FDA9C8F50FD5EC2A00A6EA6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FDA9C9010FD5EC4800A6EA6E /* unifdef.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ FDA9C8590FD5E85C00A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C8390FD5E7DB00A6EA6E /* asa */;
+ targetProxy = FDA9C8580FD5E85C00A6EA6E /* PBXContainerItemProxy */;
+ };
+ FDA9C85B0FD5E85E00A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C8540FD5E85900A6EA6E /* ctags */;
+ targetProxy = FDA9C85A0FD5E85E00A6EA6E /* PBXContainerItemProxy */;
+ };
+ FDA9C8B60FD5EAA500A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C8B10FD5EAA100A6EA6E /* indent */;
+ targetProxy = FDA9C8B50FD5EAA500A6EA6E /* PBXContainerItemProxy */;
+ };
+ FDA9C8DA0FD5EBB200A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C8D50FD5EBA400A6EA6E /* rpcgen */;
+ targetProxy = FDA9C8D90FD5EBB200A6EA6E /* PBXContainerItemProxy */;
+ };
+ FDA9C8FC0FD5EC3300A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C8F70FD5EC2A00A6EA6E /* unifdef */;
+ targetProxy = FDA9C8FB0FD5EC3300A6EA6E /* PBXContainerItemProxy */;
+ };
+ FDA9C9870FD5F06900A6EA6E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = FDA9C97F0FD5F05400A6EA6E /* lorder */;
+ targetProxy = FDA9C9860FD5F06900A6EA6E /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ FDA9C7D90FD5D84000A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_MODE_FLAG = "ugo-w,a+rX";
+ PREBINDING = NO;
+ USE_HEADERMAP = NO;
+ VERSIONING_SYSTEM = "apple-generic";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ FDA9C83D0FD5E7DB00A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = "$(DT_TOOLCHAIN_DIR)/usr/bin";
+ PRODUCT_NAME = asa;
+ };
+ name = Release;
+ };
+ FDA9C8510FD5E85100A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = default;
+ };
+ name = Release;
+ };
+ FDA9C8570FD5E85900A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = "$(DT_TOOLCHAIN_DIR)/usr/bin";
+ PRODUCT_NAME = ctags;
+ };
+ name = Release;
+ };
+ FDA9C8B40FD5EAA200A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = "$(DT_TOOLCHAIN_DIR)/usr/bin";
+ PRODUCT_NAME = indent;
+ };
+ name = Release;
+ };
+ FDA9C8D80FD5EBA400A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = "$(DT_TOOLCHAIN_DIR)/usr/bin";
+ PRODUCT_NAME = rpcgen;
+ };
+ name = Release;
+ };
+ FDA9C8FA0FD5EC2A00A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = "$(DT_TOOLCHAIN_DIR)/usr/bin";
+ PRODUCT_NAME = unifdef;
+ };
+ name = Release;
+ };
+ FDA9C9800FD5F05400A6EA6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = lorder;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ FDA9C7DA0FD5D84000A6EA6E /* Build configuration list for PBXProject "developer_cmds" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C7D90FD5D84000A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C83E0FD5E7DC00A6EA6E /* Build configuration list for PBXNativeTarget "asa" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C83D0FD5E7DB00A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C85D0FD5E86100A6EA6E /* Build configuration list for PBXNativeTarget "ctags" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C8570FD5E85900A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C85E0FD5E86100A6EA6E /* Build configuration list for PBXAggregateTarget "default" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C8510FD5E85100A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C8B90FD5EAAD00A6EA6E /* Build configuration list for PBXNativeTarget "indent" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C8B40FD5EAA200A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C8DE0FD5EBB300A6EA6E /* Build configuration list for PBXNativeTarget "rpcgen" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C8D80FD5EBA400A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C9000FD5EC3B00A6EA6E /* Build configuration list for PBXNativeTarget "unifdef" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C8FA0FD5EC2A00A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ FDA9C98B0FD5F08700A6EA6E /* Build configuration list for PBXAggregateTarget "lorder" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ FDA9C9800FD5F05400A6EA6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = FDA9C7D70FD5D84000A6EA6E /* Project object */;
+}
diff --git a/developer_cmds/developer_cmds.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/developer_cmds/developer_cmds.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/developer_cmds/developer_cmds.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:">
+ </FileRef>
+</Workspace>
diff --git a/developer_cmds/indent/args.c b/developer_cmds/indent/args.c
new file mode 100644
index 0000000..507be03
--- /dev/null
+++ b/developer_cmds/indent/args.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/args.c,v 1.16 2010/03/31 17:05:30 avg Exp $");
+
+/*
+ * Argument scanning and profile reading code. Default parameters are set
+ * here as well.
+ */
+
+#include <ctype.h>
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "indent_globs.h"
+#include "indent.h"
+
+/* profile types */
+#define PRO_SPECIAL 1 /* special case */
+#define PRO_BOOL 2 /* boolean */
+#define PRO_INT 3 /* integer */
+#define PRO_FONT 4 /* troff font */
+
+/* profile specials for booleans */
+#define ON 1 /* turn it on */
+#define OFF 0 /* turn it off */
+
+/* profile specials for specials */
+#define IGN 1 /* ignore it */
+#define CLI 2 /* case label indent (float) */
+#define STDIN 3 /* use stdin */
+#define KEY 4 /* type (keyword) */
+
+static void scan_profile(FILE *);
+
+const char *option_source = "?";
+
+/*
+ * N.B.: because of the way the table here is scanned, options whose names are
+ * substrings of other options must occur later; that is, with -lp vs -l, -lp
+ * must be first. Also, while (most) booleans occur more than once, the last
+ * default value is the one actually assigned.
+ */
+struct pro {
+ const char *p_name; /* name, e.g. -bl, -cli */
+ int p_type; /* type (int, bool, special) */
+ int p_default; /* the default value (if int) */
+ int p_special; /* depends on type */
+ int *p_obj; /* the associated variable */
+} pro[] = {
+
+ {"T", PRO_SPECIAL, 0, KEY, 0},
+ {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation},
+ {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop},
+ {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations},
+ {"bap", PRO_BOOL, false, ON, &blanklines_after_procs},
+ {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments},
+ {"bc", PRO_BOOL, true, OFF, &ps.leave_comma},
+ {"bl", PRO_BOOL, true, OFF, &btype_2},
+ {"br", PRO_BOOL, true, ON, &btype_2},
+ {"bs", PRO_BOOL, false, ON, &Bill_Shannon},
+ {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline},
+ {"cd", PRO_INT, 0, 0, &ps.decl_com_ind},
+ {"ce", PRO_BOOL, true, ON, &cuddle_else},
+ {"ci", PRO_INT, 0, 0, &continuation_indent},
+ {"cli", PRO_SPECIAL, 0, CLI, 0},
+ {"c", PRO_INT, 33, 0, &ps.com_ind},
+ {"di", PRO_INT, 16, 0, &ps.decl_indent},
+ {"dj", PRO_BOOL, false, ON, &ps.ljust_decl},
+ {"d", PRO_INT, 0, 0, &ps.unindent_displace},
+ {"eei", PRO_BOOL, false, ON, &extra_expression_indent},
+ {"ei", PRO_BOOL, true, ON, &ps.else_if},
+ {"fbc", PRO_FONT, 0, 0, (int *) &blkcomf},
+ {"fbs", PRO_BOOL, true, ON, &function_brace_split},
+ {"fbx", PRO_FONT, 0, 0, (int *) &boxcomf},
+ {"fb", PRO_FONT, 0, 0, (int *) &bodyf},
+ {"fc1", PRO_BOOL, true, ON, &format_col1_comments},
+ {"fcb", PRO_BOOL, true, ON, &format_block_comments},
+ {"fc", PRO_FONT, 0, 0, (int *) &scomf},
+ {"fk", PRO_FONT, 0, 0, (int *) &keywordf},
+ {"fs", PRO_FONT, 0, 0, (int *) &stringf},
+ {"ip", PRO_BOOL, true, ON, &ps.indent_parameters},
+ {"i", PRO_INT, 8, 0, &ps.ind_size},
+ {"lc", PRO_INT, 0, 0, &block_comment_max_col},
+ {"ldi", PRO_INT, -1, 0, &ps.local_decl_indent},
+ {"lp", PRO_BOOL, true, ON, &lineup_to_parens},
+ {"l", PRO_INT, 78, 0, &max_col},
+ {"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation},
+ {"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop},
+ {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations},
+ {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs},
+ {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments},
+ {"nbc", PRO_BOOL, true, ON, &ps.leave_comma},
+ {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon},
+ {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline},
+ {"nce", PRO_BOOL, true, OFF, &cuddle_else},
+ {"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl},
+ {"neei", PRO_BOOL, false, OFF, &extra_expression_indent},
+ {"nei", PRO_BOOL, true, OFF, &ps.else_if},
+ {"nfbs", PRO_BOOL, true, OFF, &function_brace_split},
+ {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments},
+ {"nfcb", PRO_BOOL, true, OFF, &format_block_comments},
+ {"nip", PRO_BOOL, true, OFF, &ps.indent_parameters},
+ {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens},
+ {"npcs", PRO_BOOL, false, OFF, &proc_calls_space},
+ {"npro", PRO_SPECIAL, 0, IGN, 0},
+ {"npsl", PRO_BOOL, true, OFF, &procnames_start_line},
+ {"nps", PRO_BOOL, false, OFF, &pointer_as_binop},
+ {"nsc", PRO_BOOL, true, OFF, &star_comment_cont},
+ {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines},
+ {"nut", PRO_BOOL, true, OFF, &use_tabs},
+ {"nv", PRO_BOOL, false, OFF, &verbose},
+ {"pcs", PRO_BOOL, false, ON, &proc_calls_space},
+ {"psl", PRO_BOOL, true, ON, &procnames_start_line},
+ {"ps", PRO_BOOL, false, ON, &pointer_as_binop},
+ {"sc", PRO_BOOL, true, ON, &star_comment_cont},
+ {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
+ {"st", PRO_SPECIAL, 0, STDIN, 0},
+ {"ta", PRO_BOOL, false, ON, &auto_typedefs},
+ {"troff", PRO_BOOL, false, ON, &troff},
+ {"ut", PRO_BOOL, true, ON, &use_tabs},
+ {"v", PRO_BOOL, false, ON, &verbose},
+ /* whew! */
+ {0, 0, 0, 0, 0}
+};
+
+/*
+ * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
+ * given in these files.
+ */
+void
+set_profile(void)
+{
+ FILE *f;
+ char fname[PATH_MAX];
+ static char prof[] = ".indent.pro";
+
+ snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
+ if ((f = fopen(option_source = fname, "r")) != NULL) {
+ scan_profile(f);
+ (void) fclose(f);
+ }
+ if ((f = fopen(option_source = prof, "r")) != NULL) {
+ scan_profile(f);
+ (void) fclose(f);
+ }
+ option_source = "Command line";
+}
+
+static void
+scan_profile(FILE *f)
+{
+ int comment, i;
+ char *p;
+ char buf[BUFSIZ];
+
+ while (1) {
+ p = buf;
+ comment = 0;
+ while ((i = getc(f)) != EOF) {
+ if (i == '*' && !comment && p > buf && p[-1] == '/') {
+ comment = p - buf;
+ *p++ = i;
+ } else if (i == '/' && comment && p > buf && p[-1] == '*') {
+ p = buf + comment - 1;
+ comment = 0;
+ } else if (isspace(i)) {
+ if (p > buf && !comment)
+ break;
+ } else {
+ *p++ = i;
+ }
+ }
+ if (p != buf) {
+ *p++ = 0;
+ if (verbose)
+ printf("profile: %s\n", buf);
+ set_option(buf);
+ }
+ else if (i == EOF)
+ return;
+ }
+}
+
+const char *param_start;
+
+static int
+eqin(const char *s1, const char *s2)
+{
+ while (*s1) {
+ if (*s1++ != *s2++)
+ return (false);
+ }
+ param_start = s2;
+ return (true);
+}
+
+/*
+ * Set the defaults.
+ */
+void
+set_defaults(void)
+{
+ struct pro *p;
+
+ /*
+ * Because ps.case_indent is a float, we can't initialize it from the
+ * table:
+ */
+ ps.case_indent = 0.0; /* -cli0.0 */
+ for (p = pro; p->p_name; p++)
+ if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
+ *p->p_obj = p->p_default;
+}
+
+void
+set_option(char *arg)
+{
+ struct pro *p;
+
+ arg++; /* ignore leading "-" */
+ for (p = pro; p->p_name; p++)
+ if (*p->p_name == *arg && eqin(p->p_name, arg))
+ goto found;
+ errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
+found:
+ switch (p->p_type) {
+
+ case PRO_SPECIAL:
+ switch (p->p_special) {
+
+ case IGN:
+ break;
+
+ case CLI:
+ if (*param_start == 0)
+ goto need_param;
+ ps.case_indent = atof(param_start);
+ break;
+
+ case STDIN:
+ if (input == 0)
+ input = stdin;
+ if (output == 0)
+ output = stdout;
+ break;
+
+ case KEY:
+ if (*param_start == 0)
+ goto need_param;
+ {
+ char *str = strdup(param_start);
+ if (str == NULL)
+ err(1, NULL);
+ addkey(str, 4);
+ }
+ break;
+
+ default:
+ errx(1, "set_option: internal error: p_special %d", p->p_special);
+ }
+ break;
+
+ case PRO_BOOL:
+ if (p->p_special == OFF)
+ *p->p_obj = false;
+ else
+ *p->p_obj = true;
+ break;
+
+ case PRO_INT:
+ if (!isdigit(*param_start)) {
+ need_param:
+ errx(1, "%s: ``%s'' requires a parameter", option_source, arg - 1);
+ }
+ *p->p_obj = atoi(param_start);
+ break;
+
+ case PRO_FONT:
+ parsefont((struct fstate *) p->p_obj, param_start);
+ break;
+
+ default:
+ errx(1, "set_option: internal error: p_type %d", p->p_type);
+ }
+}
diff --git a/developer_cmds/indent/indent.1 b/developer_cmds/indent/indent.1
new file mode 100644
index 0000000..f35ea95
--- /dev/null
+++ b/developer_cmds/indent/indent.1
@@ -0,0 +1,559 @@
+.\" Copyright (c) 1980, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1976 Board of Trustees of the University of Illinois.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)indent.1 8.1 (Berkeley) 7/1/93
+.\" $FreeBSD: src/usr.bin/indent/indent.1,v 1.28 2010/03/31 17:05:30 avg Exp $
+.\"
+.Dd June 29, 2004
+.Dt INDENT 1
+.Os
+.Sh NAME
+.Nm indent
+.Nd indent and format C program source
+.Sh SYNOPSIS
+.Nm
+.Op Ar input_file Op Ar output_file
+.Op Fl bacc | Fl nbacc
+.Op Fl bad | Fl nbad
+.Op Fl bap | Fl nbap
+.Bk -words
+.Op Fl bbb | Fl nbbb
+.Ek
+.Op Fl \&bc | Fl nbc
+.Op Fl \&bl
+.Op Fl \&br
+.Op Fl c Ns Ar n
+.Op Fl \&cd Ns Ar n
+.Bk -words
+.Op Fl cdb | Fl ncdb
+.Ek
+.Op Fl \&ce | Fl nce
+.Op Fl \&ci Ns Ar n
+.Op Fl cli Ns Ar n
+.Op Fl d Ns Ar n
+.Op Fl \&di Ns Ar n
+.Bk -words
+.Op Fl ei | Fl ei
+.Op Fl eei | Fl eei
+.Op Fl fbs | Fl nfbs
+.Op Fl fc1 | Fl nfc1
+.Op Fl fcb | Fl nfcb
+.Ek
+.Op Fl i Ns Ar n
+.Op Fl \&ip | Fl nip
+.Op Fl l Ns Ar n
+.Op Fl \&lc Ns Ar n
+.Op Fl \&ldi Ns Ar n
+.Op Fl \&lp | Fl nlp
+.Op Fl npro
+.Op Fl pcs | Fl npcs
+.Op Fl psl | Fl npsl
+.Op Fl \&sc | Fl nsc
+.Bk -words
+.Op Fl sob | Fl nsob
+.Ek
+.Op Fl \&st
+.Op Fl \&ta
+.Op Fl troff
+.Op Fl ut | Fl nut
+.Op Fl v | Fl \&nv
+.Sh DESCRIPTION
+.Nm
+is a
+.Em C
+program formatter.
+It reformats the
+.Em C
+program in the
+.Ar input_file
+according to the switches.
+The switches which can be
+specified are described below.
+They may appear before or after the file
+names.
+.Pp
+.Sy NOTE :
+If you only specify an
+.Ar input_file ,
+the formatting is
+done `in-place', that is, the formatted file is written back into
+.Ar input_file
+and a backup copy of
+.Ar input_file
+is written in the current directory.
+If
+.Ar input_file
+is named
+.Sq Pa /blah/blah/file ,
+the backup file is named
+.Sq Pa file.BAK .
+.Pp
+If
+.Ar output_file
+is specified,
+.Nm
+checks to make sure that it is different from
+.Ar input_file .
+.Pp
+The options listed below control the formatting style imposed by
+.Nm .
+.Bl -tag -width Op
+.It Fl bacc , nbacc
+If
+.Fl bacc
+is specified, a blank line is forced around every conditional
+compilation block.
+For example, in front of every #ifdef and after every #endif.
+Other blank lines surrounding such blocks will be swallowed.
+The default is
+.Fl nbacc .
+.It Fl bad , nbad
+If
+.Fl bad
+is specified, a blank line is forced after every block of
+declarations.
+The default is
+.Fl nbad .
+.It Fl bap , nbap
+If
+.Fl bap
+is specified, a blank line is forced after every procedure body.
+The default is
+.Fl nbap .
+.It Fl bbb , nbbb
+If
+.Fl bbb
+is specified, a blank line is forced before every block comment.
+The default is
+.Fl nbbb .
+.It Fl \&bc , nbc
+If
+.Fl \&bc
+is specified, then a newline is forced after each comma in a declaration.
+.Fl nbc
+turns off this option.
+The default is
+.Fl \&nbc .
+.It Fl \&br , \&bl
+Specifying
+.Fl \&bl
+lines-up compound statements like this:
+.Bd -literal -offset indent
+if (...)
+{
+ code
+}
+.Ed
+.Pp
+Specifying
+.Fl \&br
+(the default) makes them look like this:
+.Bd -literal -offset indent
+if (...) {
+ code
+}
+.Ed
+.Pp
+.It Fl c Ns Ar n
+The column in which comments on code start.
+The default is 33.
+.It Fl cd Ns Ar n
+The column in which comments on declarations start.
+The default
+is for these comments to start in the same column as those on code.
+.It Fl cdb , ncdb
+Enables (disables) the placement of comment delimiters on blank lines.
+With
+this option enabled, comments look like this:
+.Bd -literal -offset indent
+ /*
+ * this is a comment
+ */
+.Ed
+.Pp
+Rather than like this:
+.Bd -literal -offset indent
+ /* this is a comment */
+.Ed
+.Pp
+This only affects block comments, not comments to the right of
+code.
+The default is
+.Fl cdb .
+.It Fl ce , nce
+Enables (disables) forcing of `else's to cuddle up to the immediately preceding
+`}'.
+The default is
+.Fl \&ce .
+.It Fl \&ci Ns Ar n
+Sets the continuation indent to be
+.Ar n .
+Continuation
+lines will be indented that far from the beginning of the first line of the
+statement.
+Parenthesized expressions have extra indentation added to
+indicate the nesting, unless
+.Fl \&lp
+is in effect
+or the continuation indent is exactly half of the main indent.
+.Fl \&ci
+defaults to the same value as
+.Fl i .
+.It Fl cli Ns Ar n
+Causes case labels to be indented
+.Ar n
+tab stops to the right of the containing
+.Ic switch
+statement.
+.Fl cli0.5
+causes case labels to be indented half a tab stop.
+The
+default is
+.Fl cli0 .
+.It Fl d Ns Ar n
+Controls the placement of comments which are not to the
+right of code.
+For example,
+.Fl \&d\&1
+means that such comments are placed one indentation level to the
+left of code.
+Specifying the default
+.Fl \&d\&0
+lines-up these comments with the code.
+See the section on comment
+indentation below.
+.It Fl \&di Ns Ar n
+Specifies the indentation, in character positions,
+of global variable names and all struct/union member names
+relative to the beginning of their type declaration.
+The default is
+.Fl di16 .
+.It Fl dj , ndj
+.Fl \&dj
+left justifies declarations.
+.Fl ndj
+indents declarations the same as code.
+The default is
+.Fl ndj .
+.It Fl \&ei , nei
+Enables (disables) special
+.Ic else-if
+processing.
+If it is enabled, an
+.Ic if
+following an
+.Ic else
+will have the same indentation as the preceding
+.Ic \&if
+statement.
+The default is
+.Fl ei .
+.It Fl eei , neei
+Enables (disables) extra indentation on continuation lines of
+the expression part of
+.Ic if
+and
+.Ic while
+statements.
+These continuation lines will be indented one extra level.
+The default is
+.Fl neei .
+.It Fl fbs , nfbs
+Enables (disables) splitting the function declaration and opening brace
+across two lines.
+The default is
+.Fl fbs .
+.It Fl fc1 , nfc1
+Enables (disables) the formatting of comments that start in column 1.
+Often, comments whose leading `/' is in column 1 have been carefully
+hand formatted by the programmer.
+In such cases,
+.Fl nfc1
+should be
+used.
+The default is
+.Fl fc1 .
+.It Fl fcb , nfcb
+Enables (disables) the formatting of block comments (ones that begin
+with `/*\\n').
+Often, block comments have been not so carefully hand formatted by the
+programmer, but reformatting that would just change the line breaks is not
+wanted.
+In such cases,
+.Fl nfcb
+should be used.
+Block comments are then handled like box comments.
+The default is
+.Fl fcb .
+.It Fl i Ns Ar n
+The number of spaces for one indentation level.
+The default is 8.
+.It Fl \&ip , nip
+Enables (disables) the indentation of parameter declarations from the left
+margin.
+The default is
+.Fl \&ip .
+.It Fl l Ns Ar n
+Maximum length of an output line.
+The default is 78.
+.It Fl \&ldi Ns Ar n
+Specifies the indentation, in character positions,
+of local variable names
+relative to the beginning of their type declaration.
+The default is for local variable names to be indented
+by the same amount as global ones.
+.It Fl \&lp , nlp
+Lines-up code surrounded by parenthesis in continuation lines.
+If a line
+has a left paren which is not closed on that line, then continuation lines
+will be lined up to start at the character position just after the left
+paren.
+For example, here is how a piece of continued code looks with
+.Fl nlp
+in effect:
+.Bd -literal -offset indent
+p1 = first_procedure(second_procedure(p2, p3),
+\ \ third_procedure(p4, p5));
+.Ed
+.Pp
+With
+.Fl lp
+in effect (the default) the code looks somewhat clearer:
+.Bd -literal -offset indent
+p1\ =\ first_procedure(second_procedure(p2,\ p3),
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,\ p5));
+.Ed
+.Pp
+Inserting two more newlines we get:
+.Bd -literal -offset indent
+p1\ =\ first_procedure(second_procedure(p2,
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3),
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5));
+.Ed
+.It Fl npro
+Causes the profile files,
+.Sq Pa ./.indent.pro
+and
+.Sq Pa ~/.indent.pro ,
+to be ignored.
+.It Fl pcs , npcs
+If true
+.Pq Fl pcs
+all procedure calls will have a space inserted between
+the name and the `('.
+The default is
+.Fl npcs .
+.It Fl psl , npsl
+If true
+.Pq Fl psl
+the names of procedures being defined are placed in
+column 1 \- their types, if any, will be left on the previous lines.
+The
+default is
+.Fl psl .
+.It Fl \&sc , nsc
+Enables (disables) the placement of asterisks (`*'s) at the left edge of all
+comments.
+The default is
+.Fl sc .
+.It Fl sob , nsob
+If
+.Fl sob
+is specified, indent will swallow optional blank lines.
+You can use this to
+get rid of blank lines after declarations.
+The default is
+.Fl nsob .
+.It Fl \&st
+Causes
+.Nm
+to take its input from stdin and put its output to stdout.
+.It Fl ta
+Automatically add all identifiers ending in "_t" to the list
+of type keywords.
+.It Fl T Ns Ar typename
+Adds
+.Ar typename
+to the list of type keywords.
+Names accumulate:
+.Fl T
+can be specified more than once.
+You need to specify all the typenames that
+appear in your program that are defined by
+.Ic typedef
+\- nothing will be
+harmed if you miss a few, but the program will not be formatted as nicely as
+it should.
+This sounds like a painful thing to have to do, but it is really
+a symptom of a problem in C:
+.Ic typedef
+causes a syntactic change in the
+language and
+.Nm
+cannot find all
+instances of
+.Ic typedef .
+.It Fl troff
+Causes
+.Nm
+to format the program for processing by
+.Xr troff 1 .
+.\" It will produce a fancy
+.\" listing in much the same spirit as
+.\" .Xr vgrind 1 .
+If the output file is not specified, the default is standard output,
+rather than formatting in place.
+.It Fl ut , nut
+Enables (disables) the use of tab characters in the output.
+Tabs are assumed to be aligned on columns divisible by 8.
+The default is
+.Fl ut .
+.It Fl v , \&nv
+.Fl v
+turns on `verbose' mode;
+.Fl \&nv
+turns it off.
+When in verbose mode,
+.Nm
+reports when it splits one line of input into two or more lines of output,
+and gives some size statistics at completion.
+The default is
+.Fl \&nv .
+.El
+.Pp
+You may set up your own `profile' of defaults to
+.Nm
+by creating a file called
+.Pa .indent.pro
+in your login directory and/or the current directory and including
+whatever switches you like.
+A `.indent.pro' in the current directory takes
+precedence over the one in your login directory.
+If
+.Nm
+is run and a profile file exists, then it is read to set up the program's
+defaults.
+Switches on the command line, though, always override profile
+switches.
+The switches should be separated by spaces, tabs or newlines.
+.Pp
+.Ss Comments
+.Sq Em Box
+.Em comments .
+.Nm
+assumes that any comment with a dash or star immediately after the start of
+comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars.
+Each line of such a comment is left unchanged, except that its indentation
+may be adjusted to account for the change in indentation of the first line
+of the comment.
+.Pp
+.Em Straight text .
+All other comments are treated as straight text.
+.Nm
+fits as many words (separated by blanks, tabs, or newlines) on a
+line as possible.
+Blank lines break paragraphs.
+.Pp
+.Ss Comment indentation
+If a comment is on a line with code it is started in the `comment column',
+which is set by the
+.Fl c Ns Ns Ar n
+command line parameter.
+Otherwise, the comment is started at
+.Ar n
+indentation levels less than where code is currently being placed, where
+.Ar n
+is specified by the
+.Fl d Ns Ns Ar n
+command line parameter.
+If the code on a line extends past the comment
+column, the comment starts further to the right, and the right margin may be
+automatically extended in extreme cases.
+.Pp
+.Ss Preprocessor lines
+In general,
+.Nm
+leaves preprocessor lines alone.
+The only
+reformatting that it will do is to straighten up trailing comments.
+It
+leaves embedded comments alone.
+Conditional compilation
+.Pq Ic #ifdef...#endif
+is recognized and
+.Nm
+attempts to correctly
+compensate for the syntactic peculiarities introduced.
+.Pp
+.Ss C syntax
+.Nm
+understands a substantial amount about the syntax of C, but it
+has a `forgiving' parser.
+It attempts to cope with the usual sorts of
+incomplete and misformed syntax.
+In particular, the use of macros like:
+.Pp
+.Dl #define forever for(;;)
+.Pp
+is handled properly.
+.Sh ENVIRONMENT
+.Nm
+uses the
+.Ev HOME
+environment variable.
+.Sh FILES
+.Bl -tag -width "./.indent.pro" -compact
+.It Pa ./.indent.pro
+profile file
+.It Pa ~/.indent.pro
+profile file
+.El
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+.Nm
+has even more switches than
+.Xr ls 1 .
+.Pp
+A common mistake that often causes grief is typing:
+.Pp
+.Dl indent *.c
+.Pp
+to the shell in an attempt to indent all the
+.Tn C
+programs in a directory.
+This is probably a bug, not a feature.
diff --git a/developer_cmds/indent/indent.c b/developer_cmds/indent/indent.c
new file mode 100644
index 0000000..b88118e
--- /dev/null
+++ b/developer_cmds/indent/indent.c
@@ -0,0 +1,1234 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1976 Board of Trustees of the University of Illinois.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\
+@(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\
+@(#) Copyright (c) 1980, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/indent.c,v 1.28 2011/12/30 11:02:40 uqs Exp $");
+
+#include <sys/param.h>
+#include <err.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "indent_globs.h"
+#include "indent_codes.h"
+#include "indent.h"
+
+static void bakcopy(void);
+
+const char *in_name = "Standard Input"; /* will always point to name of input
+ * file */
+const char *out_name = "Standard Output"; /* will always point to name
+ * of output file */
+char bakfile[MAXPATHLEN] = "";
+
+int
+main(int argc, char **argv)
+{
+
+ int dec_ind; /* current indentation for declarations */
+ int di_stack[20]; /* a stack of structure indentation levels */
+ int flushed_nl; /* used when buffering up comments to remember
+ * that a newline was passed over */
+ int force_nl; /* when true, code must be broken */
+ int hd_type = 0; /* used to store type of stmt for if (...),
+ * for (...), etc */
+ int i; /* local loop counter */
+ int scase; /* set to true when we see a case, so we will
+ * know what to do with the following colon */
+ int sp_sw; /* when true, we are in the expression of
+ * if(...), while(...), etc. */
+ int squest; /* when this is positive, we have seen a ?
+ * without the matching : in a <c>?<s>:<s>
+ * construct */
+ const char *t_ptr; /* used for copying tokens */
+ int tabs_to_var; /* true if using tabs to indent to var name */
+ int type_code; /* the type of token, returned by lexi */
+
+ int last_else = 0; /* true iff last keyword was an else */
+
+
+ /*-----------------------------------------------*\
+ | INITIALIZATION |
+ \*-----------------------------------------------*/
+
+ found_err = 0;
+
+ ps.p_stack[0] = stmt; /* this is the parser's stack */
+ ps.last_nl = true; /* this is true if the last thing scanned was
+ * a newline */
+ ps.last_token = semicolon;
+ combuf = (char *) malloc(bufsize);
+ if (combuf == NULL)
+ err(1, NULL);
+ labbuf = (char *) malloc(bufsize);
+ if (labbuf == NULL)
+ err(1, NULL);
+ codebuf = (char *) malloc(bufsize);
+ if (codebuf == NULL)
+ err(1, NULL);
+ tokenbuf = (char *) malloc(bufsize);
+ if (tokenbuf == NULL)
+ err(1, NULL);
+ l_com = combuf + bufsize - 5;
+ l_lab = labbuf + bufsize - 5;
+ l_code = codebuf + bufsize - 5;
+ l_token = tokenbuf + bufsize - 5;
+ combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and
+ * comment buffers */
+ combuf[1] = codebuf[1] = labbuf[1] = '\0';
+ ps.else_if = 1; /* Default else-if special processing to on */
+ s_lab = e_lab = labbuf + 1;
+ s_code = e_code = codebuf + 1;
+ s_com = e_com = combuf + 1;
+ s_token = e_token = tokenbuf + 1;
+
+ in_buffer = (char *) malloc(10);
+ if (in_buffer == NULL)
+ err(1, NULL);
+ in_buffer_limit = in_buffer + 8;
+ buf_ptr = buf_end = in_buffer;
+ line_no = 1;
+ had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
+ sp_sw = force_nl = false;
+ ps.in_or_st = false;
+ ps.bl_line = true;
+ dec_ind = 0;
+ di_stack[ps.dec_nest = 0] = 0;
+ ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
+
+ scase = ps.pcase = false;
+ squest = 0;
+ sc_end = 0;
+ bp_save = 0;
+ be_save = 0;
+
+ output = 0;
+ tabs_to_var = 0;
+
+ /*--------------------------------------------------*\
+ | COMMAND LINE SCAN |
+ \*--------------------------------------------------*/
+
+#ifdef undef
+ max_col = 78; /* -l78 */
+ lineup_to_parens = 1; /* -lp */
+ ps.ljust_decl = 0; /* -ndj */
+ ps.com_ind = 33; /* -c33 */
+ star_comment_cont = 1; /* -sc */
+ ps.ind_size = 8; /* -i8 */
+ verbose = 0;
+ ps.decl_indent = 16; /* -di16 */
+ ps.local_decl_indent = -1; /* if this is not set to some nonnegative value
+ * by an arg, we will set this equal to
+ * ps.decl_ind */
+ ps.indent_parameters = 1; /* -ip */
+ ps.decl_com_ind = 0; /* if this is not set to some positive value
+ * by an arg, we will set this equal to
+ * ps.com_ind */
+ btype_2 = 1; /* -br */
+ cuddle_else = 1; /* -ce */
+ ps.unindent_displace = 0; /* -d0 */
+ ps.case_indent = 0; /* -cli0 */
+ format_block_comments = 1; /* -fcb */
+ format_col1_comments = 1; /* -fc1 */
+ procnames_start_line = 1; /* -psl */
+ proc_calls_space = 0; /* -npcs */
+ comment_delimiter_on_blankline = 1; /* -cdb */
+ ps.leave_comma = 1; /* -nbc */
+#endif
+
+ for (i = 1; i < argc; ++i)
+ if (strcmp(argv[i], "-npro") == 0)
+ break;
+ set_defaults();
+ if (i >= argc)
+ set_profile();
+
+ for (i = 1; i < argc; ++i) {
+
+ /*
+ * look thru args (if any) for changes to defaults
+ */
+ if (argv[i][0] != '-') {/* no flag on parameter */
+ if (input == NULL) { /* we must have the input file */
+ in_name = argv[i]; /* remember name of input file */
+ input = fopen(in_name, "r");
+ if (input == NULL) /* check for open error */
+ err(1, "%s", in_name);
+ continue;
+ }
+ else if (output == NULL) { /* we have the output file */
+ out_name = argv[i]; /* remember name of output file */
+ if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite
+ * the file */
+ errx(1, "input and output files must be different");
+ }
+ output = fopen(out_name, "w");
+ if (output == NULL) /* check for create error */
+ err(1, "%s", out_name);
+ continue;
+ }
+ errx(1, "unknown parameter: %s", argv[i]);
+ }
+ else
+ set_option(argv[i]);
+ } /* end of for */
+ if (input == NULL)
+ input = stdin;
+ if (output == NULL) {
+ if (troff || input == stdin)
+ output = stdout;
+ else {
+ out_name = in_name;
+ bakcopy();
+ }
+ }
+ if (ps.com_ind <= 1)
+ ps.com_ind = 2; /* dont put normal comments before column 2 */
+ if (troff) {
+ if (bodyf.font[0] == 0)
+ parsefont(&bodyf, "R");
+ if (scomf.font[0] == 0)
+ parsefont(&scomf, "I");
+ if (blkcomf.font[0] == 0)
+ blkcomf = scomf, blkcomf.size += 2;
+ if (boxcomf.font[0] == 0)
+ boxcomf = blkcomf;
+ if (stringf.font[0] == 0)
+ parsefont(&stringf, "L");
+ if (keywordf.font[0] == 0)
+ parsefont(&keywordf, "B");
+ writefdef(&bodyf, 'B');
+ writefdef(&scomf, 'C');
+ writefdef(&blkcomf, 'L');
+ writefdef(&boxcomf, 'X');
+ writefdef(&stringf, 'S');
+ writefdef(&keywordf, 'K');
+ }
+ if (block_comment_max_col <= 0)
+ block_comment_max_col = max_col;
+ if (ps.local_decl_indent < 0) /* if not specified by user, set this */
+ ps.local_decl_indent = ps.decl_indent;
+ if (ps.decl_com_ind <= 0) /* if not specified by user, set this */
+ ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
+ if (continuation_indent == 0)
+ continuation_indent = ps.ind_size;
+ fill_buffer(); /* get first batch of stuff into input buffer */
+
+ parse(semicolon);
+ {
+ char *p = buf_ptr;
+ int col = 1;
+
+ while (1) {
+ if (*p == ' ')
+ col++;
+ else if (*p == '\t')
+ col = ((col - 1) & ~7) + 9;
+ else
+ break;
+ p++;
+ }
+ if (col > ps.ind_size)
+ ps.ind_level = ps.i_l_follow = col / ps.ind_size;
+ }
+ if (troff) {
+ const char *p = in_name,
+ *beg = in_name;
+
+ while (*p)
+ if (*p++ == '/')
+ beg = p;
+ fprintf(output, ".Fn \"%s\"\n", beg);
+ }
+ /*
+ * START OF MAIN LOOP
+ */
+
+ while (1) { /* this is the main loop. it will go until we
+ * reach eof */
+ int is_procname;
+
+ type_code = lexi(); /* lexi reads one token. The actual
+ * characters read are stored in "token". lexi
+ * returns a code indicating the type of token */
+ is_procname = ps.procname[0];
+
+ /*
+ * The following code moves everything following an if (), while (),
+ * else, etc. up to the start of the following stmt to a buffer. This
+ * allows proper handling of both kinds of brace placement.
+ */
+
+ flushed_nl = false;
+ while (ps.search_brace) { /* if we scanned an if(), while(),
+ * etc., we might need to copy stuff
+ * into a buffer we must loop, copying
+ * stuff into save_com, until we find
+ * the start of the stmt which follows
+ * the if, or whatever */
+ switch (type_code) {
+ case newline:
+ ++line_no;
+ flushed_nl = true;
+ case form_feed:
+ break; /* form feeds and newlines found here will be
+ * ignored */
+
+ case lbrace: /* this is a brace that starts the compound
+ * stmt */
+ if (sc_end == 0) { /* ignore buffering if a comment wasn't
+ * stored up */
+ ps.search_brace = false;
+ goto check_type;
+ }
+ if (btype_2) {
+ save_com[0] = '{'; /* we either want to put the brace
+ * right after the if */
+ goto sw_buffer; /* go to common code to get out of
+ * this loop */
+ }
+ case comment: /* we have a comment, so we must copy it into
+ * the buffer */
+ if (!flushed_nl || sc_end != 0) {
+ if (sc_end == 0) { /* if this is the first comment, we
+ * must set up the buffer */
+ save_com[0] = save_com[1] = ' ';
+ sc_end = &(save_com[2]);
+ }
+ else {
+ *sc_end++ = '\n'; /* add newline between
+ * comments */
+ *sc_end++ = ' ';
+ --line_no;
+ }
+ *sc_end++ = '/'; /* copy in start of comment */
+ *sc_end++ = '*';
+
+ for (;;) { /* loop until we get to the end of the comment */
+ *sc_end = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+
+ if (*sc_end++ == '*' && *buf_ptr == '/')
+ break; /* we are at end of comment */
+
+ if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer
+ * overflow */
+ diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever");
+ fflush(output);
+ exit(1);
+ }
+ }
+ *sc_end++ = '/'; /* add ending slash */
+ if (++buf_ptr >= buf_end) /* get past / in buffer */
+ fill_buffer();
+ break;
+ }
+ default: /* it is the start of a normal statement */
+ if (flushed_nl) /* if we flushed a newline, make sure it is
+ * put back */
+ force_nl = true;
+ if ((type_code == sp_paren && *token == 'i'
+ && last_else && ps.else_if)
+ || (type_code == sp_nparen && *token == 'e'
+ && e_code != s_code && e_code[-1] == '}'))
+ force_nl = false;
+
+ if (sc_end == 0) { /* ignore buffering if comment wasn't
+ * saved up */
+ ps.search_brace = false;
+ goto check_type;
+ }
+ if (force_nl) { /* if we should insert a nl here, put it into
+ * the buffer */
+ force_nl = false;
+ --line_no; /* this will be re-increased when the nl is
+ * read from the buffer */
+ *sc_end++ = '\n';
+ *sc_end++ = ' ';
+ if (verbose && !flushed_nl) /* print error msg if the line
+ * was not already broken */
+ diag2(0, "Line broken");
+ flushed_nl = false;
+ }
+ for (t_ptr = token; *t_ptr; ++t_ptr)
+ *sc_end++ = *t_ptr; /* copy token into temp buffer */
+ ps.procname[0] = 0;
+
+ sw_buffer:
+ ps.search_brace = false; /* stop looking for start of
+ * stmt */
+ bp_save = buf_ptr; /* save current input buffer */
+ be_save = buf_end;
+ buf_ptr = save_com; /* fix so that subsequent calls to
+ * lexi will take tokens out of
+ * save_com */
+ *sc_end++ = ' ';/* add trailing blank, just in case */
+ buf_end = sc_end;
+ sc_end = 0;
+ break;
+ } /* end of switch */
+ if (type_code != 0) /* we must make this check, just in case there
+ * was an unexpected EOF */
+ type_code = lexi(); /* read another token */
+ /* if (ps.search_brace) ps.procname[0] = 0; */
+ if ((is_procname = ps.procname[0]) && flushed_nl
+ && !procnames_start_line && ps.in_decl
+ && type_code == ident)
+ flushed_nl = 0;
+ } /* end of while (search_brace) */
+ last_else = 0;
+check_type:
+ if (type_code == 0) { /* we got eof */
+ if (s_lab != e_lab || s_code != e_code
+ || s_com != e_com) /* must dump end of line */
+ dump_line();
+ if (ps.tos > 1) /* check for balanced braces */
+ diag2(1, "Stuff missing from end of file");
+
+ if (verbose) {
+ printf("There were %d output lines and %d comments\n",
+ ps.out_lines, ps.out_coms);
+ printf("(Lines with comments)/(Lines with code): %6.3f\n",
+ (1.0 * ps.com_lines) / code_lines);
+ }
+ fflush(output);
+ exit(found_err);
+ }
+ if (
+ (type_code != comment) &&
+ (type_code != newline) &&
+ (type_code != preesc) &&
+ (type_code != form_feed)) {
+ if (force_nl &&
+ (type_code != semicolon) &&
+ (type_code != lbrace || !btype_2)) {
+ /* we should force a broken line here */
+ if (verbose && !flushed_nl)
+ diag2(0, "Line broken");
+ flushed_nl = false;
+ dump_line();
+ ps.want_blank = false; /* dont insert blank at line start */
+ force_nl = false;
+ }
+ ps.in_stmt = true; /* turn on flag which causes an extra level of
+ * indentation. this is turned off by a ; or
+ * '}' */
+ if (s_com != e_com) { /* the turkey has embedded a comment
+ * in a line. fix it */
+ *e_code++ = ' ';
+ for (t_ptr = s_com; *t_ptr; ++t_ptr) {
+ CHECK_SIZE_CODE;
+ *e_code++ = *t_ptr;
+ }
+ *e_code++ = ' ';
+ *e_code = '\0'; /* null terminate code sect */
+ ps.want_blank = false;
+ e_com = s_com;
+ }
+ }
+ else if (type_code != comment) /* preserve force_nl thru a comment */
+ force_nl = false; /* cancel forced newline after newline, form
+ * feed, etc */
+
+
+
+ /*-----------------------------------------------------*\
+ | do switch on type of token scanned |
+ \*-----------------------------------------------------*/
+ CHECK_SIZE_CODE;
+ switch (type_code) { /* now, decide what to do with the token */
+
+ case form_feed: /* found a form feed in line */
+ ps.use_ff = true; /* a form feed is treated much like a newline */
+ dump_line();
+ ps.want_blank = false;
+ break;
+
+ case newline:
+ if (ps.last_token != comma || ps.p_l_follow > 0
+ || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
+ dump_line();
+ ps.want_blank = false;
+ }
+ ++line_no; /* keep track of input line number */
+ break;
+
+ case lparen: /* got a '(' or '[' */
+ ++ps.p_l_follow; /* count parens to make Healy happy */
+ if (ps.want_blank && *token != '[' &&
+ (ps.last_token != ident || proc_calls_space
+ || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon))))
+ *e_code++ = ' ';
+ if (ps.in_decl && !ps.block_init)
+ if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) {
+ ps.dumped_decl_indent = 1;
+ sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
+ e_code += strlen(e_code);
+ }
+ else {
+ while ((e_code - s_code) < dec_ind) {
+ CHECK_SIZE_CODE;
+ *e_code++ = ' ';
+ }
+ *e_code++ = token[0];
+ }
+ else
+ *e_code++ = token[0];
+ ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
+ if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent
+ && ps.paren_indents[0] < 2 * ps.ind_size)
+ ps.paren_indents[0] = 2 * ps.ind_size;
+ ps.want_blank = false;
+ if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
+ /*
+ * this is a kluge to make sure that declarations will be
+ * aligned right if proc decl has an explicit type on it, i.e.
+ * "int a(x) {..."
+ */
+ parse(semicolon); /* I said this was a kluge... */
+ ps.in_or_st = false; /* turn off flag for structure decl or
+ * initialization */
+ }
+ if (ps.sizeof_keyword)
+ ps.sizeof_mask |= 1 << ps.p_l_follow;
+ break;
+
+ case rparen: /* got a ')' or ']' */
+ rparen_count--;
+ if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
+ ps.last_u_d = true;
+ ps.cast_mask &= (1 << ps.p_l_follow) - 1;
+ ps.want_blank = false;
+ } else
+ ps.want_blank = true;
+ ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
+ if (--ps.p_l_follow < 0) {
+ ps.p_l_follow = 0;
+ diag3(0, "Extra %c", *token);
+ }
+ if (e_code == s_code) /* if the paren starts the line */
+ ps.paren_level = ps.p_l_follow; /* then indent it */
+
+ *e_code++ = token[0];
+
+ if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
+ * (...), or some such */
+ sp_sw = false;
+ force_nl = true;/* must force newline after if */
+ ps.last_u_d = true; /* inform lexi that a following
+ * operator is unary */
+ ps.in_stmt = false; /* dont use stmt continuation
+ * indentation */
+
+ parse(hd_type); /* let parser worry about if, or whatever */
+ }
+ ps.search_brace = btype_2; /* this should insure that constructs
+ * such as main(){...} and int[]{...}
+ * have their braces put in the right
+ * place */
+ break;
+
+ case unary_op: /* this could be any unary operation */
+ if (ps.want_blank)
+ *e_code++ = ' ';
+
+ if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) {
+ sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
+ ps.dumped_decl_indent = 1;
+ e_code += strlen(e_code);
+ }
+ else {
+ const char *res = token;
+
+ if (ps.in_decl && !ps.block_init) { /* if this is a unary op
+ * in a declaration, we
+ * should indent this
+ * token */
+ for (i = 0; token[i]; ++i); /* find length of token */
+ while ((e_code - s_code) < (dec_ind - i)) {
+ CHECK_SIZE_CODE;
+ *e_code++ = ' '; /* pad it */
+ }
+ }
+ if (troff && token[0] == '-' && token[1] == '>')
+ res = "\\(->";
+ for (t_ptr = res; *t_ptr; ++t_ptr) {
+ CHECK_SIZE_CODE;
+ *e_code++ = *t_ptr;
+ }
+ }
+ ps.want_blank = false;
+ break;
+
+ case binary_op: /* any binary operation */
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ {
+ const char *res = token;
+
+ if (troff)
+ switch (token[0]) {
+ case '<':
+ if (token[1] == '=')
+ res = "\\(<=";
+ break;
+ case '>':
+ if (token[1] == '=')
+ res = "\\(>=";
+ break;
+ case '!':
+ if (token[1] == '=')
+ res = "\\(!=";
+ break;
+ case '|':
+ if (token[1] == '|')
+ res = "\\(br\\(br";
+ else if (token[1] == 0)
+ res = "\\(br";
+ break;
+ }
+ for (t_ptr = res; *t_ptr; ++t_ptr) {
+ CHECK_SIZE_CODE;
+ *e_code++ = *t_ptr; /* move the operator */
+ }
+ }
+ ps.want_blank = true;
+ break;
+
+ case postop: /* got a trailing ++ or -- */
+ *e_code++ = token[0];
+ *e_code++ = token[1];
+ ps.want_blank = true;
+ break;
+
+ case question: /* got a ? */
+ squest++; /* this will be used when a later colon
+ * appears so we can distinguish the
+ * <c>?<n>:<n> construct */
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ *e_code++ = '?';
+ ps.want_blank = true;
+ break;
+
+ case casestmt: /* got word 'case' or 'default' */
+ scase = true; /* so we can process the later colon properly */
+ goto copy_id;
+
+ case colon: /* got a ':' */
+ if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */
+ --squest;
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ *e_code++ = ':';
+ ps.want_blank = true;
+ break;
+ }
+ if (ps.in_or_st) {
+ *e_code++ = ':';
+ ps.want_blank = false;
+ break;
+ }
+ ps.in_stmt = false; /* seeing a label does not imply we are in a
+ * stmt */
+ for (t_ptr = s_code; *t_ptr; ++t_ptr)
+ *e_lab++ = *t_ptr; /* turn everything so far into a label */
+ e_code = s_code;
+ *e_lab++ = ':';
+ *e_lab++ = ' ';
+ *e_lab = '\0';
+
+ force_nl = ps.pcase = scase; /* ps.pcase will be used by
+ * dump_line to decide how to
+ * indent the label. force_nl
+ * will force a case n: to be
+ * on a line by itself */
+ scase = false;
+ ps.want_blank = false;
+ break;
+
+ case semicolon: /* got a ';' */
+ ps.in_or_st = false;/* we are not in an initialization or
+ * structure declaration */
+ scase = false; /* these will only need resetting in an error */
+ squest = 0;
+ if (ps.last_token == rparen && rparen_count == 0)
+ ps.in_parameter_declaration = 0;
+ ps.cast_mask = 0;
+ ps.sizeof_mask = 0;
+ ps.block_init = 0;
+ ps.block_init_level = 0;
+ ps.just_saw_decl--;
+
+ if (ps.in_decl && s_code == e_code && !ps.block_init)
+ while ((e_code - s_code) < (dec_ind - 1)) {
+ CHECK_SIZE_CODE;
+ *e_code++ = ' ';
+ }
+
+ ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level
+ * structure declaration, we
+ * arent any more */
+
+ if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
+
+ /*
+ * This should be true iff there were unbalanced parens in the
+ * stmt. It is a bit complicated, because the semicolon might
+ * be in a for stmt
+ */
+ diag2(1, "Unbalanced parens");
+ ps.p_l_follow = 0;
+ if (sp_sw) { /* this is a check for an if, while, etc. with
+ * unbalanced parens */
+ sp_sw = false;
+ parse(hd_type); /* dont lose the if, or whatever */
+ }
+ }
+ *e_code++ = ';';
+ ps.want_blank = true;
+ ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
+ * middle of a stmt */
+
+ if (!sp_sw) { /* if not if for (;;) */
+ parse(semicolon); /* let parser know about end of stmt */
+ force_nl = true;/* force newline after an end of stmt */
+ }
+ break;
+
+ case lbrace: /* got a '{' */
+ ps.in_stmt = false; /* dont indent the {} */
+ if (!ps.block_init)
+ force_nl = true;/* force other stuff on same line as '{' onto
+ * new line */
+ else if (ps.block_init_level <= 0)
+ ps.block_init_level = 1;
+ else
+ ps.block_init_level++;
+
+ if (s_code != e_code && !ps.block_init) {
+ if (!btype_2) {
+ dump_line();
+ ps.want_blank = false;
+ }
+ else if (ps.in_parameter_declaration && !ps.in_or_st) {
+ ps.i_l_follow = 0;
+ if (function_brace_split) { /* dump the line prior to the
+ * brace ... */
+ dump_line();
+ ps.want_blank = false;
+ } else /* add a space between the decl and brace */
+ ps.want_blank = true;
+ }
+ }
+ if (ps.in_parameter_declaration)
+ prefix_blankline_requested = 0;
+
+ if (ps.p_l_follow > 0) { /* check for preceding unbalanced
+ * parens */
+ diag2(1, "Unbalanced parens");
+ ps.p_l_follow = 0;
+ if (sp_sw) { /* check for unclosed if, for, etc. */
+ sp_sw = false;
+ parse(hd_type);
+ ps.ind_level = ps.i_l_follow;
+ }
+ }
+ if (s_code == e_code)
+ ps.ind_stmt = false; /* dont put extra indentation on line
+ * with '{' */
+ if (ps.in_decl && ps.in_or_st) { /* this is either a structure
+ * declaration or an init */
+ di_stack[ps.dec_nest++] = dec_ind;
+ /* ? dec_ind = 0; */
+ }
+ else {
+ ps.decl_on_line = false; /* we can't be in the middle of
+ * a declaration, so don't do
+ * special indentation of
+ * comments */
+ if (blanklines_after_declarations_at_proctop
+ && ps.in_parameter_declaration)
+ postfix_blankline_requested = 1;
+ ps.in_parameter_declaration = 0;
+ }
+ dec_ind = 0;
+ parse(lbrace); /* let parser know about this */
+ if (ps.want_blank) /* put a blank before '{' if '{' is not at
+ * start of line */
+ *e_code++ = ' ';
+ ps.want_blank = false;
+ *e_code++ = '{';
+ ps.just_saw_decl = 0;
+ break;
+
+ case rbrace: /* got a '}' */
+ if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be
+ * omitted in
+ * declarations */
+ parse(semicolon);
+ if (ps.p_l_follow) {/* check for unclosed if, for, else. */
+ diag2(1, "Unbalanced parens");
+ ps.p_l_follow = 0;
+ sp_sw = false;
+ }
+ ps.just_saw_decl = 0;
+ ps.block_init_level--;
+ if (s_code != e_code && !ps.block_init) { /* '}' must be first on
+ * line */
+ if (verbose)
+ diag2(0, "Line broken");
+ dump_line();
+ }
+ *e_code++ = '}';
+ ps.want_blank = true;
+ ps.in_stmt = ps.ind_stmt = false;
+ if (ps.dec_nest > 0) { /* we are in multi-level structure
+ * declaration */
+ dec_ind = di_stack[--ps.dec_nest];
+ if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
+ ps.just_saw_decl = 2;
+ ps.in_decl = true;
+ }
+ prefix_blankline_requested = 0;
+ parse(rbrace); /* let parser know about this */
+ ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead
+ && ps.il[ps.tos] >= ps.ind_level;
+ if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
+ postfix_blankline_requested = 1;
+ break;
+
+ case swstmt: /* got keyword "switch" */
+ sp_sw = true;
+ hd_type = swstmt; /* keep this for when we have seen the
+ * expression */
+ goto copy_id; /* go move the token into buffer */
+
+ case sp_paren: /* token is if, while, for */
+ sp_sw = true; /* the interesting stuff is done after the
+ * expression is scanned */
+ hd_type = (*token == 'i' ? ifstmt :
+ (*token == 'w' ? whilestmt : forstmt));
+
+ /*
+ * remember the type of header for later use by parser
+ */
+ goto copy_id; /* copy the token into line */
+
+ case sp_nparen: /* got else, do */
+ ps.in_stmt = false;
+ if (*token == 'e') {
+ if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
+ if (verbose)
+ diag2(0, "Line broken");
+ dump_line();/* make sure this starts a line */
+ ps.want_blank = false;
+ }
+ force_nl = true;/* also, following stuff must go onto new line */
+ last_else = 1;
+ parse(elselit);
+ }
+ else {
+ if (e_code != s_code) { /* make sure this starts a line */
+ if (verbose)
+ diag2(0, "Line broken");
+ dump_line();
+ ps.want_blank = false;
+ }
+ force_nl = true;/* also, following stuff must go onto new line */
+ last_else = 0;
+ parse(dolit);
+ }
+ goto copy_id; /* move the token into line */
+
+ case decl: /* we have a declaration type (int, register,
+ * etc.) */
+ parse(decl); /* let parser worry about indentation */
+ if (ps.last_token == rparen && ps.tos <= 1) {
+ ps.in_parameter_declaration = 1;
+ if (s_code != e_code) {
+ dump_line();
+ ps.want_blank = 0;
+ }
+ }
+ if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
+ ps.ind_level = ps.i_l_follow = 1;
+ ps.ind_stmt = 0;
+ }
+ ps.in_or_st = true; /* this might be a structure or initialization
+ * declaration */
+ ps.in_decl = ps.decl_on_line = true;
+ if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
+ ps.just_saw_decl = 2;
+ prefix_blankline_requested = 0;
+ for (i = 0; token[i++];); /* get length of token */
+
+ if (ps.ind_level == 0 || ps.dec_nest > 0) {
+ /* global variable or struct member in local variable */
+ dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
+ tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0);
+ } else {
+ /* local variable */
+ dec_ind = ps.local_decl_indent > 0 ? ps.local_decl_indent : i;
+ tabs_to_var = (use_tabs ? ps.local_decl_indent > 0 : 0);
+ }
+ goto copy_id;
+
+ case ident: /* got an identifier or constant */
+ if (ps.in_decl) { /* if we are in a declaration, we must indent
+ * identifier */
+ if (is_procname == 0 || !procnames_start_line) {
+ if (!ps.block_init) {
+ if (troff && !ps.dumped_decl_indent) {
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ ps.want_blank = false;
+ sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7);
+ ps.dumped_decl_indent = 1;
+ e_code += strlen(e_code);
+ } else {
+ int cur_dec_ind;
+ int pos, startpos;
+
+ /*
+ * in order to get the tab math right for
+ * indentations that are not multiples of 8 we
+ * need to modify both startpos and dec_ind
+ * (cur_dec_ind) here by eight minus the
+ * remainder of the current starting column
+ * divided by eight. This seems to be a
+ * properly working fix
+ */
+ startpos = e_code - s_code;
+ cur_dec_ind = dec_ind;
+ pos = startpos;
+ if ((ps.ind_level * ps.ind_size) % 8 != 0) {
+ pos += (ps.ind_level * ps.ind_size) % 8;
+ cur_dec_ind += (ps.ind_level * ps.ind_size) % 8;
+ }
+
+ if (tabs_to_var) {
+ while ((pos & ~7) + 8 <= cur_dec_ind) {
+ CHECK_SIZE_CODE;
+ *e_code++ = '\t';
+ pos = (pos & ~7) + 8;
+ }
+ }
+ while (pos < cur_dec_ind) {
+ CHECK_SIZE_CODE;
+ *e_code++ = ' ';
+ pos++;
+ }
+ if (ps.want_blank && e_code - s_code == startpos)
+ *e_code++ = ' ';
+ ps.want_blank = false;
+ }
+ }
+ } else {
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ ps.want_blank = false;
+ if (dec_ind && s_code != e_code)
+ dump_line();
+ dec_ind = 0;
+ }
+ }
+ else if (sp_sw && ps.p_l_follow == 0) {
+ sp_sw = false;
+ force_nl = true;
+ ps.last_u_d = true;
+ ps.in_stmt = false;
+ parse(hd_type);
+ }
+ copy_id:
+ if (ps.want_blank)
+ *e_code++ = ' ';
+ if (troff && ps.its_a_keyword) {
+ e_code = chfont(&bodyf, &keywordf, e_code);
+ for (t_ptr = token; *t_ptr; ++t_ptr) {
+ CHECK_SIZE_CODE;
+ *e_code++ = keywordf.allcaps && islower(*t_ptr)
+ ? toupper(*t_ptr) : *t_ptr;
+ }
+ e_code = chfont(&keywordf, &bodyf, e_code);
+ }
+ else
+ for (t_ptr = token; *t_ptr; ++t_ptr) {
+ CHECK_SIZE_CODE;
+ *e_code++ = *t_ptr;
+ }
+ ps.want_blank = true;
+ break;
+
+ case period: /* treat a period kind of like a binary
+ * operation */
+ *e_code++ = '.'; /* move the period into line */
+ ps.want_blank = false; /* dont put a blank after a period */
+ break;
+
+ case comma:
+ ps.want_blank = (s_code != e_code); /* only put blank after comma
+ * if comma does not start the
+ * line */
+ if (ps.in_decl && is_procname == 0 && !ps.block_init)
+ while ((e_code - s_code) < (dec_ind - 1)) {
+ CHECK_SIZE_CODE;
+ *e_code++ = ' ';
+ }
+
+ *e_code++ = ',';
+ if (ps.p_l_follow == 0) {
+ if (ps.block_init_level <= 0)
+ ps.block_init = 0;
+ if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8))
+ force_nl = true;
+ }
+ break;
+
+ case preesc: /* got the character '#' */
+ if ((s_com != e_com) ||
+ (s_lab != e_lab) ||
+ (s_code != e_code))
+ dump_line();
+ *e_lab++ = '#'; /* move whole line to 'label' buffer */
+ {
+ int in_comment = 0;
+ int com_start = 0;
+ char quote = 0;
+ int com_end = 0;
+
+ while (*buf_ptr == ' ' || *buf_ptr == '\t') {
+ buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ while (*buf_ptr != '\n' || (in_comment && !had_eof)) {
+ CHECK_SIZE_LAB;
+ *e_lab = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ switch (*e_lab++) {
+ case BACKSLASH:
+ if (troff)
+ *e_lab++ = BACKSLASH;
+ if (!in_comment) {
+ *e_lab++ = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ break;
+ case '/':
+ if (*buf_ptr == '*' && !in_comment && !quote) {
+ in_comment = 1;
+ *e_lab++ = *buf_ptr++;
+ com_start = e_lab - s_lab - 2;
+ }
+ break;
+ case '"':
+ if (quote == '"')
+ quote = 0;
+ break;
+ case '\'':
+ if (quote == '\'')
+ quote = 0;
+ break;
+ case '*':
+ if (*buf_ptr == '/' && in_comment) {
+ in_comment = 0;
+ *e_lab++ = *buf_ptr++;
+ com_end = e_lab - s_lab;
+ }
+ break;
+ }
+ }
+
+ while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
+ e_lab--;
+ if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on
+ * preprocessor line */
+ if (sc_end == 0) /* if this is the first comment, we
+ * must set up the buffer */
+ sc_end = &(save_com[0]);
+ else {
+ *sc_end++ = '\n'; /* add newline between
+ * comments */
+ *sc_end++ = ' ';
+ --line_no;
+ }
+ bcopy(s_lab + com_start, sc_end, com_end - com_start);
+ sc_end += com_end - com_start;
+ if (sc_end >= &save_com[sc_size])
+ abort();
+ e_lab = s_lab + com_start;
+ while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
+ e_lab--;
+ bp_save = buf_ptr; /* save current input buffer */
+ be_save = buf_end;
+ buf_ptr = save_com; /* fix so that subsequent calls to
+ * lexi will take tokens out of
+ * save_com */
+ *sc_end++ = ' '; /* add trailing blank, just in case */
+ buf_end = sc_end;
+ sc_end = 0;
+ }
+ *e_lab = '\0'; /* null terminate line */
+ ps.pcase = false;
+ }
+
+ if (strncmp(s_lab, "#if", 3) == 0) {
+ if (blanklines_around_conditional_compilation) {
+ int c;
+ prefix_blankline_requested++;
+ while ((c = getc(input)) == '\n');
+ ungetc(c, input);
+ }
+ if ((size_t)ifdef_level < sizeof(state_stack)/sizeof(state_stack[0])) {
+ match_state[ifdef_level].tos = -1;
+ state_stack[ifdef_level++] = ps;
+ }
+ else
+ diag2(1, "#if stack overflow");
+ }
+ else if (strncmp(s_lab, "#else", 5) == 0)
+ if (ifdef_level <= 0)
+ diag2(1, "Unmatched #else");
+ else {
+ match_state[ifdef_level - 1] = ps;
+ ps = state_stack[ifdef_level - 1];
+ }
+ else if (strncmp(s_lab, "#endif", 6) == 0) {
+ if (ifdef_level <= 0)
+ diag2(1, "Unmatched #endif");
+ else {
+ ifdef_level--;
+
+#ifdef undef
+ /*
+ * This match needs to be more intelligent before the
+ * message is useful
+ */
+ if (match_state[ifdef_level].tos >= 0
+ && bcmp(&ps, &match_state[ifdef_level], sizeof ps))
+ diag2(0, "Syntactically inconsistent #ifdef alternatives");
+#endif
+ }
+ if (blanklines_around_conditional_compilation) {
+ postfix_blankline_requested++;
+ n_real_blanklines = 0;
+ }
+ }
+ break; /* subsequent processing of the newline
+ * character will cause the line to be printed */
+
+ case comment: /* we have gotten a / followed by * this is a biggie */
+ if (flushed_nl) { /* we should force a broken line here */
+ flushed_nl = false;
+ dump_line();
+ ps.want_blank = false; /* dont insert blank at line start */
+ force_nl = false;
+ }
+ pr_comment();
+ break;
+ } /* end of big switch stmt */
+
+ *e_code = '\0'; /* make sure code section is null terminated */
+ if (type_code != comment && type_code != newline && type_code != preesc)
+ ps.last_token = type_code;
+ } /* end of main while (1) loop */
+}
+
+/*
+ * copy input file to backup file if in_name is /blah/blah/blah/file, then
+ * backup file will be ".Bfile" then make the backup file the input and
+ * original input file the output
+ */
+static void
+bakcopy(void)
+{
+ int n,
+ bakchn;
+ char buff[8 * 1024];
+ const char *p;
+
+ /* construct file name .Bfile */
+ for (p = in_name; *p; p++); /* skip to end of string */
+ while (p > in_name && *p != '/') /* find last '/' */
+ p--;
+ if (*p == '/')
+ p++;
+ sprintf(bakfile, "%s.BAK", p);
+
+ /* copy in_name to backup file */
+ bakchn = creat(bakfile, 0600);
+ if (bakchn < 0)
+ err(1, "%s", bakfile);
+ while ((n = read(fileno(input), buff, sizeof buff)) != 0)
+ if (write(bakchn, buff, n) != n)
+ err(1, "%s", bakfile);
+ if (n < 0)
+ err(1, "%s", in_name);
+ close(bakchn);
+ fclose(input);
+
+ /* re-open backup file as the input file */
+ input = fopen(bakfile, "r");
+ if (input == NULL)
+ err(1, "%s", bakfile);
+ /* now the original input file will be the output */
+ output = fopen(in_name, "w");
+ if (output == NULL) {
+ unlink(bakfile);
+ err(1, "%s", in_name);
+ }
+}
diff --git a/developer_cmds/indent/indent.h b/developer_cmds/indent/indent.h
new file mode 100644
index 0000000..ac40f01
--- /dev/null
+++ b/developer_cmds/indent/indent.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001 Jens Schweikhardt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+__FBSDID("$FreeBSD: src/usr.bin/indent/indent.h,v 1.2 2002/03/30 17:10:20 dwmalone Exp $");
+#endif
+
+void addkey(char *, int);
+int compute_code_target(void);
+int compute_label_target(void);
+int count_spaces(int, char *);
+int lexi(void);
+void diag2(int, const char *);
+void diag3(int, const char *, int);
+void diag4(int, const char *, int, int);
+void dump_line(void);
+void fill_buffer(void);
+void parse(int);
+void parsefont(struct fstate *, const char *);
+void pr_comment(void);
+void set_defaults(void);
+void set_option(char *);
+void set_profile(void);
+void writefdef(struct fstate *f, int);
diff --git a/developer_cmds/indent/indent_codes.h b/developer_cmds/indent/indent_codes.h
new file mode 100644
index 0000000..008bf2b
--- /dev/null
+++ b/developer_cmds/indent/indent_codes.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
+ * $FreeBSD: src/usr.bin/indent/indent_codes.h,v 1.2 2000/12/09 09:52:51 obrien Exp $
+ */
+
+#define newline 1
+#define lparen 2
+#define rparen 3
+#define unary_op 4
+#define binary_op 5
+#define postop 6
+#define question 7
+#define casestmt 8
+#define colon 9
+#define semicolon 10
+#define lbrace 11
+#define rbrace 12
+#define ident 13
+#define comma 14
+#define comment 15
+#define swstmt 16
+#define preesc 17
+#define form_feed 18
+#define decl 19
+#define sp_paren 20
+#define sp_nparen 21
+#define ifstmt 22
+#define whilestmt 23
+#define forstmt 24
+#define stmt 25
+#define stmtl 26
+#define elselit 27
+#define dolit 28
+#define dohead 29
+#define ifhead 30
+#define elsehead 31
+#define period 32
diff --git a/developer_cmds/indent/indent_globs.h b/developer_cmds/indent/indent_globs.h
new file mode 100644
index 0000000..3ff82fa
--- /dev/null
+++ b/developer_cmds/indent/indent_globs.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
+ * $FreeBSD: src/usr.bin/indent/indent_globs.h,v 1.12 2010/03/31 17:05:30 avg Exp $
+ */
+
+#define BACKSLASH '\\'
+#define bufsize 200 /* size of internal buffers */
+#define sc_size 5000 /* size of save_com buffer */
+#define label_offset 2 /* number of levels a label is placed to left
+ * of code */
+
+#define tabsize 8 /* the size of a tab */
+#define tabmask 0177770 /* mask used when figuring length of lines
+ * with tabs */
+
+
+#define false 0
+#define true 1
+
+
+FILE *input; /* the fid for the input file */
+FILE *output; /* the output file */
+
+#define CHECK_SIZE_CODE \
+ if (e_code >= l_code) { \
+ int nsize = l_code-s_code+400; \
+ codebuf = (char *) realloc(codebuf, nsize); \
+ if (codebuf == NULL) \
+ err(1, NULL); \
+ e_code = codebuf + (e_code-s_code) + 1; \
+ l_code = codebuf + nsize - 5; \
+ s_code = codebuf + 1; \
+ }
+#define CHECK_SIZE_COM \
+ if (e_com >= l_com) { \
+ int nsize = l_com-s_com+400; \
+ combuf = (char *) realloc(combuf, nsize); \
+ if (combuf == NULL) \
+ err(1, NULL); \
+ e_com = combuf + (e_com-s_com) + 1; \
+ l_com = combuf + nsize - 5; \
+ s_com = combuf + 1; \
+ }
+#define CHECK_SIZE_LAB \
+ if (e_lab >= l_lab) { \
+ int nsize = l_lab-s_lab+400; \
+ labbuf = (char *) realloc(labbuf, nsize); \
+ if (labbuf == NULL) \
+ err(1, NULL); \
+ e_lab = labbuf + (e_lab-s_lab) + 1; \
+ l_lab = labbuf + nsize - 5; \
+ s_lab = labbuf + 1; \
+ }
+#define CHECK_SIZE_TOKEN \
+ if (e_token >= l_token) { \
+ int nsize = l_token-s_token+400; \
+ tokenbuf = (char *) realloc(tokenbuf, nsize); \
+ if (tokenbuf == NULL) \
+ err(1, NULL); \
+ e_token = tokenbuf + (e_token-s_token) + 1; \
+ l_token = tokenbuf + nsize - 5; \
+ s_token = tokenbuf + 1; \
+ }
+
+char *labbuf; /* buffer for label */
+char *s_lab; /* start ... */
+char *e_lab; /* .. and end of stored label */
+char *l_lab; /* limit of label buffer */
+
+char *codebuf; /* buffer for code section */
+char *s_code; /* start ... */
+char *e_code; /* .. and end of stored code */
+char *l_code; /* limit of code section */
+
+char *combuf; /* buffer for comments */
+char *s_com; /* start ... */
+char *e_com; /* ... and end of stored comments */
+char *l_com; /* limit of comment buffer */
+
+#define token s_token
+char *tokenbuf; /* the last token scanned */
+char *s_token;
+char *e_token;
+char *l_token;
+
+char *in_buffer; /* input buffer */
+char *in_buffer_limit; /* the end of the input buffer */
+char *buf_ptr; /* ptr to next character to be taken from
+ * in_buffer */
+char *buf_end; /* ptr to first after last char in in_buffer */
+
+char save_com[sc_size]; /* input text is saved here when looking for
+ * the brace after an if, while, etc */
+char *sc_end; /* pointer into save_com buffer */
+
+char *bp_save; /* saved value of buf_ptr when taking input
+ * from save_com */
+char *be_save; /* similarly saved value of buf_end */
+
+
+int found_err;
+int pointer_as_binop;
+int blanklines_after_declarations;
+int blanklines_before_blockcomments;
+int blanklines_after_procs;
+int blanklines_around_conditional_compilation;
+int swallow_optional_blanklines;
+int n_real_blanklines;
+int prefix_blankline_requested;
+int postfix_blankline_requested;
+int break_comma; /* when true and not in parens, break after a
+ * comma */
+int btype_2; /* when true, brace should be on same line as
+ * if, while, etc */
+float case_ind; /* indentation level to be used for a "case
+ * n:" */
+int code_lines; /* count of lines with code */
+int had_eof; /* set to true when input is exhausted */
+int line_no; /* the current line number. */
+int max_col; /* the maximum allowable line length */
+int verbose; /* when true, non-essential error messages are
+ * printed */
+int cuddle_else; /* true if else should cuddle up to '}' */
+int star_comment_cont; /* true iff comment continuation lines should
+ * have stars at the beginning of each line. */
+int comment_delimiter_on_blankline;
+int troff; /* true iff were generating troff input */
+int procnames_start_line; /* if true, the names of procedures
+ * being defined get placed in column
+ * 1 (ie. a newline is placed between
+ * the type of the procedure and its
+ * name) */
+int proc_calls_space; /* If true, procedure calls look like:
+ * foo(bar) rather than foo (bar) */
+int format_block_comments; /* true if comments beginning with
+ * `/ * \n' are to be reformatted */
+int format_col1_comments; /* If comments which start in column 1
+ * are to be magically reformatted
+ * (just like comments that begin in
+ * later columns) */
+int inhibit_formatting; /* true if INDENT OFF is in effect */
+int suppress_blanklines;/* set iff following blanklines should be
+ * suppressed */
+int continuation_indent;/* set to the indentation between the edge of
+ * code and continuation lines */
+int lineup_to_parens; /* if true, continued code within parens will
+ * be lined up to the open paren */
+int Bill_Shannon; /* true iff a blank should always be inserted
+ * after sizeof */
+int blanklines_after_declarations_at_proctop; /* This is vaguely
+ * similar to
+ * blanklines_after_decla
+ * rations except that
+ * it only applies to
+ * the first set of
+ * declarations in a
+ * procedure (just after
+ * the first '{') and it
+ * causes a blank line
+ * to be generated even
+ * if there are no
+ * declarations */
+int block_comment_max_col;
+int extra_expression_indent; /* true if continuation lines from the
+ * expression part of "if(e)",
+ * "while(e)", "for(e;e;e)" should be
+ * indented an extra tab stop so that
+ * they don't conflict with the code
+ * that follows */
+int function_brace_split; /* split function declaration and
+ * brace onto separate lines */
+int use_tabs; /* set true to use tabs for spacing,
+ * false uses all spaces */
+int auto_typedefs; /* set true to recognize identifiers
+ * ending in "_t" like typedefs */
+
+/* -troff font state information */
+
+struct fstate {
+ char font[4];
+ char size;
+ int allcaps:1;
+};
+char *chfont(struct fstate *, struct fstate *, char *);
+
+struct fstate
+ keywordf, /* keyword font */
+ stringf, /* string font */
+ boxcomf, /* Box comment font */
+ blkcomf, /* Block comment font */
+ scomf, /* Same line comment font */
+ bodyf; /* major body font */
+
+
+#define STACKSIZE 150
+
+struct parser_state {
+ int last_token;
+ struct fstate cfont; /* Current font */
+ int p_stack[STACKSIZE]; /* this is the parsers stack */
+ int il[STACKSIZE]; /* this stack stores indentation levels */
+ float cstk[STACKSIZE];/* used to store case stmt indentation levels */
+ int box_com; /* set to true when we are in a "boxed"
+ * comment. In that case, the first non-blank
+ * char should be lined up with the / in / followed by * */
+ int comment_delta,
+ n_comment_delta;
+ int cast_mask; /* indicates which close parens close off
+ * casts */
+ int sizeof_mask; /* indicates which close parens close off
+ * sizeof''s */
+ int block_init; /* true iff inside a block initialization */
+ int block_init_level; /* The level of brace nesting in an
+ * initialization */
+ int last_nl; /* this is true if the last thing scanned was
+ * a newline */
+ int in_or_st; /* Will be true iff there has been a
+ * declarator (e.g. int or char) and no left
+ * paren since the last semicolon. When true,
+ * a '{' is starting a structure definition or
+ * an initialization list */
+ int bl_line; /* set to 1 by dump_line if the line is blank */
+ int col_1; /* set to true if the last token started in
+ * column 1 */
+ int com_col; /* this is the column in which the current
+ * comment should start */
+ int com_ind; /* the column in which comments to the right
+ * of code should start */
+ int com_lines; /* the number of lines with comments, set by
+ * dump_line */
+ int dec_nest; /* current nesting level for structure or init */
+ int decl_com_ind; /* the column in which comments after
+ * declarations should be put */
+ int decl_on_line; /* set to true if this line of code has part
+ * of a declaration on it */
+ int i_l_follow; /* the level to which ind_level should be set
+ * after the current line is printed */
+ int in_decl; /* set to true when we are in a declaration
+ * stmt. The processing of braces is then
+ * slightly different */
+ int in_stmt; /* set to 1 while in a stmt */
+ int ind_level; /* the current indentation level */
+ int ind_size; /* the size of one indentation level */
+ int ind_stmt; /* set to 1 if next line should have an extra
+ * indentation level because we are in the
+ * middle of a stmt */
+ int last_u_d; /* set to true after scanning a token which
+ * forces a following operator to be unary */
+ int leave_comma; /* if true, never break declarations after
+ * commas */
+ int ljust_decl; /* true if declarations should be left
+ * justified */
+ int out_coms; /* the number of comments processed, set by
+ * pr_comment */
+ int out_lines; /* the number of lines written, set by
+ * dump_line */
+ int p_l_follow; /* used to remember how to indent following
+ * statement */
+ int paren_level; /* parenthesization level. used to indent
+ * within statements */
+ short paren_indents[20]; /* column positions of each paren */
+ int pcase; /* set to 1 if the current line label is a
+ * case. It is printed differently from a
+ * regular label */
+ int search_brace; /* set to true by parse when it is necessary
+ * to buffer up all info up to the start of a
+ * stmt after an if, while, etc */
+ int unindent_displace; /* comments not to the right of code
+ * will be placed this many
+ * indentation levels to the left of
+ * code */
+ int use_ff; /* set to one if the current line should be
+ * terminated with a form feed */
+ int want_blank; /* set to true when the following token should
+ * be prefixed by a blank. (Said prefixing is
+ * ignored in some cases.) */
+ int else_if; /* True iff else if pairs should be handled
+ * specially */
+ int decl_indent; /* column to indent declared identifiers to */
+ int local_decl_indent; /* like decl_indent but for locals */
+ int its_a_keyword;
+ int sizeof_keyword;
+ int dumped_decl_indent;
+ float case_indent; /* The distance to indent case labels from the
+ * switch statement */
+ int in_parameter_declaration;
+ int indent_parameters;
+ int tos; /* pointer to top of stack */
+ char procname[100]; /* The name of the current procedure */
+ int just_saw_decl;
+} ps;
+
+int ifdef_level;
+int rparen_count;
+struct parser_state state_stack[5];
+struct parser_state match_state[5];
diff --git a/developer_cmds/indent/io.c b/developer_cmds/indent/io.c
new file mode 100644
index 0000000..d6fd5ef
--- /dev/null
+++ b/developer_cmds/indent/io.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/io.c,v 1.17 2011/12/30 11:02:40 uqs Exp $");
+
+#include <ctype.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "indent_globs.h"
+#include "indent.h"
+
+int comment_open;
+static int paren_target;
+static int pad_output(int current, int target);
+
+void
+dump_line(void)
+{ /* dump_line is the routine that actually
+ * effects the printing of the new source. It
+ * prints the label section, followed by the
+ * code section with the appropriate nesting
+ * level, followed by any comments */
+ int cur_col,
+ target_col = 1;
+ static int not_first_line;
+
+ if (ps.procname[0]) {
+ if (troff) {
+ if (comment_open) {
+ comment_open = 0;
+ fprintf(output, ".*/\n");
+ }
+ fprintf(output, ".Pr \"%s\"\n", ps.procname);
+ }
+ ps.ind_level = 0;
+ ps.procname[0] = 0;
+ }
+ if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
+ if (suppress_blanklines > 0)
+ suppress_blanklines--;
+ else {
+ ps.bl_line = true;
+ n_real_blanklines++;
+ }
+ }
+ else if (!inhibit_formatting) {
+ suppress_blanklines = 0;
+ ps.bl_line = false;
+ if (prefix_blankline_requested && not_first_line) {
+ if (swallow_optional_blanklines) {
+ if (n_real_blanklines == 1)
+ n_real_blanklines = 0;
+ }
+ else {
+ if (n_real_blanklines == 0)
+ n_real_blanklines = 1;
+ }
+ }
+ while (--n_real_blanklines >= 0)
+ putc('\n', output);
+ n_real_blanklines = 0;
+ if (ps.ind_level == 0)
+ ps.ind_stmt = 0; /* this is a class A kludge. dont do
+ * additional statement indentation if we are
+ * at bracket level 0 */
+
+ if (e_lab != s_lab || e_code != s_code)
+ ++code_lines; /* keep count of lines with code */
+
+
+ if (e_lab != s_lab) { /* print lab, if any */
+ if (comment_open) {
+ comment_open = 0;
+ fprintf(output, ".*/\n");
+ }
+ while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
+ e_lab--;
+ cur_col = pad_output(1, compute_label_target());
+ if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0
+ || strncmp(s_lab, "#endif", 6) == 0)) {
+ char *s = s_lab;
+ if (e_lab[-1] == '\n') e_lab--;
+ do putc(*s++, output);
+ while (s < e_lab && 'a' <= *s && *s<='z');
+ while ((*s == ' ' || *s == '\t') && s < e_lab)
+ s++;
+ if (s < e_lab)
+ fprintf(output, s[0]=='/' && s[1]=='*' ? "\t%.*s" : "\t/* %.*s */",
+ (int)(e_lab - s), s);
+ }
+ else fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
+ cur_col = count_spaces(cur_col, s_lab);
+ }
+ else
+ cur_col = 1; /* there is no label section */
+
+ ps.pcase = false;
+
+ if (s_code != e_code) { /* print code section, if any */
+ char *p;
+
+ if (comment_open) {
+ comment_open = 0;
+ fprintf(output, ".*/\n");
+ }
+ target_col = compute_code_target();
+ {
+ int i;
+
+ for (i = 0; i < ps.p_l_follow; i++)
+ if (ps.paren_indents[i] >= 0)
+ ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
+ }
+ cur_col = pad_output(cur_col, target_col);
+ for (p = s_code; p < e_code; p++)
+ if (*p == (char) 0200)
+ fprintf(output, "%d", target_col * 7);
+ else
+ putc(*p, output);
+ cur_col = count_spaces(cur_col, s_code);
+ }
+ if (s_com != e_com) {
+ if (troff) {
+ int all_here = 0;
+ char *p;
+
+ if (e_com[-1] == '/' && e_com[-2] == '*')
+ e_com -= 2, all_here++;
+ while (e_com > s_com && e_com[-1] == ' ')
+ e_com--;
+ *e_com = 0;
+ p = s_com;
+ while (*p == ' ')
+ p++;
+ if (p[0] == '/' && p[1] == '*')
+ p += 2, all_here++;
+ else if (p[0] == '*')
+ p += p[1] == '/' ? 2 : 1;
+ while (*p == ' ')
+ p++;
+ if (*p == 0)
+ goto inhibit_newline;
+ if (comment_open < 2 && ps.box_com) {
+ comment_open = 0;
+ fprintf(output, ".*/\n");
+ }
+ if (comment_open == 0) {
+ if ('a' <= *p && *p <= 'z')
+ *p = *p + 'A' - 'a';
+ if (e_com - p < 50 && all_here == 2) {
+ char *follow = p;
+ fprintf(output, "\n.nr C! \\w\1");
+ while (follow < e_com) {
+ switch (*follow) {
+ case '\n':
+ putc(' ', output);
+ case 1:
+ break;
+ case '\\':
+ putc('\\', output);
+ default:
+ putc(*follow, output);
+ }
+ follow++;
+ }
+ putc(1, output);
+ }
+ fprintf(output, "\n./* %dp %d %dp\n",
+ ps.com_col * 7,
+ (s_code != e_code || s_lab != e_lab) - ps.box_com,
+ target_col * 7);
+ }
+ comment_open = 1 + ps.box_com;
+ while (*p) {
+ if (*p == BACKSLASH)
+ putc(BACKSLASH, output);
+ putc(*p++, output);
+ }
+ }
+ else { /* print comment, if any */
+ int target = ps.com_col;
+ char *com_st = s_com;
+
+ target += ps.comment_delta;
+ while (*com_st == '\t')
+ com_st++, target += 8; /* ? */
+ while (target <= 0)
+ if (*com_st == ' ')
+ target++, com_st++;
+ else if (*com_st == '\t')
+ target = ((target - 1) & ~7) + 9, com_st++;
+ else
+ target = 1;
+ if (cur_col > target) { /* if comment can't fit on this line,
+ * put it on next line */
+ putc('\n', output);
+ cur_col = 1;
+ ++ps.out_lines;
+ }
+ while (e_com > com_st && isspace(e_com[-1]))
+ e_com--;
+ cur_col = pad_output(cur_col, target);
+ if (!ps.box_com) {
+ if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1)) {
+ if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
+ com_st[1] = '*';
+ else
+ fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
+ }
+ }
+ fwrite(com_st, e_com - com_st, 1, output);
+ ps.comment_delta = ps.n_comment_delta;
+ cur_col = count_spaces(cur_col, com_st);
+ ++ps.com_lines; /* count lines with comments */
+ }
+ }
+ if (ps.use_ff)
+ putc('\014', output);
+ else
+ putc('\n', output);
+inhibit_newline:
+ ++ps.out_lines;
+ if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
+ prefix_blankline_requested = 1;
+ ps.just_saw_decl = 0;
+ }
+ else
+ prefix_blankline_requested = postfix_blankline_requested;
+ postfix_blankline_requested = 0;
+ }
+ ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
+ * declaration, remember that fact for
+ * proper comment indentation */
+ ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
+ * indented if we have not
+ * completed this stmt and if
+ * we are not in the middle of
+ * a declaration */
+ ps.use_ff = false;
+ ps.dumped_decl_indent = 0;
+ *(e_lab = s_lab) = '\0'; /* reset buffers */
+ *(e_code = s_code) = '\0';
+ *(e_com = s_com) = '\0';
+ ps.ind_level = ps.i_l_follow;
+ ps.paren_level = ps.p_l_follow;
+ paren_target = -ps.paren_indents[ps.paren_level - 1];
+ not_first_line = 1;
+}
+
+int
+compute_code_target(void)
+{
+ int target_col = ps.ind_size * ps.ind_level + 1;
+
+ if (ps.paren_level)
+ if (!lineup_to_parens)
+ target_col += continuation_indent
+ * (2 * continuation_indent == ps.ind_size ? 1 : ps.paren_level);
+ else {
+ int w;
+ int t = paren_target;
+
+ if ((w = count_spaces(t, s_code) - max_col) > 0
+ && count_spaces(target_col, s_code) <= max_col) {
+ t -= w + 1;
+ if (t > target_col)
+ target_col = t;
+ }
+ else
+ target_col = t;
+ }
+ else if (ps.ind_stmt)
+ target_col += continuation_indent;
+ return target_col;
+}
+
+int
+compute_label_target(void)
+{
+ return
+ ps.pcase ? (int) (case_ind * ps.ind_size) + 1
+ : *s_lab == '#' ? 1
+ : ps.ind_size * (ps.ind_level - label_offset) + 1;
+}
+
+
+/*
+ * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
+ *
+ * All rights reserved
+ *
+ *
+ * NAME: fill_buffer
+ *
+ * FUNCTION: Reads one block of input into input_buffer
+ *
+ * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
+ * Willcox of CAC Added check for switch back to partly full input
+ * buffer from temporary buffer
+ *
+ */
+void
+fill_buffer(void)
+{ /* this routine reads stuff from the input */
+ char *p;
+ int i;
+ FILE *f = input;
+
+ if (bp_save != 0) { /* there is a partly filled input buffer left */
+ buf_ptr = bp_save; /* dont read anything, just switch buffers */
+ buf_end = be_save;
+ bp_save = be_save = 0;
+ if (buf_ptr < buf_end)
+ return; /* only return if there is really something in
+ * this buffer */
+ }
+ for (p = in_buffer;;) {
+ if (p >= in_buffer_limit) {
+ int size = (in_buffer_limit - in_buffer) * 2 + 10;
+ int offset = p - in_buffer;
+ in_buffer = realloc(in_buffer, size);
+ if (in_buffer == NULL)
+ errx(1, "input line too long");
+ p = in_buffer + offset;
+ in_buffer_limit = in_buffer + size - 2;
+ }
+ if ((i = getc(f)) == EOF) {
+ *p++ = ' ';
+ *p++ = '\n';
+ had_eof = true;
+ break;
+ }
+ *p++ = i;
+ if (i == '\n')
+ break;
+ }
+ buf_ptr = in_buffer;
+ buf_end = p;
+ if (p[-2] == '/' && p[-3] == '*') {
+ if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
+ fill_buffer(); /* flush indent error message */
+ else {
+ int com = 0;
+
+ p = in_buffer;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '/' && p[1] == '*') {
+ p += 2;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
+ && p[4] == 'N' && p[5] == 'T') {
+ p += 6;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '*')
+ com = 1;
+ else if (*p == 'O') {
+ if (*++p == 'N')
+ p++, com = 1;
+ else if (*p == 'F' && *++p == 'F')
+ p++, com = 2;
+ }
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
+ if (s_com != e_com || s_lab != e_lab || s_code != e_code)
+ dump_line();
+ if (!(inhibit_formatting = com - 1)) {
+ n_real_blanklines = 0;
+ postfix_blankline_requested = 0;
+ prefix_blankline_requested = 0;
+ suppress_blanklines = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (inhibit_formatting) {
+ p = in_buffer;
+ do
+ putc(*p, output);
+ while (*p++ != '\n');
+ }
+}
+
+/*
+ * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
+ *
+ * All rights reserved
+ *
+ *
+ * NAME: pad_output
+ *
+ * FUNCTION: Writes tabs and spaces to move the current column up to the desired
+ * position.
+ *
+ * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
+ *
+ * PARAMETERS: current integer The current column target
+ * nteger The desired column
+ *
+ * RETURNS: Integer value of the new column. (If current >= target, no action is
+ * taken, and current is returned.
+ *
+ * GLOBALS: None
+ *
+ * CALLS: write (sys)
+ *
+ * CALLED BY: dump_line
+ *
+ * HISTORY: initial coding November 1976 D A Willcox of CAC
+ *
+ */
+static int
+pad_output(int current, int target)
+ /* writes tabs and blanks (if necessary) to
+ * get the current output position up to the
+ * target column */
+ /* current: the current column value */
+ /* target: position we want it at */
+{
+ int curr; /* internal column pointer */
+ int tcur;
+
+ if (troff)
+ fprintf(output, "\\h'|%dp'", (target - 1) * 7);
+ else {
+ if (current >= target)
+ return (current); /* line is already long enough */
+ curr = current;
+ if (use_tabs) {
+ while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
+ putc('\t', output);
+ curr = tcur;
+ }
+ }
+ while (curr++ < target)
+ putc(' ', output); /* pad with final blanks */
+ }
+ return (target);
+}
+
+/*
+ * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
+ *
+ * All rights reserved
+ *
+ *
+ * NAME: count_spaces
+ *
+ * FUNCTION: Find out where printing of a given string will leave the current
+ * character position on output.
+ *
+ * ALGORITHM: Run thru input string and add appropriate values to current
+ * position.
+ *
+ * RETURNS: Integer value of position after printing "buffer" starting in column
+ * "current".
+ *
+ * HISTORY: initial coding November 1976 D A Willcox of CAC
+ *
+ */
+int
+count_spaces(int current, char *buffer)
+/*
+ * this routine figures out where the character position will be after
+ * printing the text in buffer starting at column "current"
+ */
+{
+ char *buf; /* used to look thru buffer */
+ int cur; /* current character counter */
+
+ cur = current;
+
+ for (buf = buffer; *buf != '\0'; ++buf) {
+ switch (*buf) {
+
+ case '\n':
+ case 014: /* form feed */
+ cur = 1;
+ break;
+
+ case '\t':
+ cur = ((cur - 1) & tabmask) + tabsize + 1;
+ break;
+
+ case 010: /* backspace */
+ --cur;
+ break;
+
+ default:
+ ++cur;
+ break;
+ } /* end of switch */
+ } /* end of for loop */
+ return (cur);
+}
+
+void
+diag4(int level, const char *msg, int a, int b)
+{
+ if (level)
+ found_err = 1;
+ if (output == stdout) {
+ fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stdout, msg, a, b);
+ fprintf(stdout, " */\n");
+ }
+ else {
+ fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stderr, msg, a, b);
+ fprintf(stderr, "\n");
+ }
+}
+
+void
+diag3(int level, const char *msg, int a)
+{
+ if (level)
+ found_err = 1;
+ if (output == stdout) {
+ fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stdout, msg, a);
+ fprintf(stdout, " */\n");
+ }
+ else {
+ fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stderr, msg, a);
+ fprintf(stderr, "\n");
+ }
+}
+
+void
+diag2(int level, const char *msg)
+{
+ if (level)
+ found_err = 1;
+ if (output == stdout) {
+ fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stdout, "%s", msg);
+ fprintf(stdout, " */\n");
+ }
+ else {
+ fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
+ fprintf(stderr, "%s", msg);
+ fprintf(stderr, "\n");
+ }
+}
+
+void
+writefdef(struct fstate *f, int nm)
+{
+ fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
+ nm, f->font, nm, f->size);
+}
+
+char *
+chfont(struct fstate *of, struct fstate *nf, char *s)
+{
+ if (of->font[0] != nf->font[0]
+ || of->font[1] != nf->font[1]) {
+ *s++ = '\\';
+ *s++ = 'f';
+ if (nf->font[1]) {
+ *s++ = '(';
+ *s++ = nf->font[0];
+ *s++ = nf->font[1];
+ }
+ else
+ *s++ = nf->font[0];
+ }
+ if (nf->size != of->size) {
+ *s++ = '\\';
+ *s++ = 's';
+ if (nf->size < of->size) {
+ *s++ = '-';
+ *s++ = '0' + of->size - nf->size;
+ }
+ else {
+ *s++ = '+';
+ *s++ = '0' + nf->size - of->size;
+ }
+ }
+ return s;
+}
+
+void
+parsefont(struct fstate *f, const char *s0)
+{
+ const char *s = s0;
+ int sizedelta = 0;
+
+ bzero(f, sizeof *f);
+ while (*s) {
+ if (isdigit(*s))
+ f->size = f->size * 10 + *s - '0';
+ else if (isupper(*s))
+ if (f->font[0])
+ f->font[1] = *s;
+ else
+ f->font[0] = *s;
+ else if (*s == 'c')
+ f->allcaps = 1;
+ else if (*s == '+')
+ sizedelta++;
+ else if (*s == '-')
+ sizedelta--;
+ else {
+ errx(1, "bad font specification: %s", s0);
+ }
+ s++;
+ }
+ if (f->font[0] == 0)
+ f->font[0] = 'R';
+ if (bodyf.size == 0)
+ bodyf.size = 11;
+ if (f->size == 0)
+ f->size = bodyf.size + sizedelta;
+ else if (sizedelta > 0)
+ f->size += bodyf.size;
+ else
+ f->size = bodyf.size - f->size;
+}
diff --git a/developer_cmds/indent/lexi.c b/developer_cmds/indent/lexi.c
new file mode 100644
index 0000000..fbee368
--- /dev/null
+++ b/developer_cmds/indent/lexi.c
@@ -0,0 +1,608 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/lexi.c,v 1.21 2010/04/15 21:41:07 avg Exp $");
+
+/*
+ * Here we have the token scanner for indent. It scans off one token and puts
+ * it in the global variable "token". It returns a code, indicating the type
+ * of token scanned.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "indent_globs.h"
+#include "indent_codes.h"
+#include "indent.h"
+
+#define alphanum 1
+#define opchar 3
+
+struct templ {
+ const char *rwd;
+ int rwcode;
+};
+
+struct templ specials[1000] =
+{
+ {"switch", 1},
+ {"case", 2},
+ {"break", 0},
+ {"struct", 3},
+ {"union", 3},
+ {"enum", 3},
+ {"default", 2},
+ {"int", 4},
+ {"char", 4},
+ {"float", 4},
+ {"double", 4},
+ {"long", 4},
+ {"short", 4},
+ {"typdef", 4},
+ {"unsigned", 4},
+ {"register", 4},
+ {"static", 4},
+ {"global", 4},
+ {"extern", 4},
+ {"void", 4},
+ {"const", 4},
+ {"volatile", 4},
+ {"goto", 0},
+ {"return", 0},
+ {"if", 5},
+ {"while", 5},
+ {"for", 5},
+ {"else", 6},
+ {"do", 6},
+ {"sizeof", 7},
+ {0, 0}
+};
+
+char chartype[128] =
+{ /* this is used to facilitate the decision of
+ * what type (alphanumeric, operator) each
+ * character is */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 1, 3, 3, 0,
+ 0, 0, 3, 3, 0, 3, 0, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 3, 3, 3, 3,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 3, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 3, 0, 3, 0
+};
+
+int
+lexi(void)
+{
+ int unary_delim; /* this is set to 1 if the current token
+ * forces a following operator to be unary */
+ static int last_code; /* the last token type returned */
+ static int l_struct; /* set to 1 if the last token was 'struct' */
+ int code; /* internal code to be returned */
+ char qchar; /* the delimiter character for a string */
+
+ e_token = s_token; /* point to start of place to save token */
+ unary_delim = false;
+ ps.col_1 = ps.last_nl; /* tell world that this token started in
+ * column 1 iff the last thing scanned was nl */
+ ps.last_nl = false;
+
+ while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
+ ps.col_1 = false; /* leading blanks imply token is not in column
+ * 1 */
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ }
+
+ /* Scan an alphanumeric token */
+ if (chartype[(int)*buf_ptr] == alphanum || (buf_ptr[0] == '.' && isdigit(buf_ptr[1]))) {
+ /*
+ * we have a character or number
+ */
+ const char *j; /* used for searching thru list of
+ *
+ * reserved words */
+ struct templ *p;
+
+ if (isdigit(*buf_ptr) || (buf_ptr[0] == '.' && isdigit(buf_ptr[1]))) {
+ int seendot = 0,
+ seenexp = 0,
+ seensfx = 0;
+ if (*buf_ptr == '0' &&
+ (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
+ *e_token++ = *buf_ptr++;
+ *e_token++ = *buf_ptr++;
+ while (isxdigit(*buf_ptr)) {
+ CHECK_SIZE_TOKEN;
+ *e_token++ = *buf_ptr++;
+ }
+ }
+ else
+ while (1) {
+ if (*buf_ptr == '.') {
+ if (seendot)
+ break;
+ else
+ seendot++;
+ }
+ CHECK_SIZE_TOKEN;
+ *e_token++ = *buf_ptr++;
+ if (!isdigit(*buf_ptr) && *buf_ptr != '.') {
+ if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
+ break;
+ else {
+ seenexp++;
+ seendot++;
+ CHECK_SIZE_TOKEN;
+ *e_token++ = *buf_ptr++;
+ if (*buf_ptr == '+' || *buf_ptr == '-')
+ *e_token++ = *buf_ptr++;
+ }
+ }
+ }
+ while (1) {
+ if (!(seensfx & 1) &&
+ (*buf_ptr == 'U' || *buf_ptr == 'u')) {
+ CHECK_SIZE_TOKEN;
+ *e_token++ = *buf_ptr++;
+ seensfx |= 1;
+ continue;
+ }
+ if (!(seensfx & 2) &&
+ (*buf_ptr == 'L' || *buf_ptr == 'l')) {
+ CHECK_SIZE_TOKEN;
+ if (buf_ptr[1] == buf_ptr[0])
+ *e_token++ = *buf_ptr++;
+ *e_token++ = *buf_ptr++;
+ seensfx |= 2;
+ continue;
+ }
+ break;
+ }
+ }
+ else
+ while (chartype[(int)*buf_ptr] == alphanum || *buf_ptr == BACKSLASH) {
+ /* fill_buffer() terminates buffer with newline */
+ if (*buf_ptr == BACKSLASH) {
+ if (*(buf_ptr + 1) == '\n') {
+ buf_ptr += 2;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ } else
+ break;
+ }
+ CHECK_SIZE_TOKEN;
+ /* copy it over */
+ *e_token++ = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ *e_token++ = '\0';
+ while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ ps.its_a_keyword = false;
+ ps.sizeof_keyword = false;
+ if (l_struct && !ps.p_l_follow) {
+ /* if last token was 'struct' and we're not
+ * in parentheses, then this token
+ * should be treated as a declaration */
+ l_struct = false;
+ last_code = ident;
+ ps.last_u_d = true;
+ return (decl);
+ }
+ ps.last_u_d = l_struct; /* Operator after identifier is binary
+ * unless last token was 'struct' */
+ l_struct = false;
+ last_code = ident; /* Remember that this is the code we will
+ * return */
+
+ if (auto_typedefs) {
+ const char *q = s_token;
+ size_t q_len = strlen(q);
+ /* Check if we have an "_t" in the end */
+ if (q_len > 2 &&
+ (strcmp(q + q_len - 2, "_t") == 0)) {
+ ps.its_a_keyword = true;
+ ps.last_u_d = true;
+ goto found_auto_typedef;
+ }
+ }
+
+ /*
+ * This loop will check if the token is a keyword.
+ */
+ for (p = specials; (j = p->rwd) != 0; p++) {
+ const char *q = s_token; /* point at scanned token */
+ if (*j++ != *q++ || *j++ != *q++)
+ continue; /* This test depends on the fact that
+ * identifiers are always at least 1 character
+ * long (ie. the first two bytes of the
+ * identifier are always meaningful) */
+ if (q[-1] == 0)
+ break; /* If its a one-character identifier */
+ while (*q++ == *j)
+ if (*j++ == 0)
+ goto found_keyword; /* I wish that C had a multi-level
+ * break... */
+ }
+ if (p->rwd) { /* we have a keyword */
+ found_keyword:
+ ps.its_a_keyword = true;
+ ps.last_u_d = true;
+ switch (p->rwcode) {
+ case 1: /* it is a switch */
+ return (swstmt);
+ case 2: /* a case or default */
+ return (casestmt);
+
+ case 3: /* a "struct" */
+ /*
+ * Next time around, we will want to know that we have had a
+ * 'struct'
+ */
+ l_struct = true;
+ /* FALLTHROUGH */
+
+ case 4: /* one of the declaration keywords */
+ found_auto_typedef:
+ if (ps.p_l_follow) {
+ ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.sizeof_mask;
+ break; /* inside parens: cast, param list or sizeof */
+ }
+ last_code = decl;
+ return (decl);
+
+ case 5: /* if, while, for */
+ return (sp_paren);
+
+ case 6: /* do, else */
+ return (sp_nparen);
+
+ case 7:
+ ps.sizeof_keyword = true;
+ default: /* all others are treated like any other
+ * identifier */
+ return (ident);
+ } /* end of switch */
+ } /* end of if (found_it) */
+ if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) {
+ char *tp = buf_ptr;
+ while (tp < buf_end)
+ if (*tp++ == ')' && (*tp == ';' || *tp == ','))
+ goto not_proc;
+ strncpy(ps.procname, token, sizeof ps.procname - 1);
+ ps.in_parameter_declaration = 1;
+ rparen_count = 1;
+ not_proc:;
+ }
+ /*
+ * The following hack attempts to guess whether or not the current
+ * token is in fact a declaration keyword -- one that has been
+ * typedefd
+ */
+ if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_')
+ && !ps.p_l_follow
+ && !ps.block_init
+ && (ps.last_token == rparen || ps.last_token == semicolon ||
+ ps.last_token == decl ||
+ ps.last_token == lbrace || ps.last_token == rbrace)) {
+ ps.its_a_keyword = true;
+ ps.last_u_d = true;
+ last_code = decl;
+ return decl;
+ }
+ if (last_code == decl) /* if this is a declared variable, then
+ * following sign is unary */
+ ps.last_u_d = true; /* will make "int a -1" work */
+ last_code = ident;
+ return (ident); /* the ident is not in the list */
+ } /* end of procesing for alpanum character */
+
+ /* Scan a non-alphanumeric token */
+
+ *e_token++ = *buf_ptr; /* if it is only a one-character token, it is
+ * moved here */
+ *e_token = '\0';
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+
+ switch (*token) {
+ case '\n':
+ unary_delim = ps.last_u_d;
+ ps.last_nl = true; /* remember that we just had a newline */
+ code = (had_eof ? 0 : newline);
+
+ /*
+ * if data has been exhausted, the newline is a dummy, and we should
+ * return code to stop
+ */
+ break;
+
+ case '\'': /* start of quoted character */
+ case '"': /* start of string */
+ qchar = *token;
+ if (troff) {
+ e_token[-1] = '`';
+ if (qchar == '"')
+ *e_token++ = '`';
+ e_token = chfont(&bodyf, &stringf, e_token);
+ }
+ do { /* copy the string */
+ while (1) { /* move one character or [/<char>]<char> */
+ if (*buf_ptr == '\n') {
+ diag2(1, "Unterminated literal");
+ goto stop_lit;
+ }
+ CHECK_SIZE_TOKEN; /* Only have to do this once in this loop,
+ * since CHECK_SIZE guarantees that there
+ * are at least 5 entries left */
+ *e_token = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ if (*e_token == BACKSLASH) { /* if escape, copy extra char */
+ if (*buf_ptr == '\n') /* check for escaped newline */
+ ++line_no;
+ if (troff) {
+ *++e_token = BACKSLASH;
+ if (*buf_ptr == BACKSLASH)
+ *++e_token = BACKSLASH;
+ }
+ *++e_token = *buf_ptr++;
+ ++e_token; /* we must increment this again because we
+ * copied two chars */
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ else
+ break; /* we copied one character */
+ } /* end of while (1) */
+ } while (*e_token++ != qchar);
+ if (troff) {
+ e_token = chfont(&stringf, &bodyf, e_token - 1);
+ if (qchar == '"')
+ *e_token++ = '\'';
+ }
+stop_lit:
+ code = ident;
+ break;
+
+ case ('('):
+ case ('['):
+ unary_delim = true;
+ code = lparen;
+ break;
+
+ case (')'):
+ case (']'):
+ code = rparen;
+ break;
+
+ case '#':
+ unary_delim = ps.last_u_d;
+ code = preesc;
+ break;
+
+ case '?':
+ unary_delim = true;
+ code = question;
+ break;
+
+ case (':'):
+ code = colon;
+ unary_delim = true;
+ break;
+
+ case (';'):
+ unary_delim = true;
+ code = semicolon;
+ break;
+
+ case ('{'):
+ unary_delim = true;
+
+ /*
+ * if (ps.in_or_st) ps.block_init = 1;
+ */
+ /* ? code = ps.block_init ? lparen : lbrace; */
+ code = lbrace;
+ break;
+
+ case ('}'):
+ unary_delim = true;
+ /* ? code = ps.block_init ? rparen : rbrace; */
+ code = rbrace;
+ break;
+
+ case 014: /* a form feed */
+ unary_delim = ps.last_u_d;
+ ps.last_nl = true; /* remember this so we can set 'ps.col_1'
+ * right */
+ code = form_feed;
+ break;
+
+ case (','):
+ unary_delim = true;
+ code = comma;
+ break;
+
+ case '.':
+ unary_delim = false;
+ code = period;
+ break;
+
+ case '-':
+ case '+': /* check for -, +, --, ++ */
+ code = (ps.last_u_d ? unary_op : binary_op);
+ unary_delim = true;
+
+ if (*buf_ptr == token[0]) {
+ /* check for doubled character */
+ *e_token++ = *buf_ptr++;
+ /* buffer overflow will be checked at end of loop */
+ if (last_code == ident || last_code == rparen) {
+ code = (ps.last_u_d ? unary_op : postop);
+ /* check for following ++ or -- */
+ unary_delim = false;
+ }
+ }
+ else if (*buf_ptr == '=')
+ /* check for operator += */
+ *e_token++ = *buf_ptr++;
+ else if (*buf_ptr == '>') {
+ /* check for operator -> */
+ *e_token++ = *buf_ptr++;
+ if (!pointer_as_binop) {
+ unary_delim = false;
+ code = unary_op;
+ ps.want_blank = false;
+ }
+ }
+ break; /* buffer overflow will be checked at end of
+ * switch */
+
+ case '=':
+ if (ps.in_or_st)
+ ps.block_init = 1;
+#ifdef undef
+ if (chartype[*buf_ptr] == opchar) { /* we have two char assignment */
+ e_token[-1] = *buf_ptr++;
+ if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr)
+ *e_token++ = *buf_ptr++;
+ *e_token++ = '='; /* Flip =+ to += */
+ *e_token = 0;
+ }
+#else
+ if (*buf_ptr == '=') {/* == */
+ *e_token++ = '='; /* Flip =+ to += */
+ buf_ptr++;
+ *e_token = 0;
+ }
+#endif
+ code = binary_op;
+ unary_delim = true;
+ break;
+ /* can drop thru!!! */
+
+ case '>':
+ case '<':
+ case '!': /* ops like <, <<, <=, !=, etc */
+ if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
+ *e_token++ = *buf_ptr;
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ if (*buf_ptr == '=')
+ *e_token++ = *buf_ptr++;
+ code = (ps.last_u_d ? unary_op : binary_op);
+ unary_delim = true;
+ break;
+
+ default:
+ if (token[0] == '/' && *buf_ptr == '*') {
+ /* it is start of comment */
+ *e_token++ = '*';
+
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+
+ code = comment;
+ unary_delim = ps.last_u_d;
+ break;
+ }
+ while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
+ /*
+ * handle ||, &&, etc, and also things as in int *****i
+ */
+ *e_token++ = *buf_ptr;
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ }
+ code = (ps.last_u_d ? unary_op : binary_op);
+ unary_delim = true;
+
+
+ } /* end of switch */
+ if (code != newline) {
+ l_struct = false;
+ last_code = code;
+ }
+ if (buf_ptr >= buf_end) /* check for input buffer empty */
+ fill_buffer();
+ ps.last_u_d = unary_delim;
+ *e_token = '\0'; /* null terminate the token */
+ return (code);
+}
+
+/*
+ * Add the given keyword to the keyword table, using val as the keyword type
+ */
+void
+addkey(char *key, int val)
+{
+ struct templ *p = specials;
+ while (p->rwd)
+ if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
+ return;
+ else
+ p++;
+ if (p >= specials + sizeof specials / sizeof specials[0])
+ return; /* For now, table overflows are silently
+ * ignored */
+ p->rwd = key;
+ p->rwcode = val;
+ p[1].rwd = 0;
+ p[1].rwcode = 0;
+}
diff --git a/developer_cmds/indent/parse.c b/developer_cmds/indent/parse.c
new file mode 100644
index 0000000..7720ff1
--- /dev/null
+++ b/developer_cmds/indent/parse.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/parse.c,v 1.10 2003/06/15 09:28:17 charnier Exp $");
+
+#include <stdio.h>
+#include "indent_globs.h"
+#include "indent_codes.h"
+#include "indent.h"
+
+static void reduce(void);
+
+void
+parse(int tk) /* tk: the code for the construct scanned */
+{
+ int i;
+
+#ifdef debug
+ printf("%2d - %s\n", tk, token);
+#endif
+
+ while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
+ /* true if we have an if without an else */
+ ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
+ * reduction */
+ reduce(); /* see if this allows any reduction */
+ }
+
+
+ switch (tk) { /* go on and figure out what to do with the
+ * input */
+
+ case decl: /* scanned a declaration word */
+ ps.search_brace = btype_2;
+ /* indicate that following brace should be on same line */
+ if (ps.p_stack[ps.tos] != decl) { /* only put one declaration
+ * onto stack */
+ break_comma = true; /* while in declaration, newline should be
+ * forced after comma */
+ ps.p_stack[++ps.tos] = decl;
+ ps.il[ps.tos] = ps.i_l_follow;
+
+ if (ps.ljust_decl) {/* only do if we want left justified
+ * declarations */
+ ps.ind_level = 0;
+ for (i = ps.tos - 1; i > 0; --i)
+ if (ps.p_stack[i] == decl)
+ ++ps.ind_level; /* indentation is number of
+ * declaration levels deep we are */
+ ps.i_l_follow = ps.ind_level;
+ }
+ }
+ break;
+
+ case ifstmt: /* scanned if (...) */
+ if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
+ ps.i_l_follow = ps.il[ps.tos];
+ case dolit: /* 'do' */
+ case forstmt: /* for (...) */
+ ps.p_stack[++ps.tos] = tk;
+ ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
+ ++ps.i_l_follow; /* subsequent statements should be indented 1 */
+ ps.search_brace = btype_2;
+ break;
+
+ case lbrace: /* scanned { */
+ break_comma = false; /* don't break comma in an initial list */
+ if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
+ || ps.p_stack[ps.tos] == stmtl)
+ ++ps.i_l_follow; /* it is a random, isolated stmt group or a
+ * declaration */
+ else {
+ if (s_code == e_code) {
+ /*
+ * only do this if there is nothing on the line
+ */
+ --ps.ind_level;
+ /*
+ * it is a group as part of a while, for, etc.
+ */
+ if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
+ --ps.ind_level;
+ /*
+ * for a switch, brace should be two levels out from the code
+ */
+ }
+ }
+
+ ps.p_stack[++ps.tos] = lbrace;
+ ps.il[ps.tos] = ps.ind_level;
+ ps.p_stack[++ps.tos] = stmt;
+ /* allow null stmt between braces */
+ ps.il[ps.tos] = ps.i_l_follow;
+ break;
+
+ case whilestmt: /* scanned while (...) */
+ if (ps.p_stack[ps.tos] == dohead) {
+ /* it is matched with do stmt */
+ ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
+ ps.p_stack[++ps.tos] = whilestmt;
+ ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
+ }
+ else { /* it is a while loop */
+ ps.p_stack[++ps.tos] = whilestmt;
+ ps.il[ps.tos] = ps.i_l_follow;
+ ++ps.i_l_follow;
+ ps.search_brace = btype_2;
+ }
+
+ break;
+
+ case elselit: /* scanned an else */
+
+ if (ps.p_stack[ps.tos] != ifhead)
+ diag2(1, "Unmatched 'else'");
+ else {
+ ps.ind_level = ps.il[ps.tos]; /* indentation for else should
+ * be same as for if */
+ ps.i_l_follow = ps.ind_level + 1; /* everything following should
+ * be in 1 level */
+ ps.p_stack[ps.tos] = elsehead;
+ /* remember if with else */
+ ps.search_brace = btype_2 | ps.else_if;
+ }
+ break;
+
+ case rbrace: /* scanned a } */
+ /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
+ if (ps.p_stack[ps.tos - 1] == lbrace) {
+ ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
+ ps.p_stack[ps.tos] = stmt;
+ }
+ else
+ diag2(1, "Statement nesting error");
+ break;
+
+ case swstmt: /* had switch (...) */
+ ps.p_stack[++ps.tos] = swstmt;
+ ps.cstk[ps.tos] = case_ind;
+ /* save current case indent level */
+ ps.il[ps.tos] = ps.i_l_follow;
+ case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one
+ * level down from
+ * switch */
+ ps.i_l_follow += ps.case_indent + 1; /* statements should be two
+ * levels in */
+ ps.search_brace = btype_2;
+ break;
+
+ case semicolon: /* this indicates a simple stmt */
+ break_comma = false; /* turn off flag to break after commas in a
+ * declaration */
+ ps.p_stack[++ps.tos] = stmt;
+ ps.il[ps.tos] = ps.ind_level;
+ break;
+
+ default: /* this is an error */
+ diag2(1, "Unknown code to parser");
+ return;
+
+
+ } /* end of switch */
+
+ reduce(); /* see if any reduction can be done */
+
+#ifdef debug
+ for (i = 1; i <= ps.tos; ++i)
+ printf("(%d %d)", ps.p_stack[i], ps.il[i]);
+ printf("\n");
+#endif
+
+ return;
+}
+
+/*
+ * NAME: reduce
+ *
+ * FUNCTION: Implements the reduce part of the parsing algorithm
+ *
+ * ALGORITHM: The following reductions are done. Reductions are repeated
+ * until no more are possible.
+ *
+ * Old TOS New TOS
+ * <stmt> <stmt> <stmtl>
+ * <stmtl> <stmt> <stmtl>
+ * do <stmt> "dostmt"
+ * if <stmt> "ifstmt"
+ * switch <stmt> <stmt>
+ * decl <stmt> <stmt>
+ * "ifelse" <stmt> <stmt>
+ * for <stmt> <stmt>
+ * while <stmt> <stmt>
+ * "dostmt" while <stmt>
+ *
+ * On each reduction, ps.i_l_follow (the indentation for the following line)
+ * is set to the indentation level associated with the old TOS.
+ *
+ * PARAMETERS: None
+ *
+ * RETURNS: Nothing
+ *
+ * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
+ *
+ * CALLS: None
+ *
+ * CALLED BY: parse
+ *
+ * HISTORY: initial coding November 1976 D A Willcox of CAC
+ *
+ */
+/*----------------------------------------------*\
+| REDUCTION PHASE |
+\*----------------------------------------------*/
+static void
+reduce(void)
+{
+ int i;
+
+ for (;;) { /* keep looping until there is nothing left to
+ * reduce */
+
+ switch (ps.p_stack[ps.tos]) {
+
+ case stmt:
+ switch (ps.p_stack[ps.tos - 1]) {
+
+ case stmt:
+ case stmtl:
+ /* stmtl stmt or stmt stmt */
+ ps.p_stack[--ps.tos] = stmtl;
+ break;
+
+ case dolit: /* <do> <stmt> */
+ ps.p_stack[--ps.tos] = dohead;
+ ps.i_l_follow = ps.il[ps.tos];
+ break;
+
+ case ifstmt:
+ /* <if> <stmt> */
+ ps.p_stack[--ps.tos] = ifhead;
+ for (i = ps.tos - 1;
+ (
+ ps.p_stack[i] != stmt
+ &&
+ ps.p_stack[i] != stmtl
+ &&
+ ps.p_stack[i] != lbrace
+ );
+ --i);
+ ps.i_l_follow = ps.il[i];
+ /*
+ * for the time being, we will assume that there is no else on
+ * this if, and set the indentation level accordingly. If an
+ * else is scanned, it will be fixed up later
+ */
+ break;
+
+ case swstmt:
+ /* <switch> <stmt> */
+ case_ind = ps.cstk[ps.tos - 1];
+
+ case decl: /* finish of a declaration */
+ case elsehead:
+ /* <<if> <stmt> else> <stmt> */
+ case forstmt:
+ /* <for> <stmt> */
+ case whilestmt:
+ /* <while> <stmt> */
+ ps.p_stack[--ps.tos] = stmt;
+ ps.i_l_follow = ps.il[ps.tos];
+ break;
+
+ default: /* <anything else> <stmt> */
+ return;
+
+ } /* end of section for <stmt> on top of stack */
+ break;
+
+ case whilestmt: /* while (...) on top */
+ if (ps.p_stack[ps.tos - 1] == dohead) {
+ /* it is termination of a do while */
+ ps.tos -= 2;
+ break;
+ }
+ else
+ return;
+
+ default: /* anything else on top */
+ return;
+
+ }
+ }
+}
diff --git a/developer_cmds/indent/pr_comment.c b/developer_cmds/indent/pr_comment.c
new file mode 100644
index 0000000..ad7fe2e
--- /dev/null
+++ b/developer_cmds/indent/pr_comment.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 1985 Sun Microsystems, Inc.
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/indent/pr_comment.c,v 1.8 2003/06/15 09:28:17 charnier Exp $");
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "indent_globs.h"
+#include "indent.h"
+/*
+ * NAME:
+ * pr_comment
+ *
+ * FUNCTION:
+ * This routine takes care of scanning and printing comments.
+ *
+ * ALGORITHM:
+ * 1) Decide where the comment should be aligned, and if lines should
+ * be broken.
+ * 2) If lines should not be broken and filled, just copy up to end of
+ * comment.
+ * 3) If lines should be filled, then scan thru input_buffer copying
+ * characters to com_buf. Remember where the last blank, tab, or
+ * newline was. When line is filled, print up to last blank and
+ * continue copying.
+ *
+ * HISTORY:
+ * November 1976 D A Willcox of CAC Initial coding
+ * 12/6/76 D A Willcox of CAC Modification to handle
+ * UNIX-style comments
+ *
+ */
+
+/*
+ * this routine processes comments. It makes an attempt to keep comments from
+ * going over the max line length. If a line is too long, it moves everything
+ * from the last blank to the next comment line. Blanks and tabs from the
+ * beginning of the input line are removed
+ */
+
+void
+pr_comment(void)
+{
+ int now_col; /* column we are in now */
+ int adj_max_col; /* Adjusted max_col for when we decide to
+ * spill comments over the right margin */
+ char *last_bl; /* points to the last blank in the output
+ * buffer */
+ char *t_ptr; /* used for moving string */
+ int unix_comment; /* tri-state variable used to decide if it is
+ * a unix-style comment. 0 means only blanks
+ * since /+*, 1 means regular style comment, 2
+ * means unix style comment */
+ int break_delim = comment_delimiter_on_blankline;
+ int l_just_saw_decl = ps.just_saw_decl;
+ /*
+ * int ps.last_nl = 0; true iff the last significant thing
+ * weve seen is a newline
+ */
+ int one_liner = 1; /* true iff this comment is a one-liner */
+ adj_max_col = max_col;
+ ps.just_saw_decl = 0;
+ last_bl = 0; /* no blanks found so far */
+ ps.box_com = false; /* at first, assume that we are not in
+ * a boxed comment or some other
+ * comment that should not be touched */
+ ++ps.out_coms; /* keep track of number of comments */
+ unix_comment = 1; /* set flag to let us figure out if there is a
+ * unix-style comment ** DISABLED: use 0 to
+ * reenable this hack! */
+
+ /* Figure where to align and how to treat the comment */
+
+ if (ps.col_1 && !format_col1_comments) { /* if comment starts in column
+ * 1 it should not be touched */
+ ps.box_com = true;
+ ps.com_col = 1;
+ }
+ else {
+ if (*buf_ptr == '-' || *buf_ptr == '*' ||
+ (*buf_ptr == '\n' && !format_block_comments)) {
+ ps.box_com = true; /* A comment with a '-' or '*' immediately
+ * after the /+* is assumed to be a boxed
+ * comment. A comment with a newline
+ * immediately after the /+* is assumed to
+ * be a block comment and is treated as a
+ * box comment unless format_block_comments
+ * is nonzero (the default). */
+ break_delim = 0;
+ }
+ if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
+ /* klg: check only if this line is blank */
+ /*
+ * If this (*and previous lines are*) blank, dont put comment way
+ * out at left
+ */
+ ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
+ adj_max_col = block_comment_max_col;
+ if (ps.com_col <= 1)
+ ps.com_col = 1 + !format_col1_comments;
+ }
+ else {
+ int target_col;
+ break_delim = 0;
+ if (s_code != e_code)
+ target_col = count_spaces(compute_code_target(), s_code);
+ else {
+ target_col = 1;
+ if (s_lab != e_lab)
+ target_col = count_spaces(compute_label_target(), s_lab);
+ }
+ ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
+ if (ps.com_col < target_col)
+ ps.com_col = ((target_col + 7) & ~7) + 1;
+ if (ps.com_col + 24 > adj_max_col)
+ adj_max_col = ps.com_col + 24;
+ }
+ }
+ if (ps.box_com) {
+ buf_ptr[-2] = 0;
+ ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
+ buf_ptr[-2] = '/';
+ }
+ else {
+ ps.n_comment_delta = 0;
+ while (*buf_ptr == ' ' || *buf_ptr == '\t')
+ buf_ptr++;
+ }
+ ps.comment_delta = 0;
+ *e_com++ = '/'; /* put '/' followed by '*' into buffer */
+ *e_com++ = '*';
+ if (*buf_ptr != ' ' && !ps.box_com)
+ *e_com++ = ' ';
+
+ *e_com = '\0';
+ if (troff) {
+ now_col = 1;
+ adj_max_col = 80;
+ }
+ else
+ now_col = count_spaces(ps.com_col, s_com); /* figure what column we
+ * would be in if we
+ * printed the comment
+ * now */
+
+ /* Start to copy the comment */
+
+ while (1) { /* this loop will go until the comment is
+ * copied */
+ if (*buf_ptr > 040 && *buf_ptr != '*')
+ ps.last_nl = 0;
+ CHECK_SIZE_COM;
+ switch (*buf_ptr) { /* this checks for various spcl cases */
+ case 014: /* check for a form feed */
+ if (!ps.box_com) { /* in a text comment, break the line here */
+ ps.use_ff = true;
+ /* fix so dump_line uses a form feed */
+ dump_line();
+ last_bl = 0;
+ *e_com++ = ' ';
+ *e_com++ = '*';
+ *e_com++ = ' ';
+ while (*++buf_ptr == ' ' || *buf_ptr == '\t');
+ }
+ else {
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ *e_com++ = 014;
+ }
+ break;
+
+ case '\n':
+ if (had_eof) { /* check for unexpected eof */
+ printf("Unterminated comment\n");
+ *e_com = '\0';
+ dump_line();
+ return;
+ }
+ one_liner = 0;
+ if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
+ * we dont ignore the newline */
+ if (s_com == e_com) {
+ *e_com++ = ' ';
+ *e_com++ = ' ';
+ }
+ *e_com = '\0';
+ if (!ps.box_com && e_com - s_com > 3) {
+ if (break_delim == 1 && s_com[0] == '/'
+ && s_com[1] == '*' && s_com[2] == ' ') {
+ char *t = e_com;
+ break_delim = 2;
+ e_com = s_com + 2;
+ *e_com = 0;
+ if (blanklines_before_blockcomments)
+ prefix_blankline_requested = 1;
+ dump_line();
+ e_com = t;
+ s_com[0] = s_com[1] = s_com[2] = ' ';
+ }
+ dump_line();
+ CHECK_SIZE_COM;
+ *e_com++ = ' ';
+ *e_com++ = ' ';
+ }
+ dump_line();
+ now_col = ps.com_col;
+ }
+ else {
+ ps.last_nl = 1;
+ if (unix_comment != 1) { /* we not are in unix_style
+ * comment */
+ if (unix_comment == 0 && s_code == e_code) {
+ /*
+ * if it is a UNIX-style comment, ignore the
+ * requirement that previous line be blank for
+ * unindention
+ */
+ ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
+ if (ps.com_col <= 1)
+ ps.com_col = 2;
+ }
+ unix_comment = 2; /* permanently remember that we are in
+ * this type of comment */
+ dump_line();
+ ++line_no;
+ now_col = ps.com_col;
+ *e_com++ = ' ';
+ /*
+ * fix so that the star at the start of the line will line
+ * up
+ */
+ do /* flush leading white space */
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ while (*buf_ptr == ' ' || *buf_ptr == '\t');
+ break;
+ }
+ if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
+ last_bl = e_com - 1;
+ /*
+ * if there was a space at the end of the last line, remember
+ * where it was
+ */
+ else { /* otherwise, insert one */
+ last_bl = e_com;
+ CHECK_SIZE_COM;
+ *e_com++ = ' ';
+ ++now_col;
+ }
+ }
+ ++line_no; /* keep track of input line number */
+ if (!ps.box_com) {
+ int nstar = 1;
+ do { /* flush any blanks and/or tabs at start of
+ * next line */
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ if (*buf_ptr == '*' && --nstar >= 0) {
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+ if (*buf_ptr == '/')
+ goto end_of_comment;
+ }
+ } while (*buf_ptr == ' ' || *buf_ptr == '\t');
+ }
+ else if (++buf_ptr >= buf_end)
+ fill_buffer();
+ break; /* end of case for newline */
+
+ case '*': /* must check for possibility of being at end
+ * of comment */
+ if (++buf_ptr >= buf_end) /* get to next char after * */
+ fill_buffer();
+
+ if (unix_comment == 0) /* set flag to show we are not in
+ * unix-style comment */
+ unix_comment = 1;
+
+ if (*buf_ptr == '/') { /* it is the end!!! */
+ end_of_comment:
+ if (++buf_ptr >= buf_end)
+ fill_buffer();
+
+ if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
+ * end */
+ *e_com++ = ' ';
+ ++now_col;
+ }
+ if (break_delim == 1 && !one_liner && s_com[0] == '/'
+ && s_com[1] == '*' && s_com[2] == ' ') {
+ char *t = e_com;
+ break_delim = 2;
+ e_com = s_com + 2;
+ *e_com = 0;
+ if (blanklines_before_blockcomments)
+ prefix_blankline_requested = 1;
+ dump_line();
+ e_com = t;
+ s_com[0] = s_com[1] = s_com[2] = ' ';
+ }
+ if (break_delim == 2 && e_com > s_com + 3
+ /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
+ *e_com = '\0';
+ dump_line();
+ now_col = ps.com_col;
+ }
+ CHECK_SIZE_COM;
+ *e_com++ = '*';
+ *e_com++ = '/';
+ *e_com = '\0';
+ ps.just_saw_decl = l_just_saw_decl;
+ return;
+ }
+ else { /* handle isolated '*' */
+ *e_com++ = '*';
+ ++now_col;
+ }
+ break;
+ default: /* we have a random char */
+ if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
+ unix_comment = 1; /* we are not in unix-style comment */
+
+ *e_com = *buf_ptr++;
+ if (buf_ptr >= buf_end)
+ fill_buffer();
+
+ if (*e_com == '\t') /* keep track of column */
+ now_col = ((now_col - 1) & tabmask) + tabsize + 1;
+ else if (*e_com == '\b') /* this is a backspace */
+ --now_col;
+ else
+ ++now_col;
+
+ if (*e_com == ' ' || *e_com == '\t')
+ last_bl = e_com;
+ /* remember we saw a blank */
+
+ ++e_com;
+ if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
+ /*
+ * the comment is too long, it must be broken up
+ */
+ if (break_delim == 1 && s_com[0] == '/'
+ && s_com[1] == '*' && s_com[2] == ' ') {
+ char *t = e_com;
+ break_delim = 2;
+ e_com = s_com + 2;
+ *e_com = 0;
+ if (blanklines_before_blockcomments)
+ prefix_blankline_requested = 1;
+ dump_line();
+ e_com = t;
+ s_com[0] = s_com[1] = s_com[2] = ' ';
+ }
+ if (last_bl == 0) { /* we have seen no blanks */
+ last_bl = e_com; /* fake it */
+ *e_com++ = ' ';
+ }
+ *e_com = '\0'; /* print what we have */
+ *last_bl = '\0';
+ while (last_bl > s_com && last_bl[-1] < 040)
+ *--last_bl = 0;
+ e_com = last_bl;
+ dump_line();
+
+ *e_com++ = ' '; /* add blanks for continuation */
+ *e_com++ = ' ';
+ *e_com++ = ' ';
+
+ t_ptr = last_bl + 1;
+ last_bl = 0;
+ if (t_ptr >= e_com) {
+ while (*t_ptr == ' ' || *t_ptr == '\t')
+ t_ptr++;
+ while (*t_ptr != '\0') { /* move unprinted part of
+ * comment down in buffer */
+ if (*t_ptr == ' ' || *t_ptr == '\t')
+ last_bl = e_com;
+ *e_com++ = *t_ptr++;
+ }
+ }
+ *e_com = '\0';
+ now_col = count_spaces(ps.com_col, s_com); /* recompute current
+ * position */
+ }
+ break;
+ }
+ }
+}
diff --git a/developer_cmds/lorder/lorder.1 b/developer_cmds/lorder/lorder.1
new file mode 100644
index 0000000..45fe0e6
--- /dev/null
+++ b/developer_cmds/lorder/lorder.1
@@ -0,0 +1,75 @@
+.\" $NetBSD: lorder.1,v 1.6 1997/10/19 04:21:49 lukem Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lorder.1 8.2 (Berkeley) 4/28/95
+.\"
+.Dd April 28, 1995
+.Dt LORDER 1
+.Os
+.Sh NAME
+.Nm lorder
+.Nd list dependencies for object files
+.Sh SYNOPSIS
+.Nm
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility uses
+.Xr nm 1
+to determine interdependencies in the list of object files
+specified on the command line.
+.Nm
+outputs a list of file names where the first file contains a symbol
+which is defined by the second file.
+.Pp
+The output is normally used with
+.Xr tsort 1
+when a library is created to determine the optimum ordering of the
+object modules so that all references may be resolved in a single
+pass of the loader.
+.Sh EXAMPLES
+.Bd -literal -offset indent
+ar cr library.a `lorder ${OBJS} | tsort`
+.Ed
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr ld 1 ,
+.Xr nm 1 ,
+.Xr ranlib 1 ,
+.Xr tsort 1
+.Sh HISTORY
+An
+.Nm
+utility appeared in
+.At v7 .
diff --git a/developer_cmds/lorder/lorder.sh b/developer_cmds/lorder/lorder.sh
new file mode 100644
index 0000000..b6ed479
--- /dev/null
+++ b/developer_cmds/lorder/lorder.sh
@@ -0,0 +1,104 @@
+#!/bin/sh -
+# $NetBSD: lorder.sh,v 1.7 1998/04/09 05:28:07 fair Exp $
+#
+# Copyright (c) 1990, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)lorder.sh 8.1 (Berkeley) 6/6/93
+#
+
+# If the user has set ${NM} then we use it, otherwise we use 'nm'.
+# We try to find the compiler in the user's path, and if that fails we
+# try to find it in the default path. If we can't find it, we punt.
+# Once we find it, we canonicalize its name and set the path to the
+# default path so that other commands we use are picked properly.
+
+if ! type "${NM:=nm}" > /dev/null 2>&1; then
+ PATH=/bin:/usr/bin
+ export PATH
+ if ! type "${NM}" > /dev/null 2>&1; then
+ echo "lorder: ${NM}: not found"
+ exit 1
+ fi
+fi
+cmd='set `type "${NM}"` ; eval echo \$$#'
+NM=`eval $cmd`
+
+# only one argument is a special case, just output the name twice
+case $# in
+ 0)
+ echo "usage: lorder file ...";
+ exit ;;
+ 1)
+ echo $1 $1;
+ exit ;;
+esac
+
+# temporary files
+R=/tmp/_reference_$$
+S=/tmp/_symbol_$$
+
+# remove temporary files on HUP, INT, QUIT, PIPE, TERM
+trap "rm -f $R $S; exit 1" 1 2 3 13 15
+
+# if the line ends in a colon, assume it's the first occurrence of a new
+# object file. Echo it twice, just to make sure it gets into the output.
+#
+# if the line has " T " or " D " it's a globally defined symbol, put it
+# into the symbol file.
+#
+# if the line has " U " it's a globally undefined symbol, put it into
+# the reference file.
+(for file in $* ; do echo $file":" ; done ; $NM -go $*) | sed "
+ /:$/ {
+ s/://
+ s/.*/& &/
+ p
+ d
+ }
+ / [TDGR] / {
+ s/:.* [TDGR] / /
+ w $S
+ d
+ }
+ / U / {
+ s/:.* U / /
+ w $R
+ }
+ d
+"
+
+# sort symbols and references on the first field (the symbol)
+# join on that field, and print out the file names.
+sort -k 2 $R -o $R
+sort -k 2 $S -o $S
+join -j 2 -o "1.1 2.1" $R $S
+rm -f $R $S
diff --git a/developer_cmds/rpcgen/rpc_clntout.c b/developer_cmds/rpcgen/rpc_clntout.c
new file mode 100644
index 0000000..e0d2263
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_clntout.c
@@ -0,0 +1,230 @@
+/* $NetBSD: rpc_clntout.c,v 1.8 1997/10/18 10:53:37 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_clntout.c,v 1.8 1997/10/18 10:53:37 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
+ * Copyright (C) 1987, Sun Microsytsems, Inc.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <rpc/types.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+static void write_program __P((definition *));
+static char *ampr __P((char *));
+static void printbody __P((proc_list *));
+
+#define DEFAULT_TIMEOUT 25 /* in seconds */
+static char RESULT[] = "clnt_res";
+
+
+void
+write_stubs()
+{
+ list *l;
+ definition *def;
+
+ f_print(fout,
+ "\n/* Default timeout can be changed using clnt_control() */\n");
+ f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
+ DEFAULT_TIMEOUT);
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ write_program(def);
+ }
+ }
+}
+
+static void
+write_program(def)
+ definition *def;
+{
+ version_list *vp;
+ proc_list *proc;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\n");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*\n");
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, "clnt", "CLIENT *");
+ f_print(fout, "{\n");
+ printbody(proc);
+ f_print(fout, "}\n");
+ }
+ }
+}
+/* Writes out declarations of procedure's argument list.
+ In either ANSI C style, in one of old rpcgen style (pass by reference),
+ or new rpcgen style (multiple arguments, pass by value);
+ */
+
+/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
+
+void
+printarglist(proc, addargname, addargtype)
+ proc_list *proc;
+ char *addargname, *addargtype;
+{
+
+ decl_list *l;
+
+ if (!newstyle) { /* old style: always pass argument by
+ * reference */
+ if (Cflag) { /* C++ style heading */
+ f_print(fout, "(");
+ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+ f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
+ } else {
+ f_print(fout, "(argp, %s)\n", addargname);
+ f_print(fout, "\t");
+ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+ f_print(fout, "*argp;\n");
+ }
+ } else
+ if (streq(proc->args.decls->decl.type, "void")) {
+ /* newstyle, 0 argument */
+ if (Cflag)
+ f_print(fout, "(%s%s)\n", addargtype, addargname);
+ else
+ f_print(fout, "(%s)\n", addargname);
+ } else {
+ /* new style, 1 or multiple arguments */
+ if (!Cflag) {
+ f_print(fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ f_print(fout, "%s, ", l->decl.name);
+ f_print(fout, "%s)\n", addargname);
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ pdeclaration(proc->args.argname, &l->decl, 1, ";\n");
+ }
+ } else {/* C++ style header */
+ f_print(fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ pdeclaration(proc->args.argname, &l->decl, 0, ", ");
+ }
+ f_print(fout, " %s%s)\n", addargtype, addargname);
+ }
+ }
+
+ if (!Cflag)
+ f_print(fout, "\t%s%s;\n", addargtype, addargname);
+}
+
+
+
+static char *
+ampr(type)
+ char *type;
+{
+ if (isvectordef(type, REL_ALIAS)) {
+ return ("");
+ } else {
+ return ("&");
+ }
+}
+
+static void
+printbody(proc)
+ proc_list *proc;
+{
+ decl_list *l;
+ bool_t args2 = (proc->arg_num > 1);
+
+ /* For new style with multiple arguments, need a structure in which to
+ * stuff the arguments. */
+ if (newstyle && args2) {
+ f_print(fout, "\t%s", proc->args.argname);
+ f_print(fout, " arg;\n");
+ }
+ f_print(fout, "\tstatic ");
+ if (streq(proc->res_type, "void")) {
+ f_print(fout, "char ");
+ } else {
+ ptype(proc->res_prefix, proc->res_type, 0);
+ }
+ f_print(fout, "%s;\n", RESULT);
+ f_print(fout, "\n");
+ f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
+ ampr(proc->res_type), RESULT, RESULT);
+ if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) {
+ /* newstyle, 0 arguments */
+ f_print(fout,
+ "\tif (clnt_call(clnt, %s, xdr_void", proc->proc_name);
+ f_print(fout,
+ ", NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
+ stringfix(proc->res_type), ampr(proc->res_type), RESULT);
+
+ } else
+ if (newstyle && args2) {
+ /* newstyle, multiple arguments: stuff arguments into
+ * structure */
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ f_print(fout, "\targ.%s = %s;\n",
+ l->decl.name, l->decl.name);
+ }
+ f_print(fout,
+ "\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
+ proc->proc_name,
+ proc->args.argname,
+ stringfix(proc->res_type),
+ ampr(proc->res_type), RESULT);
+ } else { /* single argument, new or old style */
+ f_print(fout,
+ "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
+ proc->proc_name,
+ stringfix(proc->args.decls->decl.type),
+ (newstyle ? "&" : ""),
+ (newstyle ? proc->args.decls->decl.name : "argp"),
+ stringfix(proc->res_type),
+ ampr(proc->res_type), RESULT);
+ }
+ f_print(fout, "\t\treturn (NULL);\n");
+ if (streq(proc->res_type, "void")) {
+ f_print(fout, "\treturn ((void *)%s%s);\n",
+ ampr(proc->res_type), RESULT);
+ } else {
+ f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type), RESULT);
+ }
+}
diff --git a/developer_cmds/rpcgen/rpc_cout.c b/developer_cmds/rpcgen/rpc_cout.c
new file mode 100644
index 0000000..ca4eb7b
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_cout.c
@@ -0,0 +1,741 @@
+/* $NetBSD: rpc_cout.c,v 1.14 1998/08/25 20:59:40 ross Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_cout.c,v 1.14 1998/08/25 20:59:40 ross Exp $");
+#endif
+#endif
+
+/*
+ * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+static int findtype __P((definition *, char *));
+static int undefined __P((char *));
+static void print_generic_header __P((char *, int));
+static void print_header __P((definition *));
+static void print_prog_header __P((proc_list *));
+static void print_trailer __P((void));
+static void print_ifopen __P((int, char *));
+static void print_ifarg __P((char *));
+static void print_ifsizeof __P((char *, char *));
+static void print_ifclose __P((int));
+static void print_ifstat __P((int, char *, char *, relation, char *, char *, char *));
+static void emit_enum __P((definition *));
+static void emit_program __P((definition *));
+static void emit_union __P((definition *));
+static void emit_struct __P((definition *));
+static void emit_typedef __P((definition *));
+static void print_stat __P((int, declaration *));
+
+/*
+ * Emit the C-routine for the given definition
+ */
+void
+emit(def)
+ definition *def;
+{
+ if (def->def_kind == DEF_CONST) {
+ return;
+ }
+ if (def->def_kind == DEF_PROGRAM) {
+ emit_program(def);
+ return;
+ }
+ if (def->def_kind == DEF_TYPEDEF) {
+ /* now we need to handle declarations like struct typedef foo
+ * foo; since we dont want this to be expanded into 2 calls to
+ * xdr_foo */
+
+ if (strcmp(def->def.ty.old_type, def->def_name) == 0)
+ return;
+ };
+
+ print_header(def);
+
+ switch (def->def_kind) {
+ case DEF_UNION:
+ emit_union(def);
+ break;
+ case DEF_ENUM:
+ emit_enum(def);
+ break;
+ case DEF_STRUCT:
+ emit_struct(def);
+ break;
+ case DEF_TYPEDEF:
+ emit_typedef(def);
+ break;
+ case DEF_PROGRAM:
+ case DEF_CONST:
+ errx(1, "Internal error %s, %d: Case %d not handled\n",
+ __FILE__, __LINE__, def->def_kind);
+ break;
+ }
+ print_trailer();
+}
+
+static int
+findtype(def, type)
+ definition *def;
+ char *type;
+{
+
+ if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
+ return (0);
+ } else {
+ return (streq(def->def_name, type));
+ }
+}
+
+static int
+undefined(type)
+ char *type;
+{
+ definition *def;
+
+ def = (definition *) FINDVAL(defined, type, findtype);
+
+
+ return (def == NULL);
+}
+
+static void
+print_generic_header(procname, pointerp)
+ char *procname;
+ int pointerp;
+{
+ f_print(fout, "\n");
+ f_print(fout, "bool_t\n");
+ if (Cflag) {
+ f_print(fout, "xdr_%s(", procname);
+ f_print(fout, "XDR *xdrs, ");
+ f_print(fout, "%s ", procname);
+ if (pointerp)
+ f_print(fout, "*");
+ f_print(fout, "objp)\n{\n");
+ } else {
+ f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
+ f_print(fout, "\tXDR *xdrs;\n");
+ f_print(fout, "\t%s ", procname);
+ if (pointerp)
+ f_print(fout, "*");
+ f_print(fout, "objp;\n{\n");
+ }
+}
+
+static void
+print_header(def)
+ definition *def;
+{
+ print_generic_header(def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef(def->def.ty.old_type, def->def.ty.rel));
+}
+
+static void
+print_prog_header(plist)
+ proc_list *plist;
+{
+ print_generic_header(plist->args.argname, 1);
+}
+
+static void
+print_trailer()
+{
+ f_print(fout, "\treturn (TRUE);\n");
+ f_print(fout, "}\n");
+}
+
+
+static void
+print_ifopen(indent, name)
+ int indent;
+ char *name;
+{
+ tabify(fout, indent);
+ f_print(fout, "if (!xdr_%s(xdrs", name);
+}
+
+static void
+print_ifarg(arg)
+ char *arg;
+{
+ f_print(fout, ", %s", arg);
+}
+
+static void
+print_ifsizeof(prefix, type)
+ char *prefix;
+ char *type;
+{
+ if (streq(type, "bool")) {
+ f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
+ } else {
+ f_print(fout, ", sizeof(");
+ if (undefined(type) && prefix) {
+ f_print(fout, "%s ", prefix);
+ }
+ f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
+ }
+}
+
+static void
+print_ifclose(indent)
+ int indent;
+{
+ f_print(fout, "))\n");
+ tabify(fout, indent);
+ f_print(fout, "\treturn (FALSE);\n");
+}
+
+static void
+print_ifstat(indent, prefix, type, rel, amax, objname, name)
+ int indent;
+ char *prefix;
+ char *type;
+ relation rel;
+ char *amax;
+ char *objname;
+ char *name;
+{
+ char *alt = NULL;
+
+ switch (rel) {
+ case REL_POINTER:
+ print_ifopen(indent, "pointer");
+ print_ifarg("(char **)");
+ f_print(fout, "%s", objname);
+ print_ifsizeof(prefix, type);
+ break;
+ case REL_VECTOR:
+ if (streq(type, "string")) {
+ alt = "string";
+ } else
+ if (streq(type, "opaque")) {
+ alt = "opaque";
+ }
+ if (alt) {
+ print_ifopen(indent, alt);
+ print_ifarg(objname);
+ } else {
+ print_ifopen(indent, "vector");
+ print_ifarg("(char *)");
+ f_print(fout, "%s", objname);
+ }
+ print_ifarg(amax);
+ if (!alt) {
+ print_ifsizeof(prefix, type);
+ }
+ break;
+ case REL_ARRAY:
+ if (streq(type, "string")) {
+ alt = "string";
+ } else
+ if (streq(type, "opaque")) {
+ alt = "bytes";
+ }
+ if (streq(type, "string")) {
+ print_ifopen(indent, alt);
+ print_ifarg(objname);
+ } else {
+ if (alt) {
+ print_ifopen(indent, alt);
+ } else {
+ print_ifopen(indent, "array");
+ }
+ print_ifarg("(char **)");
+ if (*objname == '&') {
+ f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
+ objname, name, objname, name);
+ } else {
+ f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
+ objname, name, objname, name);
+ }
+ }
+ print_ifarg(amax);
+ if (!alt) {
+ print_ifsizeof(prefix, type);
+ }
+ break;
+ case REL_ALIAS:
+ print_ifopen(indent, type);
+ print_ifarg(objname);
+ break;
+ }
+ print_ifclose(indent);
+}
+/* ARGSUSED */
+static void
+emit_enum(def)
+ definition *def;
+{
+ fprintf(fout, "\n");
+ print_ifopen(1, "enum");
+ print_ifarg("(enum_t *)objp");
+ print_ifclose(1);
+}
+
+static void
+emit_program(def)
+ definition *def;
+{
+ decl_list *dl;
+ version_list *vlist;
+ proc_list *plist;
+
+ for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
+ for (plist = vlist->procs; plist != NULL; plist = plist->next) {
+ if (!newstyle || plist->arg_num < 2)
+ continue; /* old style, or single
+ * argument */
+ print_prog_header(plist);
+ for (dl = plist->args.decls; dl != NULL;
+ dl = dl->next)
+ print_stat(1, &dl->decl);
+ print_trailer();
+ }
+}
+
+
+static void
+emit_union(def)
+ definition *def;
+{
+ declaration *dflt;
+ case_list *cl;
+ declaration *cs;
+ char *object;
+ char *vecformat = "objp->%s_u.%s";
+ char *format = "&objp->%s_u.%s";
+
+ f_print(fout, "\n");
+ print_stat(1, &def->def.un.enum_decl);
+ f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
+ for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
+ f_print(fout, "\tcase %s:\n", cl->case_name);
+ if (cl->contflag == 1) /* a continued case statement */
+ continue;
+ cs = &cl->case_decl;
+ if (!streq(cs->type, "void")) {
+ object = alloc(strlen(def->def_name) + strlen(format) +
+ strlen(cs->name) + 1);
+ if (isvectordef(cs->type, cs->rel)) {
+ s_print(object, vecformat, def->def_name,
+ cs->name);
+ } else {
+ s_print(object, format, def->def_name,
+ cs->name);
+ }
+ print_ifstat(2, cs->prefix, cs->type, cs->rel,
+ cs->array_max, object, cs->name);
+ free(object);
+ }
+ f_print(fout, "\t\tbreak;\n");
+ }
+ dflt = def->def.un.default_decl;
+ f_print(fout, "\tdefault:\n");
+ if (dflt != NULL) {
+ if (!streq(dflt->type, "void")) {
+ object = alloc(strlen(def->def_name) + strlen(format) +
+ strlen(dflt->name) + 1);
+ if (isvectordef(dflt->type, dflt->rel)) {
+ s_print(object, vecformat, def->def_name,
+ dflt->name);
+ } else {
+ s_print(object, format, def->def_name,
+ dflt->name);
+ }
+ print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
+ dflt->array_max, object, dflt->name);
+ free(object);
+ }
+ f_print(fout, "\t\tbreak;\n");
+ } else {
+ f_print(fout, "\t\treturn (FALSE);\n");
+ }
+
+ f_print(fout, "\t}\n");
+}
+
+static void
+emit_struct(def)
+ definition *def;
+{
+ decl_list *dl;
+ int i, j, size, flag;
+ decl_list *cur = NULL, *psav;
+ bas_type *ptr;
+ char *sizestr, *plus;
+ char ptemp[256];
+ int can_inline;
+
+
+ if (doinline == 0) {
+ fprintf(fout, "\n");
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(1, &dl->decl);
+ return;
+ }
+ size = 0;
+ can_inline = 0;
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ if ((dl->decl.prefix == NULL) &&
+ ((ptr = find_type(dl->decl.type)) != NULL) &&
+ ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
+
+ if (dl->decl.rel == REL_ALIAS)
+ size += ptr->length;
+ else {
+ can_inline = 1;
+ break; /* can be inlined */
+ };
+ } else {
+ if (size >= doinline) {
+ can_inline = 1;
+ break; /* can be inlined */
+ }
+ size = 0;
+ }
+ if (size > doinline)
+ can_inline = 1;
+
+ if (can_inline == 0) { /* can not inline, drop back to old mode */
+ fprintf(fout, "\n");
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(1, &dl->decl);
+ return;
+ };
+
+ /* May cause lint to complain. but ... */
+ f_print(fout, "\tint32_t *buf;\n");
+
+ flag = PUT;
+ f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
+
+ for (j = 0; j < 2; j++) {
+ i = 0;
+ size = 0;
+ sizestr = NULL;
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
+
+ /* now walk down the list and check for basic types */
+ if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
+ if (i == 0)
+ cur = dl;
+ i++;
+
+ if (dl->decl.rel == REL_ALIAS)
+ size += ptr->length;
+ else {
+ /* this is required to handle arrays */
+
+ if (sizestr == NULL)
+ plus = "";
+ else
+ plus = " + ";
+
+ if (ptr->length != 1)
+ s_print(ptemp, "%s%s * %d", plus, dl->decl.array_max, ptr->length);
+ else
+ s_print(ptemp, "%s%s", plus, dl->decl.array_max);
+
+ /* now concatenate to sizestr !!!! */
+ if (sizestr == NULL)
+ sizestr = strdup(ptemp);
+ else {
+ sizestr = (char *) realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
+ if (sizestr == NULL) {
+
+ f_print(stderr, "Fatal error : no memory\n");
+ crash();
+ };
+ sizestr = strcat(sizestr, ptemp); /* build up length of
+ * array */
+
+ }
+ }
+
+ } else {
+ if (i > 0) {
+ if (sizestr == NULL && size < doinline) {
+ /* don't expand into inline
+ * code if size < doinline */
+ while (cur != dl) {
+ print_stat(2, &cur->decl);
+ cur = cur->next;
+ }
+ } else {
+
+
+
+ /* were already looking at a
+ * xdr_inlineable structure */
+ if (sizestr == NULL)
+ f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
+ size);
+ else
+ if (size == 0)
+ f_print(fout,
+ "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
+ sizestr);
+ else
+ f_print(fout,
+ "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
+ size, sizestr);
+
+ f_print(fout, "\t\tif (buf == NULL) {\n");
+
+ psav = cur;
+ while (cur != dl) {
+ print_stat(3, &cur->decl);
+ cur = cur->next;
+ }
+
+ f_print(fout, "\t\t} else {\n");
+
+ cur = psav;
+ while (cur != dl) {
+ emit_inline(&cur->decl, flag);
+ cur = cur->next;
+ }
+
+ f_print(fout, "\t\t}\n");
+ }
+ }
+ size = 0;
+ i = 0;
+ sizestr = NULL;
+ print_stat(2, &dl->decl);
+ }
+
+ }
+ if (i > 0) {
+ if (sizestr == NULL && size < doinline) {
+ /* don't expand into inline code if size <
+ * doinline */
+ while (cur != dl) {
+ print_stat(2, &cur->decl);
+ cur = cur->next;
+ }
+ } else {
+
+ /* were already looking at a xdr_inlineable
+ * structure */
+ if (sizestr == NULL)
+ f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
+ size);
+ else
+ if (size == 0)
+ f_print(fout,
+ "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
+ sizestr);
+ else
+ f_print(fout,
+ "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
+ size, sizestr);
+
+ f_print(fout, "\t\tif (buf == NULL) {\n");
+
+ psav = cur;
+ while (cur != NULL) {
+ print_stat(3, &cur->decl);
+ cur = cur->next;
+ }
+ f_print(fout, "\t\t} else {\n");
+
+ cur = psav;
+ while (cur != dl) {
+ emit_inline(&cur->decl, flag);
+ cur = cur->next;
+ }
+
+ f_print(fout, "\t\t}\n");
+
+ }
+ }
+ if (flag == PUT) {
+ flag = GET;
+ f_print(fout, "\t} else if (xdrs->x_op == XDR_DECODE) {\n");
+ }
+ }
+
+ f_print(fout, "\t} else {\n");
+
+ /* now take care of XDR_FREE case */
+
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(2, &dl->decl);
+
+ f_print(fout, "\t}\n");
+}
+
+static void
+emit_typedef(def)
+ definition *def;
+{
+ char *prefix = def->def.ty.old_prefix;
+ char *type = def->def.ty.old_type;
+ char *amax = def->def.ty.array_max;
+ relation rel = def->def.ty.rel;
+
+ fprintf(fout, "\n");
+ print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
+}
+
+static void
+print_stat(indent, dec)
+ declaration *dec;
+ int indent;
+{
+ char *prefix = dec->prefix;
+ char *type = dec->type;
+ char *amax = dec->array_max;
+ relation rel = dec->rel;
+ char name[256];
+
+ if (isvectordef(type, rel)) {
+ s_print(name, "objp->%s", dec->name);
+ } else {
+ s_print(name, "&objp->%s", dec->name);
+ }
+ print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
+}
+
+
+void
+emit_inline(decl, flag)
+ declaration *decl;
+ int flag;
+{
+
+/*check whether an array or not */
+
+ switch (decl->rel) {
+ case REL_ALIAS:
+ emit_single_in_line(decl, flag, REL_ALIAS);
+ break;
+ case REL_VECTOR:
+ f_print(fout, "\t\t\t{\n");
+ f_print(fout, "\t\t\t\tint i;\n");
+ f_print(fout, "\t\t\t\t%s *genp;\n", decl->type);
+ f_print(fout, "\n");
+ f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n",
+ decl->name);
+ f_print(fout, "\t\t\t\t i < %s; i++) {\n\t\t",
+ decl->array_max);
+ emit_single_in_line(decl, flag, REL_VECTOR);
+ f_print(fout, "\t\t\t\t}\n\t\t\t}\n");
+ break;
+ case REL_ARRAY:
+ case REL_POINTER:
+ errx(1, "Internal error %s, %d: Case %d not handled\n",
+ __FILE__, __LINE__, decl->rel);
+ }
+}
+
+void
+emit_single_in_line(decl, flag, rel)
+ declaration *decl;
+ int flag;
+ relation rel;
+{
+ char *upp_case;
+ int freed = 0;
+
+ if (flag == PUT)
+ f_print(fout, "\t\t\tIXDR_PUT_");
+ else
+ if (rel == REL_ALIAS)
+ f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name);
+ else
+ f_print(fout, "\t\t\t*genp++ = IXDR_GET_");
+
+ upp_case = upcase(decl->type);
+
+ /* hack - XX */
+ if (strcmp(upp_case, "INT") == 0) {
+ free(upp_case);
+ freed = 1;
+ upp_case = "LONG";
+ }
+ if (strcmp(upp_case, "U_INT") == 0) {
+ free(upp_case);
+ freed = 1;
+ upp_case = "U_LONG";
+ }
+ if (flag == PUT)
+ if (rel == REL_ALIAS)
+ f_print(fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
+ else
+ f_print(fout, "%s(buf, *genp++);\n", upp_case);
+
+ else
+ f_print(fout, "%s(buf);\n", upp_case);
+ if (!freed)
+ free(upp_case);
+
+}
+
+
+char *
+upcase(str)
+ char *str;
+{
+ char *ptr, *hptr;
+
+
+ ptr = (char *) malloc(strlen(str) + 1);
+ if (ptr == (char *) NULL) {
+ f_print(stderr, "malloc failed\n");
+ exit(1);
+ };
+
+ hptr = ptr;
+ while (*str != '\0')
+ *ptr++ = toupper(*str++);
+
+ *ptr = '\0';
+ return (hptr);
+
+}
diff --git a/developer_cmds/rpcgen/rpc_hout.c b/developer_cmds/rpcgen/rpc_hout.c
new file mode 100644
index 0000000..3b8811f
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_hout.c
@@ -0,0 +1,534 @@
+/* $NetBSD: rpc_hout.c,v 1.9 1998/02/11 23:11:17 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_hout.c,v 1.9 1998/02/11 23:11:17 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_hout.c, Header file outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <err.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+static void pconstdef __P((definition *));
+static void pargdef __P((definition *));
+static void pstructdef __P((definition *));
+static void puniondef __P((definition *));
+static void pdefine __P((char *, char *));
+static void puldefine __P((char *, char *));
+static int define_printed __P((proc_list *, version_list *));
+static void pprogramdef __P((definition *));
+static void parglist __P((proc_list *, char *));
+static void penumdef __P((definition *));
+static void ptypedef __P((definition *));
+static int undefined2 __P((char *, char *));
+
+/*
+ * Print the C-version of an xdr definition
+ */
+void
+print_datadef(def)
+ definition *def;
+{
+
+ if (def->def_kind == DEF_PROGRAM) /* handle data only */
+ return;
+
+ if (def->def_kind != DEF_CONST) {
+ f_print(fout, "\n");
+ }
+ switch (def->def_kind) {
+ case DEF_STRUCT:
+ pstructdef(def);
+ break;
+ case DEF_UNION:
+ puniondef(def);
+ break;
+ case DEF_ENUM:
+ penumdef(def);
+ break;
+ case DEF_TYPEDEF:
+ ptypedef(def);
+ break;
+ case DEF_PROGRAM:
+ pprogramdef(def);
+ break;
+ case DEF_CONST:
+ pconstdef(def);
+ break;
+ }
+ if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
+ pxdrfuncdecl(def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef(def->def.ty.old_type, def->def.ty.rel));
+
+ }
+}
+
+
+void
+print_funcdef(def)
+ definition *def;
+{
+ switch (def->def_kind) {
+ case DEF_PROGRAM:
+ f_print(fout, "\n");
+ pprogramdef(def);
+ break;
+ case DEF_CONST:
+ case DEF_TYPEDEF:
+ case DEF_ENUM:
+ case DEF_UNION:
+ case DEF_STRUCT:
+ break;
+ }
+}
+
+void
+pxdrfuncdecl(name, pointerp)
+ char *name;
+ int pointerp;
+{
+
+ f_print(fout, "#ifdef __cplusplus\n");
+ f_print(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n",
+ name,
+ name, pointerp ? ("*") : "");
+ f_print(fout, "#elif __STDC__\n");
+ f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n",
+ name,
+ name, pointerp ? ("*") : "");
+ f_print(fout, "#else /* Old Style C */\n");
+ f_print(fout, "bool_t xdr_%s();\n", name);
+ f_print(fout, "#endif /* Old Style C */\n\n");
+}
+
+
+static void
+pconstdef(def)
+ definition *def;
+{
+ pdefine(def->def_name, def->def.co);
+}
+/* print out the definitions for the arguments of functions in the
+ header file
+*/
+static void
+pargdef(def)
+ definition *def;
+{
+ decl_list *l;
+ version_list *vers;
+ char *name;
+ proc_list *plist;
+
+
+ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+ for (plist = vers->procs; plist != NULL;
+ plist = plist->next) {
+
+ if (!newstyle || plist->arg_num < 2) {
+ continue; /* old style or single args */
+ }
+ name = plist->args.argname;
+ f_print(fout, "struct %s {\n", name);
+ for (l = plist->args.decls;
+ l != NULL; l = l->next) {
+ pdeclaration(name, &l->decl, 1, ";\n");
+ }
+ f_print(fout, "};\n");
+ f_print(fout, "typedef struct %s %s;\n", name, name);
+ pxdrfuncdecl(name, 0);
+ f_print(fout, "\n");
+ }
+ }
+
+}
+
+
+static void
+pstructdef(def)
+ definition *def;
+{
+ decl_list *l;
+ char *name = def->def_name;
+
+ f_print(fout, "struct %s {\n", name);
+ for (l = def->def.st.decls; l != NULL; l = l->next) {
+ pdeclaration(name, &l->decl, 1, ";\n");
+ }
+ f_print(fout, "};\n");
+ f_print(fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+puniondef(def)
+ definition *def;
+{
+ case_list *l;
+ char *name = def->def_name;
+ declaration *decl;
+
+ f_print(fout, "struct %s {\n", name);
+ decl = &def->def.un.enum_decl;
+ if (streq(decl->type, "bool")) {
+ f_print(fout, "\tbool_t %s;\n", decl->name);
+ } else {
+ f_print(fout, "\t%s %s;\n", decl->type, decl->name);
+ }
+ f_print(fout, "\tunion {\n");
+ for (l = def->def.un.cases; l != NULL; l = l->next) {
+ if (l->contflag == 0)
+ pdeclaration(name, &l->case_decl, 2, ";\n");
+ }
+ decl = def->def.un.default_decl;
+ if (decl && !streq(decl->type, "void")) {
+ pdeclaration(name, decl, 2, ";\n");
+ }
+ f_print(fout, "\t} %s_u;\n", name);
+ f_print(fout, "};\n");
+ f_print(fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+pdefine(name, num)
+ char *name;
+ char *num;
+{
+ f_print(fout, "#define %s %s\n", name, num);
+}
+
+static void
+puldefine(name, num)
+ char *name;
+ char *num;
+{
+ f_print(fout, "#define %s ((rpc_uint)%s)\n", name, num);
+}
+
+static int
+define_printed(stop, start)
+ proc_list *stop;
+ version_list *start;
+{
+ version_list *vers;
+ proc_list *proc;
+
+ for (vers = start; vers != NULL; vers = vers->next) {
+ for (proc = vers->procs; proc != NULL; proc = proc->next) {
+ if (proc == stop) {
+ return (0);
+ } else
+ if (streq(proc->proc_name, stop->proc_name)) {
+ return (1);
+ }
+ }
+ }
+ errx(1, "Internal error %s, %d: procedure not found\n",
+ __FILE__, __LINE__);
+ /* NOTREACHED */
+}
+
+static void
+pprogramdef(def)
+ definition *def;
+{
+ version_list *vers;
+ proc_list *proc;
+ int i;
+ char *ext;
+
+ pargdef(def);
+
+ puldefine(def->def_name, def->def.pr.prog_num);
+ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+ if (tblflag) {
+ f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
+ locase(def->def_name), vers->vers_num);
+ f_print(fout, "extern %s_%s_nproc;\n",
+ locase(def->def_name), vers->vers_num);
+ }
+ puldefine(vers->vers_name, vers->vers_num);
+
+ /* Print out 3 definitions, one for ANSI-C, another for C++, a
+ * third for old style C */
+
+ for (i = 0; i < 3; i++) {
+ if (i == 0) {
+ f_print(fout, "\n#ifdef __cplusplus\n");
+ ext = "extern \"C\" ";
+ } else
+ if (i == 1) {
+ f_print(fout, "\n#elif __STDC__\n");
+ ext = "extern ";
+ } else {
+ f_print(fout, "\n#else /* Old Style C */\n");
+ ext = "extern ";
+ }
+
+
+ for (proc = vers->procs; proc != NULL; proc = proc->next) {
+ if (!define_printed(proc, def->def.pr.versions)) {
+ puldefine(proc->proc_name, proc->proc_num);
+ }
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, "CLIENT *", 0, i);
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, "struct svc_req *", 1, i);
+
+ }
+
+ }
+ f_print(fout, "#endif /* Old Style C */\n");
+ }
+}
+
+void
+pprocdef(proc, vp, addargtype, server_p, mode)
+ proc_list *proc;
+ version_list *vp;
+ char *addargtype;
+ int server_p;
+ int mode;
+{
+
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "* ");
+ if (server_p)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+
+ /*
+ * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C
+ */
+ if (mode == 0 || mode == 1)
+ parglist(proc, addargtype);
+ else
+ f_print(fout, "();\n");
+}
+
+
+/* print out argument list of procedure */
+static void
+parglist(proc, addargtype)
+ proc_list *proc;
+ char *addargtype;
+{
+ decl_list *dl;
+
+ f_print(fout, "(");
+
+ if (proc->arg_num < 2 && newstyle &&
+ streq(proc->args.decls->decl.type, "void")) {
+ /* 0 argument in new style: do nothing */
+ } else {
+ for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
+ ptype(dl->decl.prefix, dl->decl.type, 1);
+ if (!newstyle)
+ f_print(fout, "*"); /* old style passes by
+ * reference */
+
+ f_print(fout, ", ");
+ }
+ }
+
+ f_print(fout, "%s);\n", addargtype);
+}
+
+static void
+penumdef(def)
+ definition *def;
+{
+ char *name = def->def_name;
+ enumval_list *l;
+ char *last = NULL;
+ int count = 0;
+
+ f_print(fout, "enum %s {\n", name);
+ for (l = def->def.en.vals; l != NULL; l = l->next) {
+ f_print(fout, "\t%s", l->name);
+ if (l->assignment) {
+ f_print(fout, " = %s", l->assignment);
+ last = l->assignment;
+ count = 1;
+ } else {
+ if (last == NULL) {
+ f_print(fout, " = %d", count++);
+ } else {
+ f_print(fout, " = %s + %d", last, count++);
+ }
+ }
+ f_print(fout, ",\n");
+ }
+ f_print(fout, "};\n");
+ f_print(fout, "typedef enum %s %s;\n", name, name);
+}
+
+static void
+ptypedef(def)
+ definition *def;
+{
+ char *name = def->def_name;
+ char *old = def->def.ty.old_type;
+ char prefix[8]; /* enough to contain "struct ", including NUL */
+ relation rel = def->def.ty.rel;
+
+
+ if (!streq(name, old)) {
+ if (streq(old, "string")) {
+ old = "char";
+ rel = REL_POINTER;
+ } else
+ if (streq(old, "opaque")) {
+ old = "char";
+ } else
+ if (streq(old, "bool")) {
+ old = "bool_t";
+ }
+ if (undefined2(old, name) && def->def.ty.old_prefix) {
+ s_print(prefix, "%s ", def->def.ty.old_prefix);
+ } else {
+ prefix[0] = 0;
+ }
+ f_print(fout, "typedef ");
+ switch (rel) {
+ case REL_ARRAY:
+ f_print(fout, "struct {\n");
+ f_print(fout, "\tu_int %s_len;\n", name);
+ f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
+ f_print(fout, "} %s", name);
+ break;
+ case REL_POINTER:
+ f_print(fout, "%s%s *%s", prefix, old, name);
+ break;
+ case REL_VECTOR:
+ f_print(fout, "%s%s %s[%s]", prefix, old, name,
+ def->def.ty.array_max);
+ break;
+ case REL_ALIAS:
+ f_print(fout, "%s%s %s", prefix, old, name);
+ break;
+ }
+ f_print(fout, ";\n");
+ }
+}
+
+void
+pdeclaration(name, dec, tab, separator)
+ char *name;
+ declaration *dec;
+ int tab;
+ char *separator;
+{
+ char buf[8]; /* enough to hold "struct ", include NUL */
+ char *prefix;
+ char *type;
+
+ if (streq(dec->type, "void")) {
+ return;
+ }
+ tabify(fout, tab);
+ if (streq(dec->type, name) && !dec->prefix) {
+ f_print(fout, "struct ");
+ }
+ if (streq(dec->type, "string")) {
+ f_print(fout, "char *%s", dec->name);
+ } else {
+ prefix = "";
+ if (streq(dec->type, "bool")) {
+ type = "bool_t";
+ } else
+ if (streq(dec->type, "opaque")) {
+ type = "char";
+ } else {
+ if (dec->prefix) {
+ s_print(buf, "%s ", dec->prefix);
+ prefix = buf;
+ }
+ type = dec->type;
+ }
+ switch (dec->rel) {
+ case REL_ALIAS:
+ f_print(fout, "%s%s %s", prefix, type, dec->name);
+ break;
+ case REL_VECTOR:
+ f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
+ dec->array_max);
+ break;
+ case REL_POINTER:
+ f_print(fout, "%s%s *%s", prefix, type, dec->name);
+ break;
+ case REL_ARRAY:
+ f_print(fout, "struct {\n");
+ tabify(fout, tab);
+ f_print(fout, "\tu_int %s_len;\n", dec->name);
+ tabify(fout, tab);
+ f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
+ tabify(fout, tab);
+ f_print(fout, "} %s", dec->name);
+ break;
+ }
+ }
+ f_print(fout, "%s", separator);
+}
+
+static int
+undefined2(type, stop)
+ char *type;
+ char *stop;
+{
+ list *l;
+ definition *def;
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ if (streq(def->def_name, stop)) {
+ return (1);
+ } else
+ if (streq(def->def_name, type)) {
+ return (0);
+ }
+ }
+ }
+ return (1);
+}
diff --git a/developer_cmds/rpcgen/rpc_main.c b/developer_cmds/rpcgen/rpc_main.c
new file mode 100644
index 0000000..a7a15a8
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_main.c
@@ -0,0 +1,1170 @@
+/* $NetBSD: rpc_main.c,v 1.14 1997/10/18 10:53:53 lukem Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_main.c,v 1.14 1997/10/18 10:53:53 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_main.c, Top level of the RPC protocol compiler.
+ */
+
+#define RPCGEN_VERSION "199506"/* This program's version (year & month) */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+#include <sys/types.h>
+#ifdef __TURBOC__
+#define MAXPATHLEN 80
+#include <process.h>
+#include <dir.h>
+#else
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define EXTEND 1 /* alias for TRUE */
+#define DONT_EXTEND 0 /* alias for FALSE */
+
+#define SVR4_CPP "/usr/ccs/lib/cpp"
+#define SUNOS_CPP "/lib/cpp"
+static int cppDefined = 0; /* explicit path for C preprocessor */
+
+struct commandline {
+ int cflag; /* xdr C routines */
+ int hflag; /* header file */
+ int lflag; /* client side stubs */
+ int mflag; /* server side stubs */
+ int nflag; /* netid flag */
+ int sflag; /* server stubs for the given transport */
+ int tflag; /* dispatch Table file */
+ int Ssflag; /* produce server sample code */
+ int Scflag; /* produce client sample code */
+ char *infile; /* input module name */
+ char *outfile; /* output module name */
+};
+
+
+static char *cmdname;
+
+static char *svcclosetime = "120";
+static char *CPP = "/usr/bin/cpp";
+static char CPPFLAGS[] = "-C";
+static char pathbuf[MAXPATHLEN + 1];
+static char *allv[] = {
+ "rpcgen", "-s", "udp", "-s", "tcp",
+};
+static int allc = sizeof(allv) / sizeof(allv[0]);
+static char *allnv[] = {
+ "rpcgen", "-s", "netpath",
+};
+static int allnc = sizeof(allnv) / sizeof(allnv[0]);
+
+#define ARGLISTLEN 20
+#define FIXEDARGS 2
+
+static char *arglist[ARGLISTLEN];
+static int argcount = FIXEDARGS;
+
+
+int nonfatalerrors; /* errors */
+int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the default */
+int pmflag; /* Support for port monitors */
+int logflag; /* Use syslog instead of fprintf for errors */
+int tblflag; /* Support for dispatch table file */
+int callerflag; /* Generate svc_caller() function */
+
+#define INLINE 3
+/*length at which to start doing an inline */
+
+int doinline = INLINE; /* length at which to start doing an inline. 3
+ * = default if 0, no xdr_inline code */
+
+int indefinitewait; /* If started by port monitors, hang till it
+ * wants */
+int exitnow; /* If started by port monitors, exit after the
+ * call */
+int timerflag; /* TRUE if !indefinite && !exitnow */
+int newstyle; /* newstyle of passing arguments (by value) */
+int Cflag = 0; /* ANSI C syntax */
+static int allfiles; /* generate all files */
+int tirpcflag = 0; /* generating code for tirpc, by default */
+
+#ifdef __MSDOS__
+static char *dos_cppfile = NULL;
+#endif
+
+int main __P((int, char *[]));
+
+static char *extendfile __P((char *, char *));
+static void open_output __P((char *, char *));
+static void add_warning __P((void));
+static void clear_args __P((void));
+static void find_cpp __P((void));
+static void open_input __P((char *, char *));
+static int check_nettype __P((char *, char *[]));
+static void c_output __P((char *, char *, int, char *));
+static void c_initialize __P((void));
+static char *generate_guard __P((char *));
+static void h_output __P((char *, char *, int, char *));
+static void s_output __P((int, char *[], char *, char *, int, char *, int, int));
+static void l_output __P((char *, char *, int, char *));
+static void t_output __P((char *, char *, int, char *));
+static void svc_output __P((char *, char *, int, char *));
+static void clnt_output __P((char *, char *, int, char *));
+static int do_registers __P((int, char *[]));
+static void addarg __P((char *));
+static void putarg __P((int, char *));
+static void checkfiles __P((char *, char *));
+static int parseargs __P((int, char *[], struct commandline *));
+static void usage __P((void));
+static void options_usage __P((void));
+
+pid_t childpid;
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct commandline cmd;
+
+ (void) memset((char *) &cmd, 0, sizeof(struct commandline));
+ clear_args();
+ if (!parseargs(argc, argv, &cmd))
+ usage();
+
+ if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
+ cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
+ checkfiles(cmd.infile, cmd.outfile);
+ } else
+ checkfiles(cmd.infile, NULL);
+
+ if (cmd.cflag) {
+ c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
+ } else
+ if (cmd.hflag) {
+ h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
+ } else
+ if (cmd.lflag) {
+ l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
+ } else
+ if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
+ s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
+ cmd.outfile, cmd.mflag, cmd.nflag);
+ } else
+ if (cmd.tflag) {
+ t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
+ } else
+ if (cmd.Ssflag) {
+ svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
+ } else
+ if (cmd.Scflag) {
+ clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
+ } else {
+ /* the rescans
+ * are
+ * required,
+ * since cpp
+ * may effect
+ * input */
+ c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
+ reinitialize();
+ h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
+ reinitialize();
+ l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
+ reinitialize();
+ if (inetdflag || !tirpcflag)
+ s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
+ "_svc.c", cmd.mflag, cmd.nflag);
+ else
+ s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
+ EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
+ if (tblflag) {
+ reinitialize();
+ t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
+ }
+ if (allfiles) {
+ reinitialize();
+ svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
+ }
+ if (allfiles) {
+ reinitialize();
+ clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
+ }
+ }
+#ifdef __MSDOS__
+ if (dos_cppfile != NULL) {
+ (void) fclose(fin);
+ (void) unlink(dos_cppfile);
+ }
+#endif
+ exit(nonfatalerrors);
+ /* NOTREACHED */
+}
+/*
+ * add extension to filename
+ */
+static char *
+extendfile(path, ext)
+ char *path;
+ char *ext;
+{
+ char *file;
+ char *res;
+ char *p;
+
+ if ((file = strrchr(path, '/')) == NULL)
+ file = path;
+ else
+ file++;
+
+ res = alloc(strlen(file) + strlen(ext) + 1);
+ if (res == NULL) {
+ errx(1, "Out of memory");
+ }
+ p = strrchr(file, '.');
+ if (p == NULL) {
+ p = file + strlen(file);
+ }
+ (void) strcpy(res, file);
+ (void) strcpy(res + (p - file), ext);
+ return (res);
+}
+/*
+ * Open output file with given extension
+ */
+static void
+open_output(infile, outfile)
+ char *infile;
+ char *outfile;
+{
+
+ if (outfile == NULL) {
+ fout = stdout;
+ return;
+ }
+ if (infile != NULL && streq(outfile, infile)) {
+ f_print(stderr, "%s: output would overwrite %s\n", cmdname,
+ infile);
+ crash();
+ }
+ fout = fopen(outfile, "w");
+ if (fout == NULL) {
+ f_print(stderr, "%s: unable to open ", cmdname);
+ perror(outfile);
+ crash();
+ }
+ record_open(outfile);
+
+}
+
+static void
+add_warning()
+{
+ f_print(fout, "/*\n");
+ f_print(fout, " * Please do not edit this file.\n");
+ f_print(fout, " * It was generated using rpcgen.\n");
+ f_print(fout, " */\n\n");
+}
+/* clear list of arguments */
+static void
+clear_args()
+{
+ int i;
+ for (i = FIXEDARGS; i < ARGLISTLEN; i++)
+ arglist[i] = NULL;
+ argcount = FIXEDARGS;
+}
+/* make sure that a CPP exists */
+static void
+find_cpp()
+{
+ struct stat buf;
+
+ if (stat(CPP, &buf) < 0) { /* SVR4 or explicit cpp does not exist */
+ if (cppDefined) {
+ fprintf(stderr, "cannot find C preprocessor: %s\n", CPP);
+ crash();
+ } else { /* try the other one */
+ CPP = SUNOS_CPP;
+ if (stat(CPP, &buf) < 0) { /* can't find any cpp */
+ fprintf(stderr, "cannot find any C preprocessor (cpp)\n");
+ crash();
+ }
+ }
+ }
+}
+/*
+ * Open input file with given define for C-preprocessor
+ */
+static void
+open_input(infile, define)
+ char *infile;
+ char *define;
+{
+ int pd[2];
+
+ infilename = (infile == NULL) ? "<stdin>" : infile;
+#ifdef __MSDOS__
+#define DOSCPP "\\prog\\bc31\\bin\\cpp.exe"
+ {
+ int retval;
+ char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT];
+ char cppfile[MAXPATH];
+ char *cpp;
+
+ if ((cpp = searchpath("cpp.exe")) == NULL
+ && (cpp = getenv("RPCGENCPP")) == NULL)
+ cpp = DOSCPP;
+
+ putarg(0, cpp);
+ putarg(1, "-P-");
+ putarg(2, CPPFLAGS);
+ addarg(define);
+ addarg(infile);
+ addarg(NULL);
+
+ retval = spawnvp(P_WAIT, arglist[0], arglist);
+ if (retval != 0) {
+ fprintf(stderr, "%s: C PreProcessor failed\n", cmdname);
+ crash();
+ }
+ fnsplit(infile, drive, dir, name, ext);
+ fnmerge(cppfile, drive, dir, name, ".i");
+
+ fin = fopen(cppfile, "r");
+ if (fin == NULL) {
+ f_print(stderr, "%s: ", cmdname);
+ perror(cppfile);
+ crash();
+ }
+ dos_cppfile = strdup(cppfile);
+ if (dos_cppfile == NULL) {
+ fprintf(stderr, "%s: out of memory\n", cmdname);
+ crash();
+ }
+ }
+#else
+ (void) pipe(pd);
+ switch (childpid = fork()) {
+ case 0:
+ find_cpp();
+ putarg(0, CPP);
+ putarg(1, CPPFLAGS);
+ addarg(define);
+ addarg(infile);
+ addarg((char *) NULL);
+ (void) close(1);
+ (void) dup2(pd[1], 1);
+ (void) close(pd[0]);
+ execv(arglist[0], arglist);
+ perror("execv");
+ exit(1);
+ case -1:
+ perror("fork");
+ exit(1);
+ }
+ (void) close(pd[1]);
+ fin = fdopen(pd[0], "r");
+#endif
+ if (fin == NULL) {
+ f_print(stderr, "%s: ", cmdname);
+ perror(infilename);
+ crash();
+ }
+}
+/* valid tirpc nettypes */
+static char *valid_ti_nettypes[] =
+{
+ "netpath",
+ "visible",
+ "circuit_v",
+ "datagram_v",
+ "circuit_n",
+ "datagram_n",
+ "udp",
+ "tcp",
+ "raw",
+ NULL
+};
+/* valid inetd nettypes */
+static char *valid_i_nettypes[] =
+{
+ "udp",
+ "tcp",
+ NULL
+};
+
+static int
+check_nettype(name, list_to_check)
+ char *name;
+ char *list_to_check[];
+{
+ int i;
+ for (i = 0; list_to_check[i] != NULL; i++) {
+ if (strcmp(name, list_to_check[i]) == 0) {
+ return 1;
+ }
+ }
+ f_print(stderr, "illegal nettype :\'%s\'\n", name);
+ return 0;
+}
+/*
+ * Compile into an XDR routine output file
+ */
+
+static void
+c_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ char *include;
+ char *outfilename;
+ long tell;
+
+ c_initialize();
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ /* .h file already contains rpc/rpc.h */
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+ tell = ftell(fout);
+ while ((def = get_definition()) != NULL) {
+ emit(def);
+ }
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ }
+}
+
+
+static void
+c_initialize()
+{
+
+ /* add all the starting basic types */
+
+ add_type(1, "int");
+ add_type(1, "long");
+ add_type(1, "short");
+ add_type(1, "bool");
+
+ add_type(1, "u_int");
+ add_type(1, "u_long");
+ add_type(1, "u_short");
+
+}
+
+char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
+ char *(*proc)();\n\
+ xdrproc_t xdr_arg;\n\
+ unsigned len_arg;\n\
+ xdrproc_t xdr_res;\n\
+ unsigned len_res;\n\
+};\n";
+
+
+static char *
+generate_guard(pathname)
+ char *pathname;
+{
+ char *filename, *guard, *tmp;
+
+ filename = strrchr(pathname, '/'); /* find last component */
+ filename = ((filename == 0) ? pathname : filename + 1);
+ guard = strdup(filename);
+ /* convert to upper case */
+ tmp = guard;
+ while (*tmp) {
+ if (islower(*tmp))
+ *tmp = toupper(*tmp);
+ tmp++;
+ }
+
+ guard = extendfile(guard, "_H_RPCGEN");
+ return (guard);
+}
+/*
+ * Compile into an XDR header file
+ */
+
+static void
+h_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ char *outfilename;
+ long tell;
+ char *guard;
+ list *l;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ guard = generate_guard(outfilename ? outfilename : infile);
+
+ f_print(fout, "#ifndef _%s\n#define _%s\n\n", guard,
+ guard);
+
+ f_print(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION);
+ f_print(fout, "#include <rpc/rpc.h>\n\n");
+
+ tell = ftell(fout);
+ /* print data definitions */
+ while ((def = get_definition()) != NULL) {
+ print_datadef(def);
+ }
+
+ /* print function declarations. Do this after data definitions
+ * because they might be used as arguments for functions */
+ for (l = defined; l != NULL; l = l->next) {
+ print_funcdef(l->val);
+ }
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ } else
+ if (tblflag) {
+ f_print(fout, "%s", rpcgen_table_dcl);
+ }
+ f_print(fout, "\n#endif /* !_%s */\n", guard);
+}
+/*
+ * Compile into an RPC service
+ */
+static void
+s_output(argc, argv, infile, define, extend, outfile, nomain, netflag)
+ int argc;
+ char *argv[];
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+ int nomain;
+ int netflag;
+{
+ char *include;
+ definition *def;
+ int foundprogram = 0;
+ char *outfilename;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+
+ f_print(fout, "#include <sys/ioctl.h>\n");
+ f_print(fout, "#include <fcntl.h>\n");
+ f_print(fout, "#include <stdio.h>\n");
+ f_print(fout, "#include <stdlib.h>\n");
+ if (Cflag) {
+ f_print(fout, "#include <unistd.h>\n");
+ f_print(fout,
+ "#include <rpc/pmap_clnt.h>\n");
+ f_print(fout, "#include <string.h>\n");
+ }
+ f_print(fout, "#include <netdb.h>\n");
+ if (strcmp(svcclosetime, "-1") == 0)
+ indefinitewait = 1;
+ else
+ if (strcmp(svcclosetime, "0") == 0)
+ exitnow = 1;
+ else
+ if (inetdflag || pmflag) {
+ f_print(fout, "#include <signal.h>\n");
+ timerflag = 1;
+ }
+ if (!tirpcflag && inetdflag)
+ f_print(fout, "#include <sys/ttycom.h>\n");
+ if (Cflag && (inetdflag || pmflag)) {
+ f_print(fout, "#ifdef __cplusplus\n");
+ f_print(fout, "#include <sysent.h>\n");
+ f_print(fout, "#endif /* __cplusplus */\n");
+ }
+ if (tirpcflag)
+ f_print(fout, "#include <sys/types.h>\n");
+
+ f_print(fout, "#include <memory.h>\n");
+ if (tirpcflag)
+ f_print(fout, "#include <stropts.h>\n");
+
+ if (inetdflag || !tirpcflag) {
+ f_print(fout, "#include <sys/socket.h>\n");
+ f_print(fout, "#include <netinet/in.h>\n");
+ }
+ if ((netflag || pmflag) && tirpcflag) {
+ f_print(fout, "#include <netconfig.h>\n");
+ }
+ if ( /* timerflag && */ tirpcflag)
+ f_print(fout, "#include <sys/resource.h>\n");
+ if (logflag || inetdflag || pmflag)
+ f_print(fout, "#include <syslog.h>\n");
+
+ /* for ANSI-C */
+ f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
+
+ f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
+ if (timerflag)
+ f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
+ while ((def = get_definition()) != NULL) {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram) {
+ (void) unlink(outfilename);
+ return;
+ }
+ if (callerflag) /* EVAS */
+ f_print(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */
+ write_most(infile, netflag, nomain);
+ if (!nomain) {
+ if (!do_registers(argc, argv)) {
+ if (outfilename)
+ (void) unlink(outfilename);
+ usage();
+ }
+ write_rest();
+ }
+}
+/*
+ * generate client side stubs
+ */
+static void
+l_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ char *include;
+ definition *def;
+ int foundprogram = 0;
+ char *outfilename;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ if (Cflag)
+ f_print(fout, "#include <memory.h>\n");
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+ while ((def = get_definition()) != NULL) {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram) {
+ (void) unlink(outfilename);
+ return;
+ }
+ write_stubs();
+}
+/*
+ * generate the dispatch table
+ */
+static void
+t_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ int foundprogram = 0;
+ char *outfilename;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ while ((def = get_definition()) != NULL) {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram) {
+ (void) unlink(outfilename);
+ return;
+ }
+ write_tables();
+}
+/* sample routine for the server template */
+static void
+svc_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ char *include;
+ char *outfilename;
+ long tell;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ checkfiles(infile, outfilename); /* check if outfile already
+ * exists. if so, print an
+ * error message and exit */
+ open_output(infile, outfilename);
+ add_sample_msg();
+
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+
+ tell = ftell(fout);
+ while ((def = get_definition()) != NULL) {
+ write_sample_svc(def);
+ }
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ }
+}
+
+
+/* sample main routine for client */
+static void
+clnt_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ char *include;
+ char *outfilename;
+ long tell;
+ int has_program = 0;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ checkfiles(infile, outfilename); /* check if outfile already
+ * exists. if so, print an
+ * error message and exit */
+
+ open_output(infile, outfilename);
+ add_sample_msg();
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+ tell = ftell(fout);
+ while ((def = get_definition()) != NULL) {
+ has_program += write_sample_clnt(def);
+ }
+
+ if (has_program)
+ write_sample_clnt_main();
+
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ }
+}
+/*
+ * Perform registrations for service output
+ * Return 0 if failed; 1 otherwise.
+ */
+static int
+do_registers(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int i;
+
+ if (inetdflag || !tirpcflag) {
+ for (i = 1; i < argc; i++) {
+ if (streq(argv[i], "-s")) {
+ if (!check_nettype(argv[i + 1], valid_i_nettypes))
+ return 0;
+ write_inetd_register(argv[i + 1]);
+ i++;
+ }
+ }
+ } else {
+ for (i = 1; i < argc; i++)
+ if (streq(argv[i], "-s")) {
+ if (!check_nettype(argv[i + 1], valid_ti_nettypes))
+ return 0;
+ write_nettype_register(argv[i + 1]);
+ i++;
+ } else
+ if (streq(argv[i], "-n")) {
+ write_netid_register(argv[i + 1]);
+ i++;
+ }
+ }
+ return 1;
+}
+/*
+ * Add another argument to the arg list
+ */
+static void
+addarg(cp)
+ char *cp;
+{
+ if (argcount >= ARGLISTLEN) {
+ f_print(stderr, "rpcgen: too many defines\n");
+ crash();
+ /* NOTREACHED */
+ }
+ arglist[argcount++] = cp;
+
+}
+
+static void
+putarg(where, cp)
+ char *cp;
+ int where;
+{
+ if (where >= ARGLISTLEN) {
+ f_print(stderr, "rpcgen: arglist coding error\n");
+ crash();
+ /* NOTREACHED */
+ }
+ arglist[where] = cp;
+
+}
+/*
+ * if input file is stdin and an output file is specified then complain
+ * if the file already exists. Otherwise the file may get overwritten
+ * If input file does not exist, exit with an error
+ */
+
+static void
+checkfiles(infile, outfile)
+ char *infile;
+ char *outfile;
+{
+
+ struct stat buf;
+
+ if (infile) /* infile ! = NULL */
+ if (stat(infile, &buf) < 0) {
+ perror(infile);
+ crash();
+ };
+#if 0
+ if (outfile) {
+ if (stat(outfile, &buf) < 0)
+ return; /* file does not exist */
+ else {
+ f_print(stderr,
+ "file '%s' already exists and may be overwritten\n", outfile);
+ crash();
+ }
+ }
+#endif
+}
+/*
+ * Parse command line arguments
+ */
+static int
+parseargs(argc, argv, cmd)
+ int argc;
+ char *argv[];
+ struct commandline *cmd;
+{
+ int i;
+ int j;
+ int c;
+ char flag[(1 << 8 * sizeof(char))];
+ int nflags;
+
+ cmdname = argv[0];
+ cmd->infile = cmd->outfile = NULL;
+ if (argc < 2) {
+ return (0);
+ }
+ allfiles = 0;
+ flag['c'] = 0;
+ flag['h'] = 0;
+ flag['l'] = 0;
+ flag['m'] = 0;
+ flag['o'] = 0;
+ flag['s'] = 0;
+ flag['n'] = 0;
+ flag['t'] = 0;
+ flag['S'] = 0;
+ flag['C'] = 0;
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ if (cmd->infile) {
+ f_print(stderr, "Cannot specify more than one input file!\n");
+
+ return (0);
+ }
+ cmd->infile = argv[i];
+ } else {
+ for (j = 1; argv[i][j] != 0; j++) {
+ c = argv[i][j];
+ switch (c) {
+ case 'A':
+ callerflag = 1;
+ break;
+ case 'a':
+ allfiles = 1;
+ break;
+ case 'c':
+ case 'h':
+ case 'l':
+ case 'm':
+ case 't':
+ if (flag[c]) {
+ return (0);
+ }
+ flag[c] = 1;
+ break;
+ case 'S':
+ /* sample flag: Ss or Sc. Ss means set
+ * flag['S']; Sc means set flag['C']; */
+ c = argv[i][++j]; /* get next char */
+ if (c == 's')
+ c = 'S';
+ else
+ if (c == 'c')
+ c = 'C';
+ else
+ return (0);
+
+ if (flag[c]) {
+ return (0);
+ }
+ flag[c] = 1;
+ break;
+ case 'C': /* ANSI C syntax */
+ Cflag = 1;
+ break;
+
+ case 'b': /* turn TIRPC flag off for
+ * generating backward
+ * compatible */
+ tirpcflag = 0;
+ break;
+
+ case 'I':
+ inetdflag = 1;
+ break;
+ case 'N':
+ newstyle = 1;
+ break;
+ case 'L':
+ logflag = 1;
+ break;
+ case 'K':
+ if (++i == argc) {
+ return (0);
+ }
+ svcclosetime = argv[i];
+ goto nextarg;
+ case 'T':
+ tblflag = 1;
+ break;
+ case 'i':
+ if (++i == argc) {
+ return (0);
+ }
+ doinline = atoi(argv[i]);
+ goto nextarg;
+ case 'n':
+ case 'o':
+ case 's':
+ if (argv[i][j - 1] != '-' ||
+ argv[i][j + 1] != 0) {
+ return (0);
+ }
+ flag[c] = 1;
+ if (++i == argc) {
+ return (0);
+ }
+ if (c == 's') {
+ if (!streq(argv[i], "udp") &&
+ !streq(argv[i], "tcp")) {
+ return (0);
+ }
+ } else
+ if (c == 'o') {
+ if (cmd->outfile) {
+ return (0);
+ }
+ cmd->outfile = argv[i];
+ }
+ goto nextarg;
+ case 'D':
+ if (argv[i][j - 1] != '-') {
+ return (0);
+ }
+ (void) addarg(argv[i]);
+ goto nextarg;
+ case 'Y':
+ if (++i == argc) {
+ return (0);
+ }
+ (void) strcpy(pathbuf, argv[i]);
+ (void) strcat(pathbuf, "/cpp");
+ CPP = pathbuf;
+ cppDefined = 1;
+ goto nextarg;
+
+
+
+ default:
+ return (0);
+ }
+ }
+ nextarg:
+ ;
+ }
+ }
+
+ cmd->cflag = flag['c'];
+ cmd->hflag = flag['h'];
+ cmd->lflag = flag['l'];
+ cmd->mflag = flag['m'];
+ cmd->nflag = flag['n'];
+ cmd->sflag = flag['s'];
+ cmd->tflag = flag['t'];
+ cmd->Ssflag = flag['S'];
+ cmd->Scflag = flag['C'];
+
+ if (tirpcflag) {
+ pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is
+ * always TRUE */
+ if ((inetdflag && cmd->nflag)) { /* netid not allowed
+ * with inetdflag */
+ f_print(stderr, "Cannot use netid flag with inetd flag!\n");
+ return (0);
+ }
+ } else { /* 4.1 mode */
+ pmflag = 0; /* set pmflag only in tirpcmode */
+ inetdflag = 1; /* inetdflag is TRUE by default */
+ if (cmd->nflag) { /* netid needs TIRPC */
+ f_print(stderr, "Cannot use netid flag without TIRPC!\n");
+ return (0);
+ }
+ }
+
+ if (newstyle && (tblflag || cmd->tflag)) {
+ f_print(stderr, "Cannot use table flags with newstyle!\n");
+ return (0);
+ }
+ /* check no conflicts with file generation flags */
+ nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
+ cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
+
+ if (nflags == 0) {
+ if (cmd->outfile != NULL || cmd->infile == NULL) {
+ return (0);
+ }
+ } else
+ if (nflags > 1) {
+ f_print(stderr, "Cannot have more than one file generation flag!\n");
+ return (0);
+ }
+ return (1);
+}
+
+static void
+usage()
+{
+ f_print(stderr, "usage: %s infile\n", cmdname);
+ f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-A][-L][-M toolkit][-N][-T] infile\n",
+ cmdname);
+ f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n",
+ cmdname);
+ f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname);
+ f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname);
+ options_usage();
+ exit(1);
+}
+
+static void
+options_usage()
+{
+ f_print(stderr, "options:\n");
+ f_print(stderr, "-A\t\tgenerate svc_caller() function\n");
+ f_print(stderr, "-a\t\tgenerate all files, including samples\n");
+ f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n");
+ f_print(stderr, "-c\t\tgenerate XDR routines\n");
+ f_print(stderr, "-C\t\tANSI C mode\n");
+ f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
+ f_print(stderr, "-h\t\tgenerate header file\n");
+ f_print(stderr, "-i size\t\tsize at which to start generating inline code\n");
+ f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n");
+ f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n");
+ f_print(stderr, "-l\t\tgenerate client side stubs\n");
+ f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
+ f_print(stderr, "-m\t\tgenerate server side stubs\n");
+ f_print(stderr, "-n netid\tgenerate server code that supports named netid\n");
+ f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n");
+ f_print(stderr, "-o outfile\tname of the output file\n");
+ f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n");
+ f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n");
+ f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n");
+ f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
+ f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
+ f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n");
+
+ exit(1);
+}
diff --git a/developer_cmds/rpcgen/rpc_parse.c b/developer_cmds/rpcgen/rpc_parse.c
new file mode 100644
index 0000000..db0c1f1
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_parse.c
@@ -0,0 +1,643 @@
+/* $NetBSD: rpc_parse.c,v 1.9 1998/02/11 23:11:18 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_parse.c,v 1.9 1998/02/11 23:11:18 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_parse.c, Parser for the RPC protocol compiler
+ * Copyright (C) 1987 Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "rpc/types.h"
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define ARGNAME "arg"
+
+static void isdefined __P((definition *));
+static void def_struct __P((definition *));
+static void def_program __P((definition *));
+static void def_enum __P((definition *));
+static void def_const __P((definition *));
+static void def_union __P((definition *));
+static void check_type_name __P((char *, int));
+static void def_typedef __P((definition *));
+static void get_declaration __P((declaration *, defkind));
+static void get_prog_declaration __P((declaration *, defkind, int));
+static void get_type __P((char **, char **, defkind));
+static void unsigned_dec __P((char **));
+
+/*
+ * return the next definition you see
+ */
+definition *
+get_definition()
+{
+ definition *defp;
+ token tok;
+
+ defp = ALLOC(definition);
+ get_token(&tok);
+ switch (tok.kind) {
+ case TOK_STRUCT:
+ def_struct(defp);
+ break;
+ case TOK_UNION:
+ def_union(defp);
+ break;
+ case TOK_TYPEDEF:
+ def_typedef(defp);
+ break;
+ case TOK_ENUM:
+ def_enum(defp);
+ break;
+ case TOK_PROGRAM:
+ def_program(defp);
+ break;
+ case TOK_CONST:
+ def_const(defp);
+ break;
+ case TOK_EOF:
+ return (NULL);
+ default:
+ error("definition keyword expected");
+ }
+ scan(TOK_SEMICOLON, &tok);
+ isdefined(defp);
+ return (defp);
+}
+
+static void
+isdefined(defp)
+ definition *defp;
+{
+ STOREVAL(&defined, defp);
+}
+
+static void
+def_struct(defp)
+ definition *defp;
+{
+ token tok;
+ declaration dec;
+ decl_list *decls;
+ decl_list **tailp;
+
+ defp->def_kind = DEF_STRUCT;
+
+ scan(TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan(TOK_LBRACE, &tok);
+ tailp = &defp->def.st.decls;
+ do {
+ get_declaration(&dec, DEF_STRUCT);
+ decls = ALLOC(decl_list);
+ decls->decl = dec;
+ *tailp = decls;
+ tailp = &decls->next;
+ scan(TOK_SEMICOLON, &tok);
+ peek(&tok);
+ } while (tok.kind != TOK_RBRACE);
+ get_token(&tok);
+ *tailp = NULL;
+}
+
+static void
+def_program(defp)
+ definition *defp;
+{
+ token tok;
+ declaration dec;
+ decl_list *decls;
+ decl_list **tailp;
+ version_list *vlist;
+ version_list **vtailp;
+ proc_list *plist;
+ proc_list **ptailp;
+ int num_args;
+ bool_t isvoid = FALSE; /* whether first argument is void */
+ defp->def_kind = DEF_PROGRAM;
+ scan(TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan(TOK_LBRACE, &tok);
+ vtailp = &defp->def.pr.versions;
+ tailp = &defp->def.st.decls;
+ scan(TOK_VERSION, &tok);
+ do {
+ scan(TOK_IDENT, &tok);
+ vlist = ALLOC(version_list);
+ vlist->vers_name = tok.str;
+ scan(TOK_LBRACE, &tok);
+ ptailp = &vlist->procs;
+ do {
+ /* get result type */
+ plist = ALLOC(proc_list);
+ get_type(&plist->res_prefix, &plist->res_type,
+ DEF_PROGRAM);
+ if (streq(plist->res_type, "opaque")) {
+ error("illegal result type");
+ }
+ scan(TOK_IDENT, &tok);
+ plist->proc_name = tok.str;
+ scan(TOK_LPAREN, &tok);
+ /* get args - first one */
+ num_args = 1;
+ isvoid = FALSE;
+ /* type of DEF_PROGRAM in the first
+ * get_prog_declaration and DEF_STURCT in the next
+ * allows void as argument if it is the only argument */
+ get_prog_declaration(&dec, DEF_PROGRAM, num_args);
+ if (streq(dec.type, "void"))
+ isvoid = TRUE;
+ decls = ALLOC(decl_list);
+ plist->args.decls = decls;
+ decls->decl = dec;
+ tailp = &decls->next;
+ /* get args */
+ while (peekscan(TOK_COMMA, &tok)) {
+ num_args++;
+ get_prog_declaration(&dec, DEF_STRUCT,
+ num_args);
+ decls = ALLOC(decl_list);
+ decls->decl = dec;
+ *tailp = decls;
+ if (streq(dec.type, "void"))
+ isvoid = TRUE;
+ tailp = &decls->next;
+ }
+ /* multiple arguments are only allowed in newstyle */
+ if (!newstyle && num_args > 1) {
+ error("only one argument is allowed");
+ }
+ if (isvoid && num_args > 1) {
+ error("illegal use of void in program definition");
+ }
+ *tailp = NULL;
+ scan(TOK_RPAREN, &tok);
+ scan(TOK_EQUAL, &tok);
+ scan_num(&tok);
+ scan(TOK_SEMICOLON, &tok);
+ plist->proc_num = tok.str;
+ plist->arg_num = num_args;
+ *ptailp = plist;
+ ptailp = &plist->next;
+ peek(&tok);
+ } while (tok.kind != TOK_RBRACE);
+ *ptailp = NULL;
+ *vtailp = vlist;
+ vtailp = &vlist->next;
+ scan(TOK_RBRACE, &tok);
+ scan(TOK_EQUAL, &tok);
+ scan_num(&tok);
+ vlist->vers_num = tok.str;
+ /* make the argument structure name for each arg */
+ for (plist = vlist->procs; plist != NULL;
+ plist = plist->next) {
+ plist->args.argname = make_argname(plist->proc_name,
+ vlist->vers_num);
+ /* free the memory ?? */
+ }
+ scan(TOK_SEMICOLON, &tok);
+ scan2(TOK_VERSION, TOK_RBRACE, &tok);
+ } while (tok.kind == TOK_VERSION);
+ scan(TOK_EQUAL, &tok);
+ scan_num(&tok);
+ defp->def.pr.prog_num = tok.str;
+ *vtailp = NULL;
+}
+
+
+static void
+def_enum(defp)
+ definition *defp;
+{
+ token tok;
+ enumval_list *elist;
+ enumval_list **tailp;
+
+ defp->def_kind = DEF_ENUM;
+ scan(TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan(TOK_LBRACE, &tok);
+ tailp = &defp->def.en.vals;
+ do {
+ scan(TOK_IDENT, &tok);
+ elist = ALLOC(enumval_list);
+ elist->name = tok.str;
+ elist->assignment = NULL;
+ scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
+ if (tok.kind == TOK_EQUAL) {
+ scan_num(&tok);
+ elist->assignment = tok.str;
+ scan2(TOK_COMMA, TOK_RBRACE, &tok);
+ }
+ *tailp = elist;
+ tailp = &elist->next;
+ } while (tok.kind != TOK_RBRACE);
+ *tailp = NULL;
+}
+
+static void
+def_const(defp)
+ definition *defp;
+{
+ token tok;
+
+ defp->def_kind = DEF_CONST;
+ scan(TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan(TOK_EQUAL, &tok);
+ scan2(TOK_IDENT, TOK_STRCONST, &tok);
+ defp->def.co = tok.str;
+}
+
+static void
+def_union(defp)
+ definition *defp;
+{
+ token tok;
+ declaration dec;
+ case_list *cases;
+ case_list **tailp;
+ int flag;
+
+ defp->def_kind = DEF_UNION;
+ scan(TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan(TOK_SWITCH, &tok);
+ scan(TOK_LPAREN, &tok);
+ get_declaration(&dec, DEF_UNION);
+ defp->def.un.enum_decl = dec;
+ tailp = &defp->def.un.cases;
+ scan(TOK_RPAREN, &tok);
+ scan(TOK_LBRACE, &tok);
+ scan(TOK_CASE, &tok);
+ while (tok.kind == TOK_CASE) {
+ scan2(TOK_IDENT, TOK_CHARCONST, &tok);
+ cases = ALLOC(case_list);
+ cases->case_name = tok.str;
+ scan(TOK_COLON, &tok);
+ /* now peek at next token */
+ flag = 0;
+ if (peekscan(TOK_CASE, &tok)) {
+
+ do {
+ scan2(TOK_IDENT, TOK_CHARCONST, &tok);
+ cases->contflag = 1; /* continued case
+ * statement */
+ *tailp = cases;
+ tailp = &cases->next;
+ cases = ALLOC(case_list);
+ cases->case_name = tok.str;
+ scan(TOK_COLON, &tok);
+
+ } while (peekscan(TOK_CASE, &tok));
+ } else
+ if (flag) {
+
+ *tailp = cases;
+ tailp = &cases->next;
+ cases = ALLOC(case_list);
+ };
+
+ get_declaration(&dec, DEF_UNION);
+ cases->case_decl = dec;
+ cases->contflag = 0; /* no continued case statement */
+ *tailp = cases;
+ tailp = &cases->next;
+ scan(TOK_SEMICOLON, &tok);
+
+ scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
+ }
+ *tailp = NULL;
+ if (tok.kind == TOK_DEFAULT) {
+ scan(TOK_COLON, &tok);
+ get_declaration(&dec, DEF_UNION);
+ defp->def.un.default_decl = ALLOC(declaration);
+ *defp->def.un.default_decl = dec;
+ scan(TOK_SEMICOLON, &tok);
+ scan(TOK_RBRACE, &tok);
+ } else {
+ defp->def.un.default_decl = NULL;
+ }
+}
+
+static char *reserved_words[] = {
+ "array",
+ "bytes",
+ "destroy",
+ "free",
+ "getpos",
+ "inline",
+ "pointer",
+ "reference",
+ "setpos",
+ "sizeof",
+ "union",
+ "vector",
+ NULL
+};
+
+static char *reserved_types[] = {
+ "opaque",
+ "string",
+ NULL
+};
+/* check that the given name is not one that would eventually result in
+ xdr routines that would conflict with internal XDR routines. */
+static void
+check_type_name(name, new_type)
+ int new_type;
+ char *name;
+{
+ int i;
+ char tmp[100];
+
+ for (i = 0; reserved_words[i] != NULL; i++) {
+ if (strcmp(name, reserved_words[i]) == 0) {
+ sprintf(tmp,
+ "illegal (reserved) name :\'%s\' in type definition", name);
+ error(tmp);
+ }
+ }
+ if (new_type) {
+ for (i = 0; reserved_types[i] != NULL; i++) {
+ if (strcmp(name, reserved_types[i]) == 0) {
+ sprintf(tmp,
+ "illegal (reserved) name :\'%s\' in type definition", name);
+ error(tmp);
+ }
+ }
+ }
+}
+
+static void
+def_typedef(defp)
+ definition *defp;
+{
+ declaration dec;
+
+ defp->def_kind = DEF_TYPEDEF;
+ get_declaration(&dec, DEF_TYPEDEF);
+ defp->def_name = dec.name;
+ check_type_name(dec.name, 1);
+ defp->def.ty.old_prefix = dec.prefix;
+ defp->def.ty.old_type = dec.type;
+ defp->def.ty.rel = dec.rel;
+ defp->def.ty.array_max = dec.array_max;
+}
+
+static void
+get_declaration(dec, dkind)
+ declaration *dec;
+ defkind dkind;
+{
+ token tok;
+
+ get_type(&dec->prefix, &dec->type, dkind);
+ dec->rel = REL_ALIAS;
+ if (streq(dec->type, "void")) {
+ return;
+ }
+ check_type_name(dec->type, 0);
+
+ scan2(TOK_STAR, TOK_IDENT, &tok);
+ if (tok.kind == TOK_STAR) {
+ dec->rel = REL_POINTER;
+ scan(TOK_IDENT, &tok);
+ }
+ dec->name = tok.str;
+ if (peekscan(TOK_LBRACKET, &tok)) {
+ if (dec->rel == REL_POINTER) {
+ error("no array-of-pointer declarations -- use typedef");
+ }
+ dec->rel = REL_VECTOR;
+ scan_num(&tok);
+ dec->array_max = tok.str;
+ scan(TOK_RBRACKET, &tok);
+ } else
+ if (peekscan(TOK_LANGLE, &tok)) {
+ if (dec->rel == REL_POINTER) {
+ error("no array-of-pointer declarations -- use typedef");
+ }
+ dec->rel = REL_ARRAY;
+ if (peekscan(TOK_RANGLE, &tok)) {
+ dec->array_max = "~0"; /* unspecified size, use
+ * max */
+ } else {
+ scan_num(&tok);
+ dec->array_max = tok.str;
+ scan(TOK_RANGLE, &tok);
+ }
+ }
+ if (streq(dec->type, "opaque")) {
+ if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
+ error("array declaration expected");
+ }
+ } else
+ if (streq(dec->type, "string")) {
+ if (dec->rel != REL_ARRAY) {
+ error("variable-length array declaration expected");
+ }
+ }
+}
+
+static void
+get_prog_declaration(dec, dkind, num)
+ declaration *dec;
+ defkind dkind;
+ int num; /* arg number */
+{
+ token tok;
+ char name[10]; /* argument name */
+
+ if (dkind == DEF_PROGRAM) {
+ peek(&tok);
+ if (tok.kind == TOK_RPAREN) { /* no arguments */
+ dec->rel = REL_ALIAS;
+ dec->type = "void";
+ dec->prefix = NULL;
+ dec->name = NULL;
+ return;
+ }
+ }
+ get_type(&dec->prefix, &dec->type, dkind);
+ dec->rel = REL_ALIAS;
+ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
+ strcpy(name, tok.str);
+ else
+ sprintf(name, "%s%d", ARGNAME, num); /* default name of
+ * argument */
+
+ dec->name = (char *) strdup(name);
+
+ if (streq(dec->type, "void")) {
+ return;
+ }
+ if (streq(dec->type, "opaque")) {
+ error("opaque -- illegal argument type");
+ }
+ if (peekscan(TOK_STAR, &tok)) {
+ if (streq(dec->type, "string")) {
+ error("pointer to string not allowed in program arguments\n");
+ }
+ dec->rel = REL_POINTER;
+ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
+ dec->name = (char *) strdup(tok.str);
+ }
+ if (peekscan(TOK_LANGLE, &tok)) {
+ if (!streq(dec->type, "string")) {
+ error("arrays cannot be declared as arguments to procedures -- use typedef");
+ }
+ dec->rel = REL_ARRAY;
+ if (peekscan(TOK_RANGLE, &tok)) {
+ dec->array_max = "~0"; /* unspecified size, use max */
+ } else {
+ scan_num(&tok);
+ dec->array_max = tok.str;
+ scan(TOK_RANGLE, &tok);
+ }
+ }
+ if (streq(dec->type, "string")) {
+ if (dec->rel != REL_ARRAY) { /* .x specifies just string as
+ * type of argument - make it
+ * string<> */
+ dec->rel = REL_ARRAY;
+ dec->array_max = "~0"; /* unspecified size, use max */
+ }
+ }
+}
+
+
+
+static void
+get_type(prefixp, typep, dkind)
+ char **prefixp;
+ char **typep;
+ defkind dkind;
+{
+ token tok;
+
+ *prefixp = NULL;
+ get_token(&tok);
+ switch (tok.kind) {
+ case TOK_IDENT:
+ *typep = tok.str;
+ break;
+ case TOK_STRUCT:
+ case TOK_ENUM:
+ case TOK_UNION:
+ *prefixp = tok.str;
+ scan(TOK_IDENT, &tok);
+ *typep = tok.str;
+ break;
+ case TOK_UNSIGNED:
+ unsigned_dec(typep);
+ break;
+ case TOK_SHORT:
+ *typep = "short";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_LONG:
+ *typep = "long";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_HYPER:
+ *typep = "int64_t";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_VOID:
+ if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
+ error("voids allowed only inside union and program definitions with one argument");
+ }
+ *typep = tok.str;
+ break;
+ case TOK_STRING:
+ case TOK_OPAQUE:
+ case TOK_CHAR:
+ case TOK_INT:
+ case TOK_FLOAT:
+ case TOK_DOUBLE:
+ case TOK_QUAD:
+ case TOK_BOOL:
+ *typep = tok.str;
+ break;
+ default:
+ error("expected type specifier");
+ }
+}
+
+static void
+unsigned_dec(typep)
+ char **typep;
+{
+ token tok;
+
+ peek(&tok);
+ switch (tok.kind) {
+ case TOK_CHAR:
+ get_token(&tok);
+ *typep = "u_char";
+ break;
+ case TOK_SHORT:
+ get_token(&tok);
+ *typep = "u_short";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_LONG:
+ get_token(&tok);
+ *typep = "u_long";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_HYPER:
+ get_token(&tok);
+ *typep = "u_int64_t";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_INT:
+ get_token(&tok);
+ *typep = "u_int";
+ break;
+ default:
+ *typep = "u_int";
+ break;
+ }
+}
diff --git a/developer_cmds/rpcgen/rpc_parse.h b/developer_cmds/rpcgen/rpc_parse.h
new file mode 100644
index 0000000..e235bf5
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_parse.h
@@ -0,0 +1,168 @@
+/* $NetBSD: rpc_parse.h,v 1.4 1997/10/11 21:01:42 christos Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
+
+/*
+ * rpc_parse.h, Definitions for the RPCL parser
+ */
+
+enum defkind {
+ DEF_CONST,
+ DEF_STRUCT,
+ DEF_UNION,
+ DEF_ENUM,
+ DEF_TYPEDEF,
+ DEF_PROGRAM
+};
+typedef enum defkind defkind;
+
+typedef char *const_def;
+
+enum relation {
+ REL_VECTOR, /* fixed length array */
+ REL_ARRAY, /* variable length array */
+ REL_POINTER, /* pointer */
+ REL_ALIAS, /* simple */
+};
+typedef enum relation relation;
+
+struct typedef_def {
+ char *old_prefix;
+ char *old_type;
+ relation rel;
+ char *array_max;
+};
+typedef struct typedef_def typedef_def;
+
+struct enumval_list {
+ char *name;
+ char *assignment;
+ struct enumval_list *next;
+};
+typedef struct enumval_list enumval_list;
+
+struct enum_def {
+ enumval_list *vals;
+};
+typedef struct enum_def enum_def;
+
+struct declaration {
+ char *prefix;
+ char *type;
+ char *name;
+ relation rel;
+ char *array_max;
+};
+typedef struct declaration declaration;
+
+struct decl_list {
+ declaration decl;
+ struct decl_list *next;
+};
+typedef struct decl_list decl_list;
+
+struct struct_def {
+ decl_list *decls;
+};
+typedef struct struct_def struct_def;
+
+struct case_list {
+ char *case_name;
+ int contflag;
+ declaration case_decl;
+ struct case_list *next;
+};
+typedef struct case_list case_list;
+
+struct union_def {
+ declaration enum_decl;
+ case_list *cases;
+ declaration *default_decl;
+};
+typedef struct union_def union_def;
+
+struct arg_list {
+ char *argname; /* name of struct for arg*/
+ decl_list *decls;
+};
+
+typedef struct arg_list arg_list;
+
+struct proc_list {
+ char *proc_name;
+ char *proc_num;
+ arg_list args;
+ int arg_num;
+ char *res_type;
+ char *res_prefix;
+ struct proc_list *next;
+};
+typedef struct proc_list proc_list;
+
+struct version_list {
+ char *vers_name;
+ char *vers_num;
+ proc_list *procs;
+ struct version_list *next;
+};
+typedef struct version_list version_list;
+
+struct program_def {
+ char *prog_num;
+ version_list *versions;
+};
+typedef struct program_def program_def;
+
+struct definition {
+ char *def_name;
+ defkind def_kind;
+ union {
+ const_def co;
+ struct_def st;
+ union_def un;
+ enum_def en;
+ typedef_def ty;
+ program_def pr;
+ } def;
+};
+typedef struct definition definition;
+
+definition *get_definition __P((void));
+
+struct bas_type
+{
+ char *name;
+ int length;
+ struct bas_type *next;
+};
+
+typedef struct bas_type bas_type;
diff --git a/developer_cmds/rpcgen/rpc_sample.c b/developer_cmds/rpcgen/rpc_sample.c
new file mode 100644
index 0000000..3fee135
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_sample.c
@@ -0,0 +1,261 @@
+/* $NetBSD: rpc_sample.c,v 1.5 1997/10/18 10:54:01 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_sample.c,v 1.5 1997/10/18 10:54:01 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+static char RQSTP[] = "rqstp";
+
+static void write_sample_client __P((char *, version_list *));
+static void write_sample_server __P((definition *));
+static void return_type __P((proc_list *));
+
+void
+write_sample_svc(def)
+ definition *def;
+{
+
+ if (def->def_kind != DEF_PROGRAM)
+ return;
+ write_sample_server(def);
+}
+
+
+int
+write_sample_clnt(def)
+ definition *def;
+{
+ version_list *vp;
+ int count = 0;
+
+ if (def->def_kind != DEF_PROGRAM)
+ return (0);
+ /* generate sample code for each version */
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ write_sample_client(def->def_name, vp);
+ ++count;
+ }
+ return (count);
+}
+
+
+static void
+write_sample_client(program_name, vp)
+ char *program_name;
+ version_list *vp;
+{
+ proc_list *proc;
+ int i;
+ decl_list *l;
+
+ f_print(fout, "\n\nvoid\n");
+ pvname(program_name, vp->vers_num);
+ if (Cflag)
+ f_print(fout, "( char* host )\n{\n");
+ else
+ f_print(fout, "(host)\nchar *host;\n{\n");
+ f_print(fout, "\tCLIENT *clnt;\n");
+
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\t");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, " *result_%d;\n", ++i);
+ /* print out declarations for arguments */
+ if (proc->arg_num < 2 && !newstyle) {
+ f_print(fout, "\t");
+ if (!streq(proc->args.decls->decl.type, "void"))
+ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+ else
+ f_print(fout, "char* "); /* cannot have "void"
+ * type */
+ f_print(fout, " ");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_arg;\n");
+ } else
+ if (!streq(proc->args.decls->decl.type, "void")) {
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ f_print(fout, "\t");
+ ptype(l->decl.prefix, l->decl.type, 1);
+ f_print(fout, " ");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_%s;\n", l->decl.name);
+/* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/
+ }
+ }
+ }
+
+ /* generate creation of client handle */
+ f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
+ program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
+ f_print(fout, "\tif (clnt == NULL) {\n");
+ f_print(fout, "\t\tclnt_pcreateerror(host);\n");
+ f_print(fout, "\t\texit(1);\n\t}\n");
+
+ /* generate calls to procedures */
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\tresult_%d = ", ++i);
+ pvname(proc->proc_name, vp->vers_num);
+ if (proc->arg_num < 2 && !newstyle) {
+ f_print(fout, "(");
+ if (streq(proc->args.decls->decl.type, "void")) /* cast to void* */
+ f_print(fout, "(void*)");
+ f_print(fout, "&");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_arg, clnt);\n");
+ } else
+ if (streq(proc->args.decls->decl.type, "void")) {
+ f_print(fout, "(clnt);\n");
+ } else {
+ f_print(fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_%s, ", l->decl.name);
+ }
+ f_print(fout, "clnt);\n");
+ }
+ f_print(fout, "\tif (result_%d == NULL) {\n", i);
+ f_print(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n");
+ f_print(fout, "\t}\n");
+ }
+
+ f_print(fout, "\tclnt_destroy( clnt );\n");
+ f_print(fout, "}\n");
+}
+
+static void
+write_sample_server(def)
+ definition *def;
+{
+ version_list *vp;
+ proc_list *proc;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\n");
+/* if( Cflag )
+ f_print( fout, "extern \"C\"{\n");
+*/
+ return_type(proc);
+ f_print(fout, "*\n");
+ if (Cflag)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, RQSTP, "struct svc_req *");
+
+ f_print(fout, "{\n");
+ f_print(fout, "\n\tstatic ");
+ if (!streq(proc->res_type, "void"))
+ return_type(proc);
+ else
+ f_print(fout, "char*"); /* cannot have void type */
+ f_print(fout, " result;\n");
+ f_print(fout,
+ "\n\t/*\n\t * insert server code here\n\t */\n\n");
+ if (!streq(proc->res_type, "void"))
+ f_print(fout, "\treturn(&result);\n}\n");
+ else /* cast back to void * */
+ f_print(fout, "\treturn((void*) &result);\n}\n");
+/* if( Cflag)
+ f_print( fout, "};\n");
+*/
+
+ }
+ }
+}
+
+static void
+return_type(plist)
+ proc_list *plist;
+{
+ ptype(plist->res_prefix, plist->res_type, 1);
+}
+
+void
+add_sample_msg()
+{
+ f_print(fout, "/*\n");
+ f_print(fout, " * This is sample code generated by rpcgen.\n");
+ f_print(fout, " * These are only templates and you can use them\n");
+ f_print(fout, " * as a guideline for developing your own functions.\n");
+ f_print(fout, " */\n\n");
+}
+
+void
+write_sample_clnt_main()
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ f_print(fout, "\n\n");
+ if (Cflag)
+ f_print(fout, "main( int argc, char* argv[] )\n{\n");
+ else
+ f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n");
+
+ f_print(fout, "\tchar *host;");
+ f_print(fout, "\n\n\tif(argc < 2) {");
+ f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n");
+ f_print(fout, "\t\texit(1);\n\t}");
+ f_print(fout, "\n\thost = argv[1];\n");
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout, "\t");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, "( host );\n");
+ }
+ }
+ f_print(fout, "}\n");
+}
diff --git a/developer_cmds/rpcgen/rpc_scan.c b/developer_cmds/rpcgen/rpc_scan.c
new file mode 100644
index 0000000..4130107
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_scan.c
@@ -0,0 +1,521 @@
+/* $NetBSD: rpc_scan.c,v 1.6 1997/10/18 10:54:05 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_scan.c,v 1.6 1997/10/18 10:54:05 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_scan.c, Scanner for the RPC protocol compiler
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define startcomment(where) (where[0] == '/' && where[1] == '*')
+#define endcomment(where) (where[-1] == '*' && where[0] == '/')
+
+static void unget_token __P((token *));
+static void findstrconst __P((char **, char **));
+static void findchrconst __P((char **, char **));
+static void findconst __P((char **, char **));
+static void findkind __P((char **, token *));
+static int cppline __P((char *));
+static int directive __P((char *));
+static void printdirective __P((char *));
+static void docppline __P((char *, int *, char **));
+
+static int pushed = 0; /* is a token pushed */
+static token lasttok; /* last token, if pushed */
+
+/*
+ * scan expecting 1 given token
+ */
+void
+scan(expect, tokp)
+ tok_kind expect;
+ token *tokp;
+{
+ get_token(tokp);
+ if (tokp->kind != expect) {
+ expected1(expect);
+ }
+}
+/*
+ * scan expecting any of the 2 given tokens
+ */
+void
+scan2(expect1, expect2, tokp)
+ tok_kind expect1;
+ tok_kind expect2;
+ token *tokp;
+{
+ get_token(tokp);
+ if (tokp->kind != expect1 && tokp->kind != expect2) {
+ expected2(expect1, expect2);
+ }
+}
+/*
+ * scan expecting any of the 3 given token
+ */
+void
+scan3(expect1, expect2, expect3, tokp)
+ tok_kind expect1;
+ tok_kind expect2;
+ tok_kind expect3;
+ token *tokp;
+{
+ get_token(tokp);
+ if (tokp->kind != expect1 && tokp->kind != expect2
+ && tokp->kind != expect3) {
+ expected3(expect1, expect2, expect3);
+ }
+}
+/*
+ * scan expecting a constant, possibly symbolic
+ */
+void
+scan_num(tokp)
+ token *tokp;
+{
+ get_token(tokp);
+ switch (tokp->kind) {
+ case TOK_IDENT:
+ break;
+ default:
+ error("constant or identifier expected");
+ }
+}
+/*
+ * Peek at the next token
+ */
+void
+peek(tokp)
+ token *tokp;
+{
+ get_token(tokp);
+ unget_token(tokp);
+}
+/*
+ * Peek at the next token and scan it if it matches what you expect
+ */
+int
+peekscan(expect, tokp)
+ tok_kind expect;
+ token *tokp;
+{
+ peek(tokp);
+ if (tokp->kind == expect) {
+ get_token(tokp);
+ return (1);
+ }
+ return (0);
+}
+/*
+ * Get the next token, printing out any directive that are encountered.
+ */
+void
+get_token(tokp)
+ token *tokp;
+{
+ int commenting;
+ int stat = 0;
+
+ if (pushed) {
+ pushed = 0;
+ *tokp = lasttok;
+ return;
+ }
+ commenting = 0;
+ for (;;) {
+ if (*where == 0) {
+ for (;;) {
+ if (!fgets(curline, MAXLINESIZE, fin)) {
+ tokp->kind = TOK_EOF;
+ /* now check if cpp returned non NULL value */
+ waitpid(childpid, &stat, WUNTRACED);
+ if (stat > 0) {
+ /* Set return value from rpcgen */
+ nonfatalerrors = stat >> 8;
+ }
+ *where = 0;
+ return;
+ }
+ linenum++;
+ if (commenting) {
+ break;
+ } else
+ /* skip lines beginning with #pragma */
+ if (!strncmp(curline, "#pragma", 7)) *curline = 0;
+ else if (cppline(curline)) {
+ docppline(curline, &linenum,
+ &infilename);
+ } else
+ if (directive(curline)) {
+ printdirective(curline);
+ } else {
+ break;
+ }
+ }
+ where = curline;
+ } else
+ if (isspace(*where)) {
+ while (isspace(*where)) {
+ where++; /* eat */
+ }
+ } else
+ if (commenting) {
+ for (where++; *where; where++) {
+ if (endcomment(where)) {
+ where++;
+ commenting--;
+ break;
+ }
+ }
+ } else
+ if (startcomment(where)) {
+ where += 2;
+ commenting++;
+ } else {
+ break;
+ }
+ }
+
+ /*
+ * 'where' is not whitespace, comment or directive Must be a token!
+ */
+ switch (*where) {
+ case ':':
+ tokp->kind = TOK_COLON;
+ where++;
+ break;
+ case ';':
+ tokp->kind = TOK_SEMICOLON;
+ where++;
+ break;
+ case ',':
+ tokp->kind = TOK_COMMA;
+ where++;
+ break;
+ case '=':
+ tokp->kind = TOK_EQUAL;
+ where++;
+ break;
+ case '*':
+ tokp->kind = TOK_STAR;
+ where++;
+ break;
+ case '[':
+ tokp->kind = TOK_LBRACKET;
+ where++;
+ break;
+ case ']':
+ tokp->kind = TOK_RBRACKET;
+ where++;
+ break;
+ case '{':
+ tokp->kind = TOK_LBRACE;
+ where++;
+ break;
+ case '}':
+ tokp->kind = TOK_RBRACE;
+ where++;
+ break;
+ case '(':
+ tokp->kind = TOK_LPAREN;
+ where++;
+ break;
+ case ')':
+ tokp->kind = TOK_RPAREN;
+ where++;
+ break;
+ case '<':
+ tokp->kind = TOK_LANGLE;
+ where++;
+ break;
+ case '>':
+ tokp->kind = TOK_RANGLE;
+ where++;
+ break;
+
+ case '"':
+ tokp->kind = TOK_STRCONST;
+ findstrconst(&where, &tokp->str);
+ break;
+ case '\'':
+ tokp->kind = TOK_CHARCONST;
+ findchrconst(&where, &tokp->str);
+ break;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tokp->kind = TOK_IDENT;
+ findconst(&where, &tokp->str);
+ break;
+
+ default:
+ if (!(isalpha(*where) || *where == '_')) {
+ char buf[100];
+ char *p;
+
+ s_print(buf, "illegal character in file: ");
+ p = buf + strlen(buf);
+ if (isprint(*where)) {
+ s_print(p, "%c", *where);
+ } else {
+ s_print(p, "%d", *where);
+ }
+ error(buf);
+ }
+ findkind(&where, tokp);
+ break;
+ }
+}
+
+static void
+unget_token(tokp)
+ token *tokp;
+{
+ lasttok = *tokp;
+ pushed = 1;
+}
+
+static void
+findstrconst(str, val)
+ char **str;
+ char **val;
+{
+ char *p;
+ int size;
+
+ p = *str;
+ do {
+ p++;
+ } while (*p && *p != '"');
+ if (*p == 0) {
+ error("unterminated string constant");
+ }
+ p++;
+ size = p - *str;
+ *val = alloc(size + 1);
+ (void) strncpy(*val, *str, size);
+ (*val)[size] = 0;
+ *str = p;
+}
+
+static void
+findchrconst(str, val)
+ char **str;
+ char **val;
+{
+ char *p;
+ int size;
+
+ p = *str;
+ do {
+ p++;
+ } while (*p && *p != '\'');
+ if (*p == 0) {
+ error("unterminated string constant");
+ }
+ p++;
+ size = p - *str;
+ if (size != 3) {
+ error("empty char string");
+ }
+ *val = alloc(size + 1);
+ (void) strncpy(*val, *str, size);
+ (*val)[size] = 0;
+ *str = p;
+}
+
+static void
+findconst(str, val)
+ char **str;
+ char **val;
+{
+ char *p;
+ int size;
+
+ p = *str;
+ if (*p == '0' && *(p + 1) == 'x') {
+ p++;
+ do {
+ p++;
+ } while (isxdigit(*p));
+ } else {
+ do {
+ p++;
+ } while (isdigit(*p));
+ }
+ size = p - *str;
+ *val = alloc(size + 1);
+ (void) strncpy(*val, *str, size);
+ (*val)[size] = 0;
+ *str = p;
+}
+
+static token symbols[] = {
+ {TOK_CONST, "const"},
+ {TOK_UNION, "union"},
+ {TOK_SWITCH, "switch"},
+ {TOK_CASE, "case"},
+ {TOK_DEFAULT, "default"},
+ {TOK_STRUCT, "struct"},
+ {TOK_TYPEDEF, "typedef"},
+ {TOK_ENUM, "enum"},
+ {TOK_OPAQUE, "opaque"},
+ {TOK_BOOL, "bool"},
+ {TOK_VOID, "void"},
+ {TOK_CHAR, "char"},
+ {TOK_INT, "int"},
+ {TOK_UNSIGNED, "unsigned"},
+ {TOK_SHORT, "short"},
+ {TOK_LONG, "long"},
+ {TOK_HYPER, "hyper"},
+ {TOK_FLOAT, "float"},
+ {TOK_DOUBLE, "double"},
+ {TOK_QUAD, "quadruple"},
+ {TOK_STRING, "string"},
+ {TOK_PROGRAM, "program"},
+ {TOK_VERSION, "version"},
+ {TOK_EOF, "??????"},
+};
+
+static void
+findkind(mark, tokp)
+ char **mark;
+ token *tokp;
+{
+ int len;
+ token *s;
+ char *str;
+
+ str = *mark;
+ for (s = symbols; s->kind != TOK_EOF; s++) {
+ len = strlen(s->str);
+ if (strncmp(str, s->str, len) == 0) {
+ if (!isalnum(str[len]) && str[len] != '_') {
+ tokp->kind = s->kind;
+ tokp->str = s->str;
+ *mark = str + len;
+ return;
+ }
+ }
+ }
+ tokp->kind = TOK_IDENT;
+ for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
+ tokp->str = alloc(len + 1);
+ (void) strncpy(tokp->str, str, len);
+ tokp->str[len] = 0;
+ *mark = str + len;
+}
+
+static int
+cppline(line)
+ char *line;
+{
+ return (line == curline && *line == '#');
+}
+
+static int
+directive(line)
+ char *line;
+{
+ return (line == curline && *line == '%');
+}
+
+static void
+printdirective(line)
+ char *line;
+{
+ f_print(fout, "%s", line + 1);
+}
+
+static void
+docppline(line, lineno, fname)
+ char *line;
+ int *lineno;
+ char **fname;
+{
+ char *file;
+ int num;
+ char *p;
+
+ line++;
+ while (isspace(*line)) {
+ line++;
+ }
+ num = atoi(line);
+ while (isdigit(*line)) {
+ line++;
+ }
+ while (isspace(*line)) {
+ line++;
+ }
+ if (*line != '"') {
+ error("preprocessor error");
+ }
+ line++;
+ p = file = alloc(strlen(line) + 1);
+ while (*line && *line != '"') {
+ *p++ = *line++;
+ }
+ if (*line == 0) {
+ error("preprocessor error");
+ }
+ *p = 0;
+ if (*file == 0) {
+ *fname = NULL;
+ } else {
+ *fname = file;
+ }
+ *lineno = num - 1;
+}
diff --git a/developer_cmds/rpcgen/rpc_scan.h b/developer_cmds/rpcgen/rpc_scan.h
new file mode 100644
index 0000000..e4c57c8
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_scan.h
@@ -0,0 +1,104 @@
+/* $NetBSD: rpc_scan.h,v 1.4 1997/10/11 21:01:50 christos Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
+
+/*
+ * rpc_scan.h, Definitions for the RPCL scanner
+ */
+
+/*
+ * kinds of tokens
+ */
+enum tok_kind {
+ TOK_IDENT,
+ TOK_CHARCONST,
+ TOK_STRCONST,
+ TOK_LPAREN,
+ TOK_RPAREN,
+ TOK_LBRACE,
+ TOK_RBRACE,
+ TOK_LBRACKET,
+ TOK_RBRACKET,
+ TOK_LANGLE,
+ TOK_RANGLE,
+ TOK_STAR,
+ TOK_COMMA,
+ TOK_EQUAL,
+ TOK_COLON,
+ TOK_SEMICOLON,
+ TOK_CONST,
+ TOK_STRUCT,
+ TOK_UNION,
+ TOK_SWITCH,
+ TOK_CASE,
+ TOK_DEFAULT,
+ TOK_ENUM,
+ TOK_TYPEDEF,
+ TOK_INT,
+ TOK_SHORT,
+ TOK_LONG,
+ TOK_HYPER,
+ TOK_UNSIGNED,
+ TOK_FLOAT,
+ TOK_DOUBLE,
+ TOK_QUAD,
+ TOK_OPAQUE,
+ TOK_CHAR,
+ TOK_STRING,
+ TOK_BOOL,
+ TOK_VOID,
+ TOK_PROGRAM,
+ TOK_VERSION,
+ TOK_EOF
+};
+typedef enum tok_kind tok_kind;
+
+/*
+ * a token
+ */
+struct token {
+ tok_kind kind;
+ char *str;
+};
+typedef struct token token;
+
+
+/*
+ * routine interface
+ */
+void scan __P((tok_kind, token *));
+void scan2 __P((tok_kind, tok_kind, token *));
+void scan3 __P((tok_kind, tok_kind, tok_kind, token *));
+void scan_num __P((token *));
+void peek __P((token *));
+int peekscan __P((tok_kind, token *));
+void get_token __P((token *));
diff --git a/developer_cmds/rpcgen/rpc_svcout.c b/developer_cmds/rpcgen/rpc_svcout.c
new file mode 100644
index 0000000..cb0ed46
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_svcout.c
@@ -0,0 +1,980 @@
+/* $NetBSD: rpc_svcout.c,v 1.10 1997/10/18 10:54:07 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_svcout.c,v 1.10 1997/10/18 10:54:07 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+static char RQSTP[] = "rqstp";
+static char TRANSP[] = "transp";
+static char ARG[] = "argument";
+static char RESULT[] = "result";
+static char ROUTINE[] = "local";
+
+static void p_xdrfunc __P((char *, char *));
+static void internal_proctype __P((proc_list *));
+static void write_real_program __P((definition *));
+static void write_program __P((definition *, char *));
+static void printerr __P((char *, char *));
+static void printif __P((char *, char *, char *, char *));
+static void write_inetmost __P((char *));
+static void print_return __P((char *));
+static void print_pmapunset __P((char *));
+static void print_err_message __P((char *));
+static void write_timeout_func __P((void));
+static void write_caller_func __P((void));
+static void write_pm_most __P((char *, int));
+static void write_rpc_svc_fg __P((char *, char *));
+static void open_log_file __P((char *, char *));
+
+char _errbuf[256]; /* For all messages */
+
+static void
+p_xdrfunc(rname, typename)
+ char *rname;
+ char *typename;
+{
+ if (Cflag)
+ f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname,
+ stringfix(typename));
+ else
+ f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename));
+}
+
+static void
+internal_proctype(plist)
+ proc_list *plist;
+{
+ f_print(fout, "static ");
+ ptype(plist->res_prefix, plist->res_type, 1);
+ f_print(fout, "*");
+}
+
+
+/*
+ * write most of the service, that is, everything but the registrations.
+ */
+void
+write_most(infile, netflag, nomain)
+ char *infile; /* our name */
+ int netflag;
+ int nomain;
+{
+ if (inetdflag || pmflag) {
+ char *var_type;
+ var_type = (nomain ? "extern" : "static");
+ f_print(fout, "%s int _rpcpmstart;", var_type);
+ f_print(fout, "\t\t/* Started by a port monitor ? */\n");
+ f_print(fout, "%s int _rpcfdtype;", var_type);
+ f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
+ if (timerflag) {
+ f_print(fout, "%s int _rpcsvcdirty;", var_type);
+ f_print(fout, "\t/* Still serving ? */\n");
+ }
+ write_svc_aux(nomain);
+ }
+ /* write out dispatcher and stubs */
+ write_programs(nomain ? (char *) NULL : "static");
+
+ if (nomain)
+ return;
+
+ f_print(fout, "\n\n");
+ if (Cflag)
+ f_print(fout, "int main( int argc, char* argv[] );\n");
+ f_print(fout, "\nint\n");
+ if (Cflag)
+ f_print(fout, "main( int argc, char* argv[] )\n");
+ else
+ f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n");
+ f_print(fout, "{\n");
+ if (inetdflag) {
+ write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
+ } else {
+ if (tirpcflag) {
+ if (netflag) {
+ f_print(fout, "\tSVCXPRT *%s;\n", TRANSP);
+ f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
+ }
+ f_print(fout, "\tpid_t pid;\n");
+ f_print(fout, "\tint i;\n");
+ f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
+ write_pm_most(infile, netflag);
+ f_print(fout, "\telse {\n");
+ write_rpc_svc_fg(infile, "\t\t");
+ f_print(fout, "\t}\n");
+ } else {
+ f_print(fout, "\tSVCXPRT *%s;\n", TRANSP);
+ f_print(fout, "\n");
+ print_pmapunset("\t");
+ }
+ }
+
+ if (logflag && !inetdflag) {
+ open_log_file(infile, "\t");
+ }
+}
+/*
+ * write a registration for the given transport
+ */
+void
+write_netid_register(transp)
+ char *transp;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ char *sp;
+ char tmpbuf[32];
+
+ sp = "";
+ f_print(fout, "\n");
+ f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
+ f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
+ (void) sprintf(_errbuf, "cannot find %s netid.", transp);
+ sprintf(tmpbuf, "%s\t\t", sp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+ f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
+ sp, TRANSP);
+ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+ (void) sprintf(_errbuf, "cannot create %s service.", transp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout,
+ "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
+ sp, def->def_name, vp->vers_name);
+ f_print(fout,
+ "%s\tif (!svc_reg(%s, %s, %s, ",
+ sp, TRANSP, def->def_name, vp->vers_name);
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, ", nconf)) {\n");
+ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
+ def->def_name, vp->vers_name, transp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+ }
+ }
+ f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
+}
+/*
+ * write a registration for the given transport for TLI
+ */
+void
+write_nettype_register(transp)
+ char *transp;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout, "\tif (!svc_create(");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, ", %s, %s, \"%s\")) {\n ",
+ def->def_name, vp->vers_name, transp);
+ (void) sprintf(_errbuf,
+ "unable to create (%s, %s) for %s.",
+ def->def_name, vp->vers_name, transp);
+ print_err_message("\t\t");
+ f_print(fout, "\t\texit(1);\n");
+ f_print(fout, "\t}\n");
+ }
+ }
+}
+/*
+ * write the rest of the service
+ */
+void
+write_rest()
+{
+ f_print(fout, "\n");
+ if (inetdflag) {
+ f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
+ (void) sprintf(_errbuf, "could not create a handle");
+ print_err_message("\t\t");
+ f_print(fout, "\t\texit(1);\n");
+ f_print(fout, "\t}\n");
+ if (timerflag) {
+ f_print(fout, "\tif (_rpcpmstart) {\n");
+ f_print(fout,
+ "\t\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag ? "(SIG_PF)" : "(void(*)())");
+ f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+ f_print(fout, "\t}\n");
+ }
+ }
+ f_print(fout, "\tsvc_run();\n");
+ (void) sprintf(_errbuf, "svc_run returned");
+ print_err_message("\t");
+ f_print(fout, "\texit(1);\n");
+ f_print(fout, "\t/* NOTREACHED */\n");
+ f_print(fout, "}\n");
+}
+
+void
+write_programs(storage)
+ char *storage;
+{
+ list *l;
+ definition *def;
+
+ /* write out stubs for procedure definitions */
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ write_real_program(def);
+ }
+ }
+
+ /* write out dispatcher for each program */
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ write_program(def, storage);
+ }
+ }
+
+
+}
+/* write out definition of internal function (e.g. _printmsg_1(...))
+ which calls server's defintion of actual function (e.g. printmsg_1(...)).
+ Unpacks single user argument of printmsg_1 to call-by-value format
+ expected by printmsg_1. */
+static void
+write_real_program(def)
+ definition *def;
+{
+ version_list *vp;
+ proc_list *proc;
+ decl_list *l;
+
+ if (!newstyle)
+ return; /* not needed for old style */
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\n");
+ internal_proctype(proc);
+ f_print(fout, "\n_");
+ pvname(proc->proc_name, vp->vers_num);
+ if (Cflag) {
+ f_print(fout, "(");
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print(fout, "%s", proc->args.argname);
+ else
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ f_print(fout, " *argp, struct svc_req *%s)\n",
+ RQSTP);
+ } else {
+ f_print(fout, "(argp, %s)\n", RQSTP);
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print(fout, "\t%s *argp;\n", proc->args.argname);
+ else {
+ f_print(fout, "\t");
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ f_print(fout, " *argp;\n");
+ }
+ f_print(fout, " struct svc_req *%s;\n", RQSTP);
+ }
+
+ f_print(fout, "{\n");
+ f_print(fout, "\treturn(");
+ pvname_svc(proc->proc_name, vp->vers_num);
+ f_print(fout, "(");
+ if (proc->arg_num < 2) { /* single argument */
+ if (!streq(proc->args.decls->decl.type, "void"))
+ f_print(fout, "*argp, "); /* non-void */
+ } else {
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ f_print(fout, "argp->%s, ", l->decl.name);
+ }
+ f_print(fout, "%s));\n}\n", RQSTP);
+ }
+ }
+}
+
+static void
+write_program(def, storage)
+ definition *def;
+ char *storage;
+{
+ version_list *vp;
+ proc_list *proc;
+ int filled;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ if (Cflag) {
+ f_print(fout, "\n");
+ if (storage != NULL) {
+ f_print(fout, "%s ", storage);
+ }
+ f_print(fout, "void ");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, "(struct svc_req *%s, ", RQSTP);
+ f_print(fout, "SVCXPRT *%s);\n", TRANSP);
+ }
+ f_print(fout, "\n");
+ if (storage != NULL) {
+ f_print(fout, "%s ", storage);
+ }
+ f_print(fout, "void\n");
+ pvname(def->def_name, vp->vers_num);
+
+ if (Cflag) {
+ f_print(fout, "(struct svc_req *%s, ", RQSTP);
+ f_print(fout, "SVCXPRT *%s)\n", TRANSP);
+ } else {
+ f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
+ f_print(fout, " struct svc_req *%s;\n", RQSTP);
+ f_print(fout, " SVCXPRT *%s;\n", TRANSP);
+ }
+
+ f_print(fout, "{\n");
+
+ filled = 0;
+ f_print(fout, "\tunion {\n");
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ if (proc->arg_num < 2) { /* single argument */
+ if (streq(proc->args.decls->decl.type,
+ "void")) {
+ continue;
+ }
+ filled = 1;
+ f_print(fout, "\t\t");
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_arg;\n");
+
+ } else {
+ filled = 1;
+ f_print(fout, "\t\t%s", proc->args.argname);
+ f_print(fout, " ");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_arg;\n");
+ }
+ }
+ if (!filled) {
+ f_print(fout, "\t\tint fill;\n");
+ }
+ f_print(fout, "\t} %s;\n", ARG);
+ f_print(fout, "\tchar *%s;\n", RESULT);
+
+ if (Cflag) {
+ f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
+ f_print(fout,
+ "\tchar *(*%s)(char *, struct svc_req *);\n",
+ ROUTINE);
+ } else {
+ f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
+ f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
+ }
+
+ f_print(fout, "\n");
+
+ if (callerflag)
+ f_print(fout, "\tcaller = transp;\n"); /* EVAS */
+ if (timerflag)
+ f_print(fout, "\t_rpcsvcdirty = 1;\n");
+ f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
+ if (!nullproc(vp->procs)) {
+ f_print(fout, "\tcase NULLPROC:\n");
+ f_print(fout,
+ "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
+ TRANSP);
+ print_return("\t\t");
+ f_print(fout, "\n");
+ }
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\tcase %s:\n", proc->proc_name);
+ if (proc->arg_num < 2) { /* single argument */
+ p_xdrfunc(ARG, proc->args.decls->decl.type);
+ } else {
+ p_xdrfunc(ARG, proc->args.argname);
+ }
+ p_xdrfunc(RESULT, proc->res_type);
+ if (Cflag)
+ f_print(fout,
+ "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
+ ROUTINE);
+ else
+ f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
+
+ if (newstyle) { /* new style: calls internal routine */
+ f_print(fout, "_");
+ }
+ if (!newstyle)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, ";\n");
+ f_print(fout, "\t\tbreak;\n\n");
+ }
+ f_print(fout, "\tdefault:\n");
+ printerr("noproc", TRANSP);
+ print_return("\t\t");
+ f_print(fout, "\t}\n");
+
+ f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
+ printif("getargs", TRANSP, "(caddr_t) &", ARG);
+ printerr("decode", TRANSP);
+ print_return("\t\t");
+ f_print(fout, "\t}\n");
+
+ if (Cflag)
+ f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ else
+ f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ f_print(fout,
+ "\tif (%s != NULL && !svc_sendreply(%s, (xdrproc_t) xdr_%s, %s)) {\n",
+ RESULT, TRANSP, RESULT, RESULT);
+ printerr("systemerr", TRANSP);
+ f_print(fout, "\t}\n");
+
+ printif("freeargs", TRANSP, "(caddr_t) &", ARG);
+ (void) sprintf(_errbuf, "unable to free arguments");
+ print_err_message("\t\t");
+ f_print(fout, "\t\texit(1);\n");
+ f_print(fout, "\t}\n");
+ print_return("\t");
+ f_print(fout, "}\n");
+ }
+}
+
+static void
+printerr(err, transp)
+ char *err;
+ char *transp;
+{
+ f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
+}
+
+static void
+printif(proc, transp, prefix, arg)
+ char *proc;
+ char *transp;
+ char *prefix;
+ char *arg;
+{
+ f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n",
+ proc, transp, arg, prefix, arg);
+}
+
+int
+nullproc(proc)
+ proc_list *proc;
+{
+ for (; proc != NULL; proc = proc->next) {
+ if (streq(proc->proc_num, "0")) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void
+write_inetmost(infile)
+ char *infile;
+{
+ f_print(fout, "\tSVCXPRT *%s = NULL;\n", TRANSP);
+ f_print(fout, "\tint sock;\n");
+ f_print(fout, "\tint proto = 0;\n");
+ f_print(fout, "\tstruct sockaddr_in saddr;\n");
+ f_print(fout, "\tint asize = sizeof (saddr);\n");
+ f_print(fout, "\n");
+ f_print(fout,
+ "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
+ f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
+ f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
+ f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\tsock = 0;\n");
+ f_print(fout, "\t\t_rpcpmstart = 1;\n");
+ f_print(fout, "\t\tproto = 0;\n");
+ open_log_file(infile, "\t\t");
+ f_print(fout, "\t} else {\n");
+ write_rpc_svc_fg(infile, "\t\t");
+ f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
+ print_pmapunset("\t\t");
+ f_print(fout, "\t}\n");
+}
+
+static void
+print_return(space)
+ char *space;
+{
+ if (exitnow)
+ f_print(fout, "%sexit(0);\n", space);
+ else {
+ if (timerflag)
+ f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
+ f_print(fout, "%sreturn;\n", space);
+ }
+}
+
+static void
+print_pmapunset(space)
+ char *space;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ for (vp = def->def.pr.versions; vp != NULL;
+ vp = vp->next) {
+ f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
+ space, def->def_name, vp->vers_name);
+ }
+ }
+ }
+}
+
+static void
+print_err_message(space)
+ char *space;
+{
+ if (logflag)
+ f_print(fout, "%ssyslog(LOG_ERR, \"%%s\", \"%s\");\n", space, _errbuf);
+ else
+ if (inetdflag || pmflag)
+ f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
+ else
+ f_print(fout, "%sfprintf(stderr, \"%%s\", \"%s\");\n", space, _errbuf);
+}
+/*
+ * Write the server auxiliary function ( _msgout, timeout)
+ */
+void
+write_svc_aux(nomain)
+ int nomain;
+{
+ if (!logflag)
+ write_msg_out();
+ if (!nomain)
+ write_timeout_func();
+ if (callerflag) /* EVAS */
+ write_caller_func(); /* EVAS */
+}
+/*
+ * Write the _msgout function
+ */
+void
+write_msg_out()
+{
+ f_print(fout, "\n");
+ f_print(fout, "static\n");
+ if (!Cflag) {
+ f_print(fout, "void _msgout(msg)\n");
+ f_print(fout, "\tchar *msg;\n");
+ } else {
+ f_print(fout, "void _msgout(char* msg)\n");
+ }
+ f_print(fout, "{\n");
+ f_print(fout, "#ifdef RPC_SVC_FG\n");
+ if (inetdflag || pmflag)
+ f_print(fout, "\tif (_rpcpmstart)\n");
+ f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
+ f_print(fout, "\telse\n");
+ f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
+ f_print(fout, "#else\n");
+ f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
+ f_print(fout, "#endif\n");
+ f_print(fout, "}\n");
+}
+/*
+ * Write the timeout function
+ */
+static void
+write_timeout_func()
+{
+ if (!timerflag)
+ return;
+ if (Cflag) {
+ f_print(fout, "\n");
+ f_print(fout, "static void closedown(void);\n");
+ }
+ f_print(fout, "\n");
+ f_print(fout, "static void\n");
+ f_print(fout, "closedown()\n");
+ f_print(fout, "{\n");
+ f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
+ f_print(fout, "\t\textern fd_set svc_fdset;\n");
+ f_print(fout, "\t\tstatic int size;\n");
+ f_print(fout, "\t\tint i, openfd;\n");
+ if (tirpcflag && pmflag) {
+ f_print(fout, "\t\tstruct t_info tinfo;\n\n");
+ f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
+ } else {
+ f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
+ }
+ f_print(fout, "\t\t\texit(0);\n");
+ f_print(fout, "\t\tif (size == 0) {\n");
+ if (tirpcflag) {
+ f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
+ f_print(fout, "\t\t\trl.rlim_max = 0;\n");
+ f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
+ f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
+ f_print(fout, "\t\t\t\treturn;\n");
+ } else {
+ f_print(fout, "\t\t\tsize = getdtablesize();\n");
+ }
+ f_print(fout, "\t\t}\n");
+ f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
+ f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
+ f_print(fout, "\t\t\t\topenfd++;\n");
+ f_print(fout, "\t\tif (openfd <= (_rpcpmstart?0:1))\n");
+ f_print(fout, "\t\t\texit(0);\n");
+ f_print(fout, "\t}\n");
+ f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+ f_print(fout, "}\n");
+}
+
+static void
+write_caller_func()
+{ /* EVAS */
+#define P(s) f_print(fout, s);
+
+ P("\n");
+ P("char *svc_caller()\n");
+ P("{\n");
+ P(" struct sockaddr_in actual;\n");
+ P(" struct hostent *hp;\n");
+ P(" static struct in_addr prev;\n");
+ P(" static char cname[128];\n\n");
+
+ P(" actual = *svc_getcaller(caller);\n\n");
+
+ P(" if (memcmp((char *)&actual.sin_addr, (char *)&prev,\n");
+ P(" sizeof(struct in_addr)) == 0)\n");
+ P(" return (cname);\n\n");
+
+ P(" prev = actual.sin_addr;\n\n");
+
+ P(" hp = gethostbyaddr((char *) &actual.sin_addr, sizeof(actual.sin_addr), AF_INET);\n");
+ P(" if (hp == NULL) { /* dummy one up */\n");
+ P(" extern char *inet_ntoa();\n");
+ P(" strcpy(cname, inet_ntoa(actual.sin_addr));\n");
+ P(" } else {\n");
+ P(" strcpy(cname, hp->h_name);\n");
+ P(" }\n\n");
+
+ P(" return (cname);\n");
+ P("}\n");
+
+#undef P
+}
+/*
+ * Write the most of port monitor support
+ */
+static void
+write_pm_most(infile, netflag)
+ char *infile;
+ int netflag;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
+ f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
+ f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
+ f_print(fout, "\t\tchar *netid;\n");
+ if (!netflag) { /* Not included by -n option */
+ f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
+ f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
+ }
+ if (timerflag)
+ f_print(fout, "\t\tint pmclose;\n");
+/* not necessary, defined in /usr/include/stdlib */
+/* f_print(fout, "\t\textern char *getenv();\n");*/
+ f_print(fout, "\n");
+ f_print(fout, "\t\t_rpcpmstart = 1;\n");
+ if (logflag)
+ open_log_file(infile, "\t\t");
+ f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
+ sprintf(_errbuf, "cannot get transport name");
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
+ sprintf(_errbuf, "cannot get transport info");
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t}\n");
+ /*
+ * A kludgy support for inetd services. Inetd only works with
+ * sockmod, and RPC works only with timod, hence all this jugglery
+ */
+ f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
+ f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
+ sprintf(_errbuf, "could not get the right module");
+ print_err_message("\t\t\t\t");
+ f_print(fout, "\t\t\t\texit(1);\n");
+ f_print(fout, "\t\t\t}\n");
+ f_print(fout, "\t\t}\n");
+ if (timerflag)
+ f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
+ f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
+ TRANSP);
+ sprintf(_errbuf, "cannot create server handle");
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\t}\n");
+ f_print(fout, "\t\tif (nconf)\n");
+ f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout,
+ "\t\tif (!svc_reg(%s, %s, %s, ",
+ TRANSP, def->def_name, vp->vers_name);
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, ", 0)) {\n");
+ (void) sprintf(_errbuf, "unable to register (%s, %s).",
+ def->def_name, vp->vers_name);
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\t}\n");
+ }
+ }
+ if (timerflag) {
+ f_print(fout, "\t\tif (pmclose) {\n");
+ f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag ? "(SIG_PF)" : "(void(*)())");
+ f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+ f_print(fout, "\t\t}\n");
+ }
+ f_print(fout, "\t\tsvc_run();\n");
+ f_print(fout, "\t\texit(1);\n");
+ f_print(fout, "\t\t/* NOTREACHED */\n");
+ f_print(fout, "\t}\n");
+}
+/*
+ * Support for backgrounding the server if self started.
+ */
+static void
+write_rpc_svc_fg(infile, sp)
+ char *infile;
+ char *sp;
+{
+ f_print(fout, "#ifndef RPC_SVC_FG\n");
+ f_print(fout, "%sint size;\n", sp);
+ if (tirpcflag)
+ f_print(fout, "%sstruct rlimit rl;\n", sp);
+ if (inetdflag)
+ f_print(fout, "%sint pid, i;\n\n", sp);
+ f_print(fout, "%spid = fork();\n", sp);
+ f_print(fout, "%sif (pid < 0) {\n", sp);
+ f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
+ f_print(fout, "%s\texit(1);\n", sp);
+ f_print(fout, "%s}\n", sp);
+ f_print(fout, "%sif (pid)\n", sp);
+ f_print(fout, "%s\texit(0);\n", sp);
+ /* get number of file descriptors */
+ if (tirpcflag) {
+ f_print(fout, "%srl.rlim_max = 0;\n", sp);
+ f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
+ f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
+ f_print(fout, "%s\texit(1);\n", sp);
+ } else {
+ f_print(fout, "%ssize = getdtablesize();\n", sp);
+ }
+
+ f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
+ f_print(fout, "%s\t(void) close(i);\n", sp);
+ /* Redirect stderr and stdout to console */
+ f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
+ f_print(fout, "%s(void) dup2(i, 1);\n", sp);
+ f_print(fout, "%s(void) dup2(i, 2);\n", sp);
+ /* This removes control of the controlling terminal */
+ if (tirpcflag)
+ f_print(fout, "%ssetsid();\n", sp);
+ else {
+ f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
+ f_print(fout, "%sif (i >= 0) {\n", sp);
+ f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
+ f_print(fout, "%s\t(void) close(i);\n", sp);
+ f_print(fout, "%s}\n", sp);
+ }
+ if (!logflag)
+ open_log_file(infile, sp);
+ f_print(fout, "#endif\n");
+ if (logflag)
+ open_log_file(infile, sp);
+}
+
+static void
+open_log_file(infile, sp)
+ char *infile;
+ char *sp;
+{
+ char *s, *p;
+
+ s = strrchr(infile, '.');
+ if (s)
+ *s = '\0';
+ p = strrchr(infile, '/');
+ if (p)
+ p++;
+ else
+ p = infile;
+ f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, p);
+ if (s)
+ *s = '.';
+}
+
+/*
+ * write a registration for the given transport for Inetd
+ */
+void
+write_inetd_register(transp)
+ char *transp;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ char *sp;
+ int isudp;
+ char tmpbuf[32];
+
+ if (inetdflag)
+ sp = "\t";
+ else
+ sp = "";
+ if (streq(transp, "udp"))
+ isudp = 1;
+ else
+ isudp = 0;
+ f_print(fout, "\n");
+ if (inetdflag) {
+ f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
+ isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
+ }
+ if (inetdflag && streq(transp, "tcp")) {
+ f_print(fout, "%s\tif (_rpcpmstart)\n", sp);
+
+ f_print(fout, "%s\t\t%s = svc%s_create(%s",
+ sp, TRANSP, "fd", inetdflag ? "sock" : "RPC_ANYSOCK");
+ if (!isudp)
+ f_print(fout, ", 0, 0");
+ f_print(fout, ");\n");
+
+ f_print(fout, "%s\telse\n", sp);
+
+ f_print(fout, "%s\t\t%s = svc%s_create(%s",
+ sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
+ if (!isudp)
+ f_print(fout, ", 0, 0");
+ f_print(fout, ");\n");
+
+ } else {
+ f_print(fout, "%s\t%s = svc%s_create(%s",
+ sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
+ if (!isudp)
+ f_print(fout, ", 0, 0");
+ f_print(fout, ");\n");
+ }
+ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+ (void) sprintf(_errbuf, "cannot create %s service.", transp);
+ (void) sprintf(tmpbuf, "%s\t\t", sp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+
+ if (inetdflag) {
+ f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
+ f_print(fout, "%s\tproto = IPPROTO_%s;\n",
+ sp, isudp ? "UDP" : "TCP");
+ }
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
+ sp, TRANSP, def->def_name, vp->vers_name);
+ pvname(def->def_name, vp->vers_num);
+ if (inetdflag)
+ f_print(fout, ", proto)) {\n");
+ else
+ f_print(fout, ", IPPROTO_%s)) {\n",
+ isudp ? "UDP" : "TCP");
+ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
+ def->def_name, vp->vers_name, transp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+ }
+ }
+ if (inetdflag)
+ f_print(fout, "\t}\n");
+}
diff --git a/developer_cmds/rpcgen/rpc_tblout.c b/developer_cmds/rpcgen/rpc_tblout.c
new file mode 100644
index 0000000..610dcd0
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_tblout.c
@@ -0,0 +1,179 @@
+/* $NetBSD: rpc_tblout.c,v 1.7 1997/10/18 10:54:11 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
+#else
+__RCSID("$NetBSD: rpc_tblout.c,v 1.7 1997/10/18 10:54:11 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define TABSIZE 8
+#define TABCOUNT 5
+#define TABSTOP (TABSIZE*TABCOUNT)
+
+static char tabstr[TABCOUNT + 1] = "\t\t\t\t\t";
+
+static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
+static char tbl_end[] = "};\n";
+
+static char null_entry[] = "\t(char *(*)())0,\n\
+ \t(xdrproc_t)xdr_void,\t\t0,\n\
+ \t(xdrproc_t)xdr_void,\t\t0,\n";
+
+static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
+
+static void write_table __P((definition *));
+static void printit __P((char *, char *));
+
+void
+write_tables()
+{
+ list *l;
+ definition *def;
+
+ f_print(fout, "\n");
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ write_table(def);
+ }
+ }
+}
+
+static void
+write_table(def)
+ definition *def;
+{
+ version_list *vp;
+ proc_list *proc;
+ int current;
+ int expected;
+ char progvers[100];
+ int warning;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ warning = 0;
+ s_print(progvers, "%s_%s",
+ locase(def->def_name), vp->vers_num);
+ /* print the table header */
+ f_print(fout, tbl_hdr, progvers);
+
+ if (nullproc(vp->procs)) {
+ expected = 0;
+ } else {
+ expected = 1;
+ f_print(fout, "%s", null_entry);
+ }
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ if (expected != 0)
+ f_print(fout, "\n");
+ current = atoi(proc->proc_num);
+ if (current != expected++) {
+ f_print(fout,
+ "/*\n * WARNING: table out of order\n */\n\n");
+ if (warning == 0) {
+ f_print(stderr,
+ "WARNING %s table is out of order\n",
+ progvers);
+ warning = 1;
+ nonfatalerrors = 1;
+ }
+ expected = current + 1;
+ }
+ f_print(fout, "\t(char *(*)())RPCGEN_ACTION(");
+
+ /* routine to invoke */
+ if (!newstyle)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else {
+ if (newstyle)
+ f_print(fout, "_"); /* calls internal func */
+ pvname(proc->proc_name, vp->vers_num);
+ }
+ f_print(fout, "),\n");
+
+ /* argument info */
+ if (proc->arg_num > 1)
+ printit((char *) NULL, proc->args.argname);
+ else
+ /* do we have to do something special for
+ * newstyle */
+ printit(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type);
+ /* result info */
+ printit(proc->res_prefix, proc->res_type);
+ }
+
+ /* print the table trailer */
+ f_print(fout, "%s", tbl_end);
+ f_print(fout, tbl_nproc, progvers, progvers, progvers);
+ }
+}
+
+static void
+printit(prefix, type)
+ char *prefix;
+ char *type;
+{
+ int len;
+ int tabs;
+
+
+ len = fprintf(fout, "\txdr_%s,", stringfix(type));
+ /* account for leading tab expansion */
+ len += TABSIZE - 1;
+ /* round up to tabs required */
+ tabs = (TABSTOP - len + TABSIZE - 1) / TABSIZE;
+ f_print(fout, "%s", &tabstr[TABCOUNT - tabs]);
+
+ if (streq(type, "void")) {
+ f_print(fout, "0");
+ } else {
+ f_print(fout, "sizeof ( ");
+ /* XXX: should "follow" be 1 ??? */
+ ptype(prefix, type, 0);
+ f_print(fout, ")");
+ }
+ f_print(fout, ",\n");
+}
diff --git a/developer_cmds/rpcgen/rpc_util.c b/developer_cmds/rpcgen/rpc_util.c
new file mode 100644
index 0000000..f51114c
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_util.c
@@ -0,0 +1,513 @@
+/* $NetBSD: rpc_util.c,v 1.8 1997/10/18 10:54:14 lukem Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
+#else
+__RCSID("$NetBSD: rpc_util.c,v 1.8 1997/10/18 10:54:14 lukem Exp $");
+#endif
+#endif
+
+/*
+ * rpc_util.c, Utility routines for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define ARGEXT "argument"
+
+static void printwhere __P((void));
+
+char curline[MAXLINESIZE]; /* current read line */
+char *where = curline; /* current point in line */
+int linenum = 0; /* current line number */
+
+char *infilename; /* input filename */
+
+#define NFILES 7
+char *outfiles[NFILES]; /* output file names */
+int nfiles;
+
+FILE *fout; /* file pointer of current output */
+FILE *fin; /* file pointer of current input */
+
+list *defined; /* list of defined things */
+
+static char *toktostr __P((tok_kind));
+static void printbuf __P((void));
+static void printwhere __P((void));
+static int findit __P((definition *, char *));
+static char *fixit __P((char *, char *));
+static int typedefed __P((definition *, char *));
+
+/*
+ * Reinitialize the world
+ */
+void
+reinitialize()
+{
+ memset(curline, 0, MAXLINESIZE);
+ where = curline;
+ linenum = 0;
+ defined = NULL;
+}
+/*
+ * string equality
+ */
+int
+streq(a, b)
+ char *a;
+ char *b;
+{
+ return (strcmp(a, b) == 0);
+}
+/*
+ * find a value in a list
+ */
+definition *
+findval(lst, val, cmp)
+ list *lst;
+ char *val;
+ int (*cmp) __P((definition *, char *));
+
+{
+
+ for (; lst != NULL; lst = lst->next) {
+ if ((*cmp) (lst->val, val)) {
+ return (lst->val);
+ }
+ }
+ return (NULL);
+}
+/*
+ * store a value in a list
+ */
+void
+storeval(lstp, val)
+ list **lstp;
+ definition *val;
+{
+ list **l;
+ list *lst;
+
+
+ for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
+ lst = ALLOC(list);
+ lst->val = val;
+ lst->next = NULL;
+ *l = lst;
+}
+
+static int
+findit(def, type)
+ definition *def;
+ char *type;
+{
+ return (streq(def->def_name, type));
+}
+
+static char *
+fixit(type, orig)
+ char *type;
+ char *orig;
+{
+ definition *def;
+
+ def = (definition *) FINDVAL(defined, type, findit);
+ if (def == NULL || def->def_kind != DEF_TYPEDEF) {
+ return (orig);
+ }
+ switch (def->def.ty.rel) {
+ case REL_VECTOR:
+ return (def->def.ty.old_type);
+ case REL_ALIAS:
+ return (fixit(def->def.ty.old_type, orig));
+ default:
+ return (orig);
+ }
+}
+
+char *
+fixtype(type)
+ char *type;
+{
+ return (fixit(type, type));
+}
+
+char *
+stringfix(type)
+ char *type;
+{
+ if (streq(type, "string")) {
+ return ("wrapstring");
+ } else {
+ return (type);
+ }
+}
+
+void
+ptype(prefix, type, follow)
+ char *prefix;
+ char *type;
+ int follow;
+{
+ if (prefix != NULL) {
+ if (streq(prefix, "enum")) {
+ f_print(fout, "enum ");
+ } else {
+ f_print(fout, "struct ");
+ }
+ }
+ if (streq(type, "bool")) {
+ f_print(fout, "bool_t ");
+ } else
+ if (streq(type, "string")) {
+ f_print(fout, "char *");
+ } else {
+ f_print(fout, "%s ", follow ? fixtype(type) : type);
+ }
+}
+
+static int
+typedefed(def, type)
+ definition *def;
+ char *type;
+{
+ if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
+ return (0);
+ } else {
+ return (streq(def->def_name, type));
+ }
+}
+
+int
+isvectordef(type, rel)
+ char *type;
+ relation rel;
+{
+ definition *def;
+
+ for (;;) {
+ switch (rel) {
+ case REL_VECTOR:
+ return (!streq(type, "string"));
+ case REL_ARRAY:
+ return (0);
+ case REL_POINTER:
+ return (0);
+ case REL_ALIAS:
+ def = (definition *) FINDVAL(defined, type, typedefed);
+ if (def == NULL) {
+ return (0);
+ }
+ type = def->def.ty.old_type;
+ rel = def->def.ty.rel;
+ }
+ }
+}
+
+char *
+locase(str)
+ char *str;
+{
+ char c;
+ static char buf[100];
+ char *p = buf;
+
+ while ((c = *str++) != '\0') {
+ *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
+ }
+ *p = 0;
+ return (buf);
+}
+
+void
+pvname_svc(pname, vnum)
+ char *pname;
+ char *vnum;
+{
+ f_print(fout, "%s_%s_svc", locase(pname), vnum);
+}
+
+void
+pvname(pname, vnum)
+ char *pname;
+ char *vnum;
+{
+ f_print(fout, "%s_%s", locase(pname), vnum);
+}
+/*
+ * print a useful (?) error message, and then die
+ */
+void
+error(msg)
+ char *msg;
+{
+ printwhere();
+ f_print(stderr, "%s, line %d: ", infilename, linenum);
+ f_print(stderr, "%s\n", msg);
+ crash();
+}
+/*
+ * Something went wrong, unlink any files that we may have created and then
+ * die.
+ */
+void
+crash()
+{
+ int i;
+
+ for (i = 0; i < nfiles; i++) {
+ (void) unlink(outfiles[i]);
+ }
+ exit(1);
+}
+
+void
+record_open(file)
+ char *file;
+{
+ if (nfiles < NFILES) {
+ outfiles[nfiles++] = file;
+ } else {
+ f_print(stderr, "too many files!\n");
+ crash();
+ }
+}
+
+static char expectbuf[100];
+
+/*
+ * error, token encountered was not the expected one
+ */
+void
+expected1(exp1)
+ tok_kind exp1;
+{
+ s_print(expectbuf, "expected '%s'",
+ toktostr(exp1));
+ error(expectbuf);
+}
+/*
+ * error, token encountered was not one of two expected ones
+ */
+void
+expected2(exp1, exp2)
+ tok_kind exp1, exp2;
+{
+ s_print(expectbuf, "expected '%s' or '%s'",
+ toktostr(exp1),
+ toktostr(exp2));
+ error(expectbuf);
+}
+/*
+ * error, token encountered was not one of 3 expected ones
+ */
+void
+expected3(exp1, exp2, exp3)
+ tok_kind exp1, exp2, exp3;
+{
+ s_print(expectbuf, "expected '%s', '%s' or '%s'",
+ toktostr(exp1),
+ toktostr(exp2),
+ toktostr(exp3));
+ error(expectbuf);
+}
+
+void
+tabify(f, tab)
+ FILE *f;
+ int tab;
+{
+ while (tab--) {
+ (void) fputc('\t', f);
+ }
+}
+
+
+static token tokstrings[] = {
+ {TOK_IDENT, "identifier"},
+ {TOK_CONST, "const"},
+ {TOK_RPAREN, ")"},
+ {TOK_LPAREN, "("},
+ {TOK_RBRACE, "}"},
+ {TOK_LBRACE, "{"},
+ {TOK_LBRACKET, "["},
+ {TOK_RBRACKET, "]"},
+ {TOK_STAR, "*"},
+ {TOK_COMMA, ","},
+ {TOK_EQUAL, "="},
+ {TOK_COLON, ":"},
+ {TOK_SEMICOLON, ";"},
+ {TOK_UNION, "union"},
+ {TOK_STRUCT, "struct"},
+ {TOK_SWITCH, "switch"},
+ {TOK_CASE, "case"},
+ {TOK_DEFAULT, "default"},
+ {TOK_ENUM, "enum"},
+ {TOK_TYPEDEF, "typedef"},
+ {TOK_INT, "int"},
+ {TOK_SHORT, "short"},
+ {TOK_LONG, "long"},
+ {TOK_UNSIGNED, "unsigned"},
+ {TOK_DOUBLE, "double"},
+ {TOK_FLOAT, "float"},
+ {TOK_CHAR, "char"},
+ {TOK_STRING, "string"},
+ {TOK_OPAQUE, "opaque"},
+ {TOK_BOOL, "bool"},
+ {TOK_VOID, "void"},
+ {TOK_PROGRAM, "program"},
+ {TOK_VERSION, "version"},
+ {TOK_EOF, "??????"}
+};
+
+static char *
+toktostr(kind)
+ tok_kind kind;
+{
+ token *sp;
+
+ for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
+ return (sp->str);
+}
+
+static void
+printbuf()
+{
+ char c;
+ int i;
+ int cnt;
+
+#define TABSIZE 4
+
+ for (i = 0; (c = curline[i]) != '\0'; i++) {
+ if (c == '\t') {
+ cnt = 8 - (i % TABSIZE);
+ c = ' ';
+ } else {
+ cnt = 1;
+ }
+ while (cnt--) {
+ (void) fputc(c, stderr);
+ }
+ }
+}
+
+static void
+printwhere()
+{
+ int i;
+ char c;
+ int cnt;
+
+ printbuf();
+ for (i = 0; i < where - curline; i++) {
+ c = curline[i];
+ if (c == '\t') {
+ cnt = 8 - (i % TABSIZE);
+ } else {
+ cnt = 1;
+ }
+ while (cnt--) {
+ (void) fputc('^', stderr);
+ }
+ }
+ (void) fputc('\n', stderr);
+}
+
+char *
+make_argname(pname, vname)
+ char *pname;
+ char *vname;
+{
+ char *name;
+
+ name = (char *) malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
+ if (!name) {
+ fprintf(stderr, "failed in malloc");
+ exit(1);
+ }
+ sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
+ return (name);
+}
+
+bas_type *typ_list_h;
+bas_type *typ_list_t;
+
+void
+add_type(len, type)
+ int len;
+ char *type;
+{
+ bas_type *ptr;
+
+ if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) {
+ fprintf(stderr, "failed in malloc");
+ exit(1);
+ }
+ ptr->name = type;
+ ptr->length = len;
+ ptr->next = NULL;
+ if (typ_list_t == NULL) {
+ typ_list_t = ptr;
+ typ_list_h = ptr;
+ } else {
+ typ_list_t->next = ptr;
+ typ_list_t = ptr;
+ }
+}
+
+bas_type *
+find_type(type)
+ char *type;
+{
+ bas_type *ptr;
+
+ ptr = typ_list_h;
+
+
+ while (ptr != NULL) {
+ if (strcmp(ptr->name, type) == 0)
+ return (ptr);
+ else
+ ptr = ptr->next;
+ }
+ return (NULL);
+}
diff --git a/developer_cmds/rpcgen/rpc_util.h b/developer_cmds/rpcgen/rpc_util.h
new file mode 100644
index 0000000..33a84b3
--- /dev/null
+++ b/developer_cmds/rpcgen/rpc_util.h
@@ -0,0 +1,178 @@
+/* $NetBSD: rpc_util.h,v 1.4 1997/10/11 21:01:58 christos Exp $ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
+
+/*
+ * rpc_util.h, Useful definitions for the RPC protocol compiler
+ */
+#include <sys/types.h>
+#include <stdlib.h>
+
+#define alloc(size) (void *)malloc((unsigned)(size))
+#define ALLOC(object) (object *) malloc(sizeof(object))
+
+#define s_print (void) sprintf
+#define f_print (void) fprintf
+
+struct list {
+ definition *val;
+ struct list *next;
+};
+typedef struct list list;
+
+#define PUT 1
+#define GET 2
+
+/*
+ * Global variables
+ */
+#define MAXLINESIZE 1024
+extern char curline[MAXLINESIZE];
+extern char *where;
+extern int linenum;
+
+extern char *infilename;
+extern FILE *fout;
+extern FILE *fin;
+
+extern list *defined;
+
+
+extern bas_type *typ_list_h;
+extern bas_type *typ_list_t;
+
+/*
+ * All the option flags
+ */
+extern int inetdflag;
+extern int pmflag;
+extern int tblflag;
+extern int logflag;
+extern int newstyle;
+extern int Cflag; /* C++ flag */
+extern int tirpcflag; /* flag for generating tirpc code */
+extern int doinline; /* if this is 0, then do not generate inline code */
+extern int callerflag;
+
+/*
+ * Other flags related with inetd jumpstart.
+ */
+extern int indefinitewait;
+extern int exitnow;
+extern int timerflag;
+
+extern int nonfatalerrors;
+
+extern pid_t childpid;
+
+/*
+ * rpc_util routines
+ */
+
+#define STOREVAL(list,item) \
+ storeval(list,item)
+
+#define FINDVAL(list,item,finder) \
+ findval(list, item, finder)
+
+void reinitialize __P((void));
+int streq __P((char *, char *));
+definition *findval __P((list *, char *, int (*)(definition *, char *)));
+void storeval __P((list **, definition *));
+char *fixtype __P((char *));
+char *stringfix __P((char *));
+void ptype __P((char *, char *, int));
+int isvectordef __P((char *, relation));
+char *locase __P((char *));
+void pvname_svc __P((char *, char *));
+void pvname __P((char *, char *));
+void error __P((char *));
+void crash __P((void));
+void record_open __P((char *));
+void expected1 __P((tok_kind));
+void expected2 __P((tok_kind, tok_kind ));
+void expected3 __P((tok_kind, tok_kind, tok_kind));
+void tabify __P((FILE *, int));
+void record_open __P((char *));
+char *make_argname __P((char *, char *));
+void add_type __P((int, char *));
+bas_type *find_type __P((char *));
+/*
+ * rpc_cout routines
+ */
+void emit __P((definition *));
+void emit_inline __P((declaration *, int));
+void emit_single_in_line __P((declaration *, int, relation));
+char *upcase __P((char *));
+
+/*
+ * rpc_hout routines
+ */
+
+void print_datadef __P((definition *));
+void print_funcdef __P((definition *));
+void pxdrfuncdecl __P((char *, int));
+void pprocdef __P((proc_list *, version_list *, char *, int, int));
+void pdeclaration __P((char *, declaration *, int, char *));
+
+/*
+ * rpc_svcout routines
+ */
+void write_most __P((char *, int, int));
+void write_netid_register __P((char *));
+void write_nettype_register __P((char *));
+void write_rest __P((void));
+void write_programs __P((char *));
+int nullproc __P((proc_list *));
+void write_svc_aux __P((int));
+void write_msg_out __P((void));
+void write_inetd_register __P((char *));
+
+/*
+ * rpc_clntout routines
+ */
+void write_stubs __P((void));
+void printarglist __P((proc_list *, char *, char *));
+
+
+/*
+ * rpc_tblout routines
+ */
+void write_tables __P((void));
+
+/*
+ * rpc_sample routines
+ */
+void write_sample_svc __P((definition *));
+int write_sample_clnt __P((definition *));
+void add_sample_msg __P((void));
+void write_sample_clnt_main __P((void));
diff --git a/developer_cmds/rpcgen/rpcgen.1 b/developer_cmds/rpcgen/rpcgen.1
new file mode 100644
index 0000000..a5764a6
--- /dev/null
+++ b/developer_cmds/rpcgen/rpcgen.1
@@ -0,0 +1,452 @@
+.\" $NetBSD: rpcgen.1,v 1.8 1998/04/28 07:19:29 fair Exp $
+.\" from: @(#)rpcgen.new.1 1.1 90/11/09 TIRPC 1.0; from 40.10 of 10/10/89
+.\" Copyright (c) 1988,1990 Sun Microsystems, Inc. - All Rights Reserved.
+.Dd June 11, 1995
+.Dt RPCGEN 1
+.Sh NAME
+.Nm rpcgen
+.Nd Remote Procedure Call (RPC) protocol compiler
+.Sh SYNOPSIS
+.Nm
+.Ar infile
+.Nm
+.Op Fl D Op Ar name=value
+.Op Fl A
+.Op Fl M
+.Op Fl T
+.Op Fl K Ar secs
+.Ar infile
+.Nm
+.Op Fl L
+.Fl c Li |
+.Fl h Li |
+.Fl l Li |
+.Fl m Li |
+.Fl t Li |
+.Fl S\&c Li |
+.Fl S\&s Li |
+.Op Fl o Ar outfile
+.Op Ar infile
+.Nm
+.Fl c Li |
+.Ar nettype
+.Op Fl o Ar outfile
+.Op Ar infile
+.Nm
+.Fl s Li |
+.Ar netid
+.Op Fl o Ar outfile
+.Op Ar infile
+.Sh DESCRIPTION
+.Nm
+is a tool that generates C code to implement an
+.Tn RPC
+protocol.
+The input to
+.Nm
+is a language similar to C known as
+.Tn RPC
+Language (Remote Procedure Call Language).
+.Nm
+is normally used as in the first synopsis where
+it takes an input file and generates up to four output files.
+If the
+.Ar infile
+is named
+.Pa proto.x ,
+then
+.Nm
+will generate a header file in
+.Pa proto.h ,
+.Tn XDR
+routines in
+.Pa proto_xdr.c ,
+server-side stubs in
+.Pa proto_svc.c ,
+and client-side stubs in
+.Pa proto_clnt.c .
+With the
+.Fl T
+option,
+it will also generate the
+.Tn RPC
+dispatch table in
+.Pa proto_tbl.i .
+With the
+.Fl S\&c
+option,
+it will also generate sample code which would illustrate how to use the
+remote procedures on the client side. This code would be created in
+.Pa proto_client.c .
+With the
+.Fl S\&s
+option,
+it will also generate a sample server code which would illustrate how to write
+the remote procedures. This code would be created in
+.Pa proto_server.c .
+.Pp
+The server created can be started both by the port monitors
+(for example,
+.Em inetd
+or
+.Em listen )
+or by itself.
+When it is started by a port monitor,
+it creates servers only for the transport for which
+the file descriptor 0 was passed.
+The name of the transport must be specified
+by setting up the environmental variable
+.Ev PM_TRANSPORT .
+When the server generated by
+.Nm
+is executed,
+it creates server handles for all the transports
+specified in
+.Ev NETPATH
+environment variable,
+or if it is unset,
+it creates server handles for all the visible transports from
+.Pa /etc/netconfig
+file.
+.Pp
+.Em Note:
+the transports are chosen at run time and not at compile time.
+When the server is self-started,
+it backgrounds itself by default.
+A special define symbol
+.Dv RPC_SVC_FG
+can be used to run the server process in foreground.
+.P
+The second synopsis provides special features which allow
+for the creation of more sophisticated
+.Tn RPC
+servers.
+These features include support for user provided
+.Li #defines
+and
+.Tn RPC
+dispatch tables.
+The entries in the
+.Tn RPC
+dispatch table contain:
+.Pp
+.Bl -inset -offset indent -compact
+.It +
+pointers to the service routine corresponding to that procedure,
+.It +
+a pointer to the input and output arguments,
+.It +
+the size of these routines
+.El
+.Pp
+A server can use the dispatch table to check authorization
+and then to execute the service routine;
+a client library may use it to deal with the details of storage
+management and
+.Tn XDR
+data conversion.
+.Pp
+The other three synopses shown above are used when
+one does not want to generate all the output files,
+but only a particular one.
+Some examples of their usage is described in the
+EXAMPLE
+section below.
+When
+.Nm
+is executed with the
+.Fl s
+option,
+it creates servers for that particular class of transports.
+When
+executed with the
+.Fl n
+option,
+it creates a server for the transport specified by
+.Em netid .
+If
+.Ar infile
+is not specified,
+.Nm
+accepts the standard input.
+.Pp
+The C preprocessor,
+.Xr cpp 1
+is run on the input file before it is actually interpreted by
+.Nm
+For each type of output file,
+.Nm
+defines a special preprocessor symbol for use by the
+.Nm
+programmer:
+.Bl -tag -width RPC_CLNT
+.It Dv RPC_HDR
+defined when compiling into header files
+.It Dv RPC_XDR
+defined when compiling into
+.Tn XDR
+routines
+.It Dv RPC_SVC
+defined when compiling into server-side stubs
+.It Dv RPC_CLNT
+defined when compiling into client-side stubs
+.It Dv RPC_TBL
+defined when compiling into
+.Tn RPC
+dispatch tables
+.El
+.Pp
+Any line beginning with
+.Sq %
+is passed directly into the output file,
+uninterpreted by
+.Nm .
+.Pp
+For every data type referred to in
+.Ar infile
+.Nm
+assumes that there exists a
+routine with the string
+.Dq xdr_
+prepended to the name of the data type.
+If this routine does not exist in the
+.Tn RPC/XDR
+library, it must be provided.
+Providing an undefined data type
+allows customization of
+.Tn XDR
+routines.
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl a
+Generate all the files including sample code for client and server side.
+.It Fl b
+This generates code for the
+.Tn "SunOS 4.1"
+style of
+.Tn RPC .
+This is the default.
+.It Fl C
+Generate code in
+.Tn ANSI
+C.
+This option also generates code that could be compiled with the
+C++ compiler.
+.It Fl c
+Compile into
+.Tn XDR
+routines.
+.It Fl D Ar name Ns Op Ar =value
+Define a symbol
+.Dv name .
+Equivalent to the
+.Dv #define
+directive in the source.
+If no
+.Dv value
+is given,
+.Dv value
+is defined as 1.
+This option may be specified more than once.
+.It Fl h
+Compile into C data-definitions (a header file).
+The
+.Fl T
+option can be used in conjunction to produce a
+header file which supports
+.Tn RPC
+dispatch tables.
+.It Fl K Ar secs
+By default, services created using
+.Nm
+wait 120 seconds
+after servicing a request before exiting.
+That interval can be changed using the
+.Fl K
+flag.
+To create a server that exits immediately upon servicing a request,
+.Dq Fl K No 0
+can be used.
+To create a server that never exits, the appropriate argument is
+.Dq Fl K No -1 .
+.Pp
+When monitoring for a server,
+some port monitors, like the
+.At V.4
+utility
+.Xr listen 1 ,
+.Em always
+spawn a new process in response to a service request.
+If it is known that a server will be used with such a monitor, the
+server should exit immediately on completion.
+For such servers,
+.Nm
+should be used with
+.Dq Fl K No -1 .
+.It Fl L
+Server errors will be sent to syslog instead of stderr.
+.It Fl l
+Compile into client-side stubs.
+.It Fl m
+Compile into server-side stubs,
+but do not generate a
+.Fn main
+routine.
+This option is useful for doing callback-routines
+and for users who need to write their own
+.Fn main
+routine to do initialization.
+.It Fl N
+Use the newstyle of
+.Nm .
+This allows procedures to have multiple arguments.
+It also uses the style of parameter passing that closely resembles C.
+So, when passing an argument to a remote procedure you do not have
+to pass a pointer to the argument but the argument itself.
+This behaviour is different from the oldstyle
+of
+.Nm
+generated code.
+The newstyle is not the default case because of backward compatibility.
+.It Fl n Ar netid
+Compile into server-side stubs for the transport
+specified by
+.Ar netid.
+There should be an entry for
+.Ar netid
+in the
+netconfig database.
+This option may be specified more than once,
+so as to compile a server that serves multiple transports.
+.It Fl o Ar outfile
+Specify the name of the output file.
+If none is specified,
+standard output is used
+.Po
+.Fl c Fl h Fl l
+.Fl m Fl n Fl s
+modes only
+.Pc
+.It Fl S\&c
+Generate sample code to show the use of remote procedure and how to bind
+to the server before calling the client side stubs generated by
+.Nm .
+.It Fl S\&s
+Generate skeleton code for the remote procedures on the server side. You would need
+to fill in the actual code for the remote procedures.
+.It Fl s Ar nettype
+Compile into server-side stubs for all the
+transports belonging to the class
+.Ar nettype .
+The supported classes are
+.Em netpath,
+.Em visible,
+.Em circuit_n,
+.Em circuit_v,
+.Em datagram_n,
+.Em datagram_v,
+.Em tcp,
+and
+.Em udp
+[see
+.Xr rpc 3
+for the meanings associated with these classes.
+.Em Note:
+.Bx
+currently supports only the
+.Em tcp
+and
+.Em udp
+classes].
+This option may be specified more than once.
+.Em Note:
+the transports are chosen at run time and not at compile time.
+.It Fl T
+Generate the code to support
+.Tn RPC
+dispatch tables.
+.It Fl t
+Compile into
+.Tn RPC
+dispatch table.
+.El
+.Pp
+The options
+.Fl c ,
+.Fl h ,
+.Fl l ,
+.Fl m ,
+.Fl s ,
+and
+.Fl t
+are used exclusively to generate a particular type of file,
+while the options
+.Fl D
+and
+.Fl T
+are global and can be used with the other options.
+.Sh NOTES
+The
+.Tn RPC
+Language does not support nesting of structures.
+As a work-around,
+structures can be declared at the top-level,
+and their name used inside other structures in
+order to achieve the same effect.
+.Pp
+Name clashes can occur when using program definitions,
+since the apparent scoping does not really apply.
+Most of these can be avoided by giving
+unique names for programs,
+versions,
+procedures and types.
+.Pp
+The server code generated with
+.Fl n
+option refers to the transport indicated by
+.Em netid
+and hence is very site specific.
+.Sh EXAMPLE
+.Pp
+The command
+.Pp
+.Bd -literal -offset indent
+$ rpcgen -T prot.x
+.Ed
+.Pp
+generates the five files:
+.Pa prot.h ,
+.Pa prot_clnt.c ,
+.Pa prot_svc.c ,
+.Pa prot_xdr.c
+and
+.Pa prot_tbl.i .
+.Pp
+The following example sends the C data-definitions (header file)
+to standard output.
+.Pp
+.Bd -literal -offset indent
+$ rpcgen -h prot.x
+.Ed
+.Pp
+To send the test version of the
+.Dv -DTEST ,
+server side stubs for
+all the transport belonging to the class
+.Em datagram_n
+to standard output, use:
+.Pp
+.Bd -literal -offset indent
+$ rpcgen -s datagram_n -DTEST prot.x
+.Ed
+.Pp
+To create the server side stubs for the transport indicated by
+.Em netid
+.Em tcp ,
+use:
+.Pp
+.Bd -literal -offset indent
+$ rpcgen -n tcp -o prot_svc.c prot.x
+.Ed
+.Sh SEE ALSO
+.Xr cpp 1
diff --git a/developer_cmds/unifdef/unifdef.1 b/developer_cmds/unifdef/unifdef.1
new file mode 100644
index 0000000..292ee67
--- /dev/null
+++ b/developer_cmds/unifdef/unifdef.1
@@ -0,0 +1,415 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 2002 - 2010 Tony Finch <dot@dotat.at>. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Dave Yost. It was rewritten to support ANSI C by Tony Finch.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/usr.bin/unifdef/unifdef.1,v 1.30 2010/08/01 09:10:09 joel Exp $
+.\"
+.Dd March 11, 2010
+.Dt UNIFDEF 1
+.Os
+.Sh NAME
+.Nm unifdef , unifdefall
+.Nd remove preprocessor conditionals from code
+.Sh SYNOPSIS
+.Nm
+.Op Fl bBcdeKknsStV
+.Op Fl I Ns Ar path
+.Op Fl D Ns Ar sym Ns Op = Ns Ar val
+.Op Fl U Ns Ar sym
+.Op Fl iD Ns Ar sym Ns Op = Ns Ar val
+.Op Fl iU Ns Ar sym
+.Ar ...
+.Op Fl o Ar outfile
+.Op Ar infile
+.Nm unifdefall
+.Op Fl I Ns Ar path
+.Ar ...
+.Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility selectively processes conditional
+.Xr cpp 1
+directives.
+It removes from a file
+both the directives
+and any additional text that they specify should be removed,
+while otherwise leaving the file alone.
+.Pp
+The
+.Nm
+utility acts on
+.Ic #if , #ifdef , #ifndef , #elif , #else ,
+and
+.Ic #endif
+lines.
+A directive is only processed
+if the symbols specified on the command line are sufficient to allow
+.Nm
+to get a definite value for its control expression.
+If the result is false,
+the directive and the following lines under its control are removed.
+If the result is true,
+only the directive is removed.
+An
+.Ic #ifdef
+or
+.Ic #ifndef
+directive is passed through unchanged
+if its controlling symbol is not specified on the command line.
+Any
+.Ic #if
+or
+.Ic #elif
+control expression that has an unknown value or that
+.Nm
+cannot parse is passed through unchanged.
+By default,
+.Nm
+ignores
+.Ic #if
+and
+.Ic #elif
+lines with constant expressions;
+it can be told to process them by specifying the
+.Fl k
+flag on the command line.
+.Pp
+It understands a commonly-used subset
+of the expression syntax for
+.Ic #if
+and
+.Ic #elif
+lines:
+integer constants,
+integer values of symbols defined on the command line,
+the
+.Fn defined
+operator,
+the operators
+.Ic \&! , < , > , <= , >= , == , != , && , || ,
+and parenthesized expressions.
+A kind of
+.Dq "short circuit"
+evaluation is used for the
+.Ic &&
+operator:
+if either operand is definitely false then the result is false,
+even if the value of the other operand is unknown.
+Similarly,
+if either operand of
+.Ic ||
+is definitely true then the result is true.
+.Pp
+In most cases, the
+.Nm
+utility does not distinguish between object-like macros
+(without arguments) and function-like arguments (with arguments).
+If a macro is not explicitly defined, or is defined with the
+.Fl D
+flag on the command-line, its arguments are ignored.
+If a macro is explicitly undefined on the command line with the
+.Fl U
+flag, it may not have any arguments since this leads to a syntax error.
+.Pp
+The
+.Nm
+utility understands just enough about C
+to know when one of the directives is inactive
+because it is inside
+a comment,
+or affected by a backslash-continued line.
+It spots unusually-formatted preprocessor directives
+and knows when the layout is too odd for it to handle.
+.Pp
+A script called
+.Nm unifdefall
+can be used to remove all conditional
+.Xr cpp 1
+directives from a file.
+It uses
+.Nm Fl s
+and
+.Nm cpp Fl dM
+to get lists of all the controlling symbols
+and their definitions (or lack thereof),
+then invokes
+.Nm
+with appropriate arguments to process the file.
+.Sh OPTIONS
+.Pp
+.Bl -tag -width indent -compact
+.It Fl D Ns Ar sym Ns = Ns Ar val
+Specify that a symbol is defined to a given value
+which is used when evaluating
+.Ic #if
+and
+.Ic #elif
+control expressions.
+.Pp
+.It Fl D Ns Ar sym
+Specify that a symbol is defined to the value 1.
+.Pp
+.It Fl U Ns Ar sym
+Specify that a symbol is undefined.
+If the same symbol appears in more than one argument,
+the last occurrence dominates.
+.Pp
+.It Fl b
+Replace removed lines with blank lines
+instead of deleting them.
+Mutually exclusive with the
+.Fl B
+option.
+.Pp
+.It Fl B
+Compress blank lines around a deleted section.
+Mutually exclusive with the
+.Fl b
+option.
+.Pp
+.It Fl c
+If the
+.Fl c
+flag is specified,
+then the operation of
+.Nm
+is complemented,
+i.e., the lines that would have been removed or blanked
+are retained and vice versa.
+.Pp
+.It Fl d
+Turn on printing of debugging messages.
+.Pp
+.It Fl e
+Because
+.Nm
+processes its input one line at a time,
+it cannot remove preprocessor directives that span more than one line.
+The most common example of this is a directive with a multi-line
+comment hanging off its right hand end.
+By default,
+if
+.Nm
+has to process such a directive,
+it will complain that the line is too obfuscated.
+The
+.Fl e
+option changes the behaviour so that,
+where possible,
+such lines are left unprocessed instead of reporting an error.
+.Pp
+.It Fl K
+Always treat the result of
+.Ic &&
+and
+.Ic ||
+operators as unknown if either operand is unknown,
+instead of short-circuiting when unknown operands can't affect the result.
+This option is for compatibility with older versions of
+.Nm .
+.Pp
+.It Fl k
+Process
+.Ic #if
+and
+.Ic #elif
+lines with constant expressions.
+By default, sections controlled by such lines are passed through unchanged
+because they typically start
+.Dq Li "#if 0"
+and are used as a kind of comment to sketch out future or past development.
+It would be rude to strip them out, just as it would be for normal comments.
+.Pp
+.It Fl n
+Add
+.Li #line
+directives to the output following any deleted lines,
+so that errors produced when compiling the output file correspond to
+line numbers in the input file.
+.Pp
+.It Fl o Ar outfile
+Write output to the file
+.Ar outfile
+instead of the standard output.
+If
+.Ar outfile
+is the same as the input file,
+the output is written to a temporary file
+which is renamed into place when
+.Nm
+completes successfully.
+.Pp
+.It Fl s
+Instead of processing the input file as usual,
+this option causes
+.Nm
+to produce a list of symbols that appear in expressions
+that
+.Nm
+understands.
+It is useful in conjunction with the
+.Fl dM
+option of
+.Xr cpp 1
+for creating
+.Nm
+command lines.
+.Pp
+.It Fl S
+Like the
+.Fl s
+option, but the nesting depth of each symbol is also printed.
+This is useful for working out the number of possible combinations
+of interdependent defined/undefined symbols.
+.Pp
+.It Fl t
+Disables parsing for C comments
+and line continuations,
+which is useful
+for plain text.
+.Pp
+.It Fl iD Ns Ar sym Ns Op = Ns Ar val
+.It Fl iU Ns Ar sym
+Ignore
+.Ic #ifdef Ns s .
+If your C code uses
+.Ic #ifdef Ns s
+to delimit non-C lines,
+such as comments
+or code which is under construction,
+then you must tell
+.Nm
+which symbols are used for that purpose so that it will not try to parse
+comments
+and line continuations
+inside those
+.Ic #ifdef Ns s .
+You can specify ignored symbols with
+.Fl iD Ns Ar sym Ns Oo = Ns Ar val Oc
+and
+.Fl iU Ns Ar sym
+similar to
+.Fl D Ns Ar sym Ns Op = Ns Ar val
+and
+.Fl U Ns Ar sym
+above.
+.Pp
+.It Fl I Ns Ar path
+Specifies to
+.Nm unifdefall
+an additional place to look for
+.Ic #include
+files.
+This option is ignored by
+.Nm
+for compatibility with
+.Xr cpp 1
+and to simplify the implementation of
+.Nm unifdefall .
+.Pp
+.It Fl V
+Print version details.
+.El
+.Pp
+The
+.Nm
+utility copies its output to
+.Em stdout
+and will take its input from
+.Em stdin
+if no
+.Ar file
+argument is given.
+.Pp
+The
+.Nm
+utility works nicely with the
+.Fl D Ns Ar sym
+option of
+.Xr diff 1 .
+.Sh EXIT STATUS
+The
+.Nm
+utility exits 0 if the output is an exact copy of the input,
+1 if not, and 2 if in trouble.
+.Sh DIAGNOSTICS
+.Bl -item
+.It
+Too many levels of nesting.
+.It
+Inappropriate
+.Ic #elif ,
+.Ic #else
+or
+.Ic #endif .
+.It
+Obfuscated preprocessor control line.
+.It
+Premature
+.Tn EOF
+(with the line number of the most recent unterminated
+.Ic #if ) .
+.It
+.Tn EOF
+in comment.
+.El
+.Sh SEE ALSO
+.Xr cpp 1 ,
+.Xr diff 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 2.9 .
+.Tn ANSI\~C
+support was added in
+.Fx 4.7 .
+.Sh AUTHORS
+The original implementation was written by
+.An Dave Yost Aq Dave@Yost.com .
+.An Tony Finch Aq dot@dotat.at
+rewrote it to support
+.Tn ANSI\~C .
+.Sh BUGS
+Expression evaluation is very limited.
+.Pp
+Preprocessor control lines split across more than one physical line
+(because of comments or backslash-newline)
+cannot be handled in every situation.
+.Pp
+Trigraphs are not recognized.
+.Pp
+There is no support for symbols with different definitions at
+different points in the source file.
+.Pp
+The text-mode and ignore functionality does not correspond to modern
+.Xr cpp 1
+behaviour.
diff --git a/developer_cmds/unifdef/unifdef.c b/developer_cmds/unifdef/unifdef.c
new file mode 100644
index 0000000..8c54e6e
--- /dev/null
+++ b/developer_cmds/unifdef/unifdef.c
@@ -0,0 +1,1235 @@
+/*
+ * Copyright (c) 2002 - 2011 Tony Finch <dot@dotat.at>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * unifdef - remove ifdef'ed lines
+ *
+ * This code was derived from software contributed to Berkeley by Dave Yost.
+ * It was rewritten to support ANSI C by Tony Finch. The original version
+ * of unifdef carried the 4-clause BSD copyright licence. None of its code
+ * remains in this version (though some of the names remain) so it now
+ * carries a more liberal licence.
+ *
+ * Wishlist:
+ * provide an option which will append the name of the
+ * appropriate symbol after #else's and #endif's
+ * provide an option which will check symbols after
+ * #else's and #endif's to see that they match their
+ * corresponding #ifdef or #ifndef
+ *
+ * These require better buffer handling, which would also make
+ * it possible to handle all "dodgy" directives correctly.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+const char copyright[] =
+ "@(#) $Version: unifdef-2.5.6.21f1388 $\n"
+ "@(#) $FreeBSD: src/usr.bin/unifdef/unifdef.c,v 1.31 2011/01/21 18:10:11 fanf Exp $\n"
+ "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
+ "@(#) $URL: http://dotat.at/prog/unifdef $\n"
+;
+
+/* types of input lines: */
+typedef enum {
+ LT_TRUEI, /* a true #if with ignore flag */
+ LT_FALSEI, /* a false #if with ignore flag */
+ LT_IF, /* an unknown #if */
+ LT_TRUE, /* a true #if */
+ LT_FALSE, /* a false #if */
+ LT_ELIF, /* an unknown #elif */
+ LT_ELTRUE, /* a true #elif */
+ LT_ELFALSE, /* a false #elif */
+ LT_ELSE, /* #else */
+ LT_ENDIF, /* #endif */
+ LT_DODGY, /* flag: directive is not on one line */
+ LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
+ LT_PLAIN, /* ordinary line */
+ LT_EOF, /* end of file */
+ LT_ERROR, /* unevaluable #if */
+ LT_COUNT
+} Linetype;
+
+static char const * const linetype_name[] = {
+ "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
+ "ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
+ "DODGY TRUEI", "DODGY FALSEI",
+ "DODGY IF", "DODGY TRUE", "DODGY FALSE",
+ "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
+ "DODGY ELSE", "DODGY ENDIF",
+ "PLAIN", "EOF", "ERROR"
+};
+
+/* state of #if processing */
+typedef enum {
+ IS_OUTSIDE,
+ IS_FALSE_PREFIX, /* false #if followed by false #elifs */
+ IS_TRUE_PREFIX, /* first non-false #(el)if is true */
+ IS_PASS_MIDDLE, /* first non-false #(el)if is unknown */
+ IS_FALSE_MIDDLE, /* a false #elif after a pass state */
+ IS_TRUE_MIDDLE, /* a true #elif after a pass state */
+ IS_PASS_ELSE, /* an else after a pass state */
+ IS_FALSE_ELSE, /* an else after a true state */
+ IS_TRUE_ELSE, /* an else after only false states */
+ IS_FALSE_TRAILER, /* #elifs after a true are false */
+ IS_COUNT
+} Ifstate;
+
+static char const * const ifstate_name[] = {
+ "OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
+ "PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
+ "PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
+ "FALSE_TRAILER"
+};
+
+/* state of comment parser */
+typedef enum {
+ NO_COMMENT = false, /* outside a comment */
+ C_COMMENT, /* in a comment like this one */
+ CXX_COMMENT, /* between // and end of line */
+ STARTING_COMMENT, /* just after slash-backslash-newline */
+ FINISHING_COMMENT, /* star-backslash-newline in a C comment */
+ CHAR_LITERAL, /* inside '' */
+ STRING_LITERAL /* inside "" */
+} Comment_state;
+
+static char const * const comment_name[] = {
+ "NO", "C", "CXX", "STARTING", "FINISHING", "CHAR", "STRING"
+};
+
+/* state of preprocessor line parser */
+typedef enum {
+ LS_START, /* only space and comments on this line */
+ LS_HASH, /* only space, comments, and a hash */
+ LS_DIRTY /* this line can't be a preprocessor line */
+} Line_state;
+
+static char const * const linestate_name[] = {
+ "START", "HASH", "DIRTY"
+};
+
+/*
+ * Minimum translation limits from ISO/IEC 9899:1999 5.2.4.1
+ */
+#define MAXDEPTH 64 /* maximum #if nesting */
+#define MAXLINE 4096 /* maximum length of line */
+#define MAXSYMS 4096 /* maximum number of symbols */
+
+/*
+ * Sometimes when editing a keyword the replacement text is longer, so
+ * we leave some space at the end of the tline buffer to accommodate this.
+ */
+#define EDITSLOP 10
+
+/*
+ * For temporary filenames
+ */
+#define TEMPLATE "unifdef.XXXXXX"
+
+/*
+ * Globals.
+ */
+
+static bool compblank; /* -B: compress blank lines */
+static bool lnblank; /* -b: blank deleted lines */
+static bool complement; /* -c: do the complement */
+static bool debugging; /* -d: debugging reports */
+static bool iocccok; /* -e: fewer IOCCC errors */
+static bool strictlogic; /* -K: keep ambiguous #ifs */
+static bool killconsts; /* -k: eval constant #ifs */
+static bool lnnum; /* -n: add #line directives */
+static bool symlist; /* -s: output symbol list */
+static bool symdepth; /* -S: output symbol depth */
+static bool text; /* -t: this is a text file */
+
+static const char *symname[MAXSYMS]; /* symbol name */
+static const char *value[MAXSYMS]; /* -Dsym=value */
+static bool ignore[MAXSYMS]; /* -iDsym or -iUsym */
+static int nsyms; /* number of symbols */
+
+static FILE *input; /* input file pointer */
+static const char *filename; /* input file name */
+static int linenum; /* current line number */
+static FILE *output; /* output file pointer */
+static const char *ofilename; /* output file name */
+static bool overwriting; /* output overwrites input */
+static char tempname[FILENAME_MAX]; /* used when overwriting */
+
+static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
+static char *keyword; /* used for editing #elif's */
+
+static const char *newline; /* input file format */
+static const char newline_unix[] = "\n";
+static const char newline_crlf[] = "\r\n";
+
+static Comment_state incomment; /* comment parser state */
+static Line_state linestate; /* #if line parser state */
+static Ifstate ifstate[MAXDEPTH]; /* #if processor state */
+static bool ignoring[MAXDEPTH]; /* ignore comments state */
+static int stifline[MAXDEPTH]; /* start of current #if */
+static int depth; /* current #if nesting */
+static int delcount; /* count of deleted lines */
+static unsigned blankcount; /* count of blank lines */
+static unsigned blankmax; /* maximum recent blankcount */
+static bool constexpr; /* constant #if expression */
+static bool zerosyms = true; /* to format symdepth output */
+static bool firstsym; /* ditto */
+
+static int exitstat; /* program exit status */
+
+static void addsym(bool, bool, char *);
+static void closeout(void);
+static void debug(const char *, ...);
+static void done(void);
+static void error(const char *);
+static int findsym(const char *);
+static void flushline(bool);
+static Linetype parseline(void);
+static Linetype ifeval(const char **);
+static void ignoreoff(void);
+static void ignoreon(void);
+static void keywordedit(const char *);
+static void nest(void);
+static void process(void);
+static const char *skipargs(const char *);
+static const char *skipcomment(const char *);
+static const char *skipsym(const char *);
+static void state(Ifstate);
+static int strlcmp(const char *, const char *, size_t);
+static void unnest(void);
+static void usage(void);
+static void version(void);
+
+#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
+
+/*
+ * The main program.
+ */
+int
+main(int argc, char *argv[])
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
+ switch (opt) {
+ case 'i': /* treat stuff controlled by these symbols as text */
+ /*
+ * For strict backwards-compatibility the U or D
+ * should be immediately after the -i but it doesn't
+ * matter much if we relax that requirement.
+ */
+ opt = *optarg++;
+ if (opt == 'D')
+ addsym(true, true, optarg);
+ else if (opt == 'U')
+ addsym(true, false, optarg);
+ else
+ usage();
+ break;
+ case 'D': /* define a symbol */
+ addsym(false, true, optarg);
+ break;
+ case 'U': /* undef a symbol */
+ addsym(false, false, optarg);
+ break;
+ case 'I': /* no-op for compatibility with cpp */
+ break;
+ case 'b': /* blank deleted lines instead of omitting them */
+ case 'l': /* backwards compatibility */
+ lnblank = true;
+ break;
+ case 'B': /* compress blank lines around removed section */
+ compblank = true;
+ break;
+ case 'c': /* treat -D as -U and vice versa */
+ complement = true;
+ break;
+ case 'd':
+ debugging = true;
+ break;
+ case 'e': /* fewer errors from dodgy lines */
+ iocccok = true;
+ break;
+ case 'K': /* keep ambiguous #ifs */
+ strictlogic = true;
+ break;
+ case 'k': /* process constant #ifs */
+ killconsts = true;
+ break;
+ case 'n': /* add #line directive after deleted lines */
+ lnnum = true;
+ break;
+ case 'o': /* output to a file */
+ ofilename = optarg;
+ break;
+ case 's': /* only output list of symbols that control #ifs */
+ symlist = true;
+ break;
+ case 'S': /* list symbols with their nesting depth */
+ symlist = symdepth = true;
+ break;
+ case 't': /* don't parse C comments */
+ text = true;
+ break;
+ case 'V': /* print version */
+ version();
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (compblank && lnblank)
+ errx(2, "-B and -b are mutually exclusive");
+ if (argc > 1) {
+ errx(2, "can only do one file");
+ } else if (argc == 1 && strcmp(*argv, "-") != 0) {
+ filename = *argv;
+ input = fopen(filename, "rb");
+ if (input == NULL)
+ err(2, "can't open %s", filename);
+ } else {
+ filename = "[stdin]";
+ input = stdin;
+ }
+ if (ofilename == NULL) {
+ ofilename = "[stdout]";
+ output = stdout;
+ } else {
+ struct stat ist, ost;
+ if (stat(ofilename, &ost) == 0 &&
+ fstat(fileno(input), &ist) == 0)
+ overwriting = (ist.st_dev == ost.st_dev
+ && ist.st_ino == ost.st_ino);
+ if (overwriting) {
+ const char *dirsep;
+ int ofd;
+
+ dirsep = strrchr(ofilename, '/');
+ if (dirsep != NULL)
+ snprintf(tempname, sizeof(tempname),
+ "%.*s/" TEMPLATE,
+ (int)(dirsep - ofilename), ofilename);
+ else
+ snprintf(tempname, sizeof(tempname),
+ TEMPLATE);
+ ofd = mkstemp(tempname);
+ if (ofd != -1)
+ output = fdopen(ofd, "wb+");
+ if (output == NULL)
+ err(2, "can't create temporary file");
+ fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
+ } else {
+ output = fopen(ofilename, "wb");
+ if (output == NULL)
+ err(2, "can't open %s", ofilename);
+ }
+ }
+ process();
+ abort(); /* bug */
+}
+
+static void
+version(void)
+{
+ const char *c = copyright;
+ for (;;) {
+ while (*++c != '$')
+ if (*c == '\0')
+ exit(0);
+ while (*++c != '$')
+ putc(*c, stderr);
+ putc('\n', stderr);
+ }
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]"
+ " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
+ exit(2);
+}
+
+/*
+ * A state transition function alters the global #if processing state
+ * in a particular way. The table below is indexed by the current
+ * processing state and the type of the current line.
+ *
+ * Nesting is handled by keeping a stack of states; some transition
+ * functions increase or decrease the depth. They also maintain the
+ * ignore state on a stack. In some complicated cases they have to
+ * alter the preprocessor directive, as follows.
+ *
+ * When we have processed a group that starts off with a known-false
+ * #if/#elif sequence (which has therefore been deleted) followed by a
+ * #elif that we don't understand and therefore must keep, we edit the
+ * latter into a #if to keep the nesting correct. We use strncpy() to
+ * overwrite the 4 byte token "elif" with "if " without a '\0' byte.
+ *
+ * When we find a true #elif in a group, the following block will
+ * always be kept and the rest of the sequence after the next #elif or
+ * #else will be discarded. We edit the #elif into a #else and the
+ * following directive to #endif since this has the desired behaviour.
+ *
+ * "Dodgy" directives are split across multiple lines, the most common
+ * example being a multi-line comment hanging off the right of the
+ * directive. We can handle them correctly only if there is no change
+ * from printing to dropping (or vice versa) caused by that directive.
+ * If the directive is the first of a group we have a choice between
+ * failing with an error, or passing it through unchanged instead of
+ * evaluating it. The latter is not the default to avoid questions from
+ * users about unifdef unexpectedly leaving behind preprocessor directives.
+ */
+typedef void state_fn(void);
+
+/* report an error */
+static void Eelif (void) { error("Inappropriate #elif"); }
+static void Eelse (void) { error("Inappropriate #else"); }
+static void Eendif(void) { error("Inappropriate #endif"); }
+static void Eeof (void) { error("Premature EOF"); }
+static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
+/* plain line handling */
+static void print (void) { flushline(true); }
+static void drop (void) { flushline(false); }
+/* output lacks group's start line */
+static void Strue (void) { drop(); ignoreoff(); state(IS_TRUE_PREFIX); }
+static void Sfalse(void) { drop(); ignoreoff(); state(IS_FALSE_PREFIX); }
+static void Selse (void) { drop(); state(IS_TRUE_ELSE); }
+/* print/pass this block */
+static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
+static void Pelse (void) { print(); state(IS_PASS_ELSE); }
+static void Pendif(void) { print(); unnest(); }
+/* discard this block */
+static void Dfalse(void) { drop(); ignoreoff(); state(IS_FALSE_TRAILER); }
+static void Delif (void) { drop(); ignoreoff(); state(IS_FALSE_MIDDLE); }
+static void Delse (void) { drop(); state(IS_FALSE_ELSE); }
+static void Dendif(void) { drop(); unnest(); }
+/* first line of group */
+static void Fdrop (void) { nest(); Dfalse(); }
+static void Fpass (void) { nest(); Pelif(); }
+static void Ftrue (void) { nest(); Strue(); }
+static void Ffalse(void) { nest(); Sfalse(); }
+/* variable pedantry for obfuscated lines */
+static void Oiffy (void) { if (!iocccok) Eioccc(); Fpass(); ignoreon(); }
+static void Oif (void) { if (!iocccok) Eioccc(); Fpass(); }
+static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
+/* ignore comments in this block */
+static void Idrop (void) { Fdrop(); ignoreon(); }
+static void Itrue (void) { Ftrue(); ignoreon(); }
+static void Ifalse(void) { Ffalse(); ignoreon(); }
+/* modify this line */
+static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
+static void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); }
+static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
+static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
+
+static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
+/* IS_OUTSIDE */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif,
+ print, done, abort },
+/* IS_FALSE_PREFIX */
+{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
+ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
+ drop, Eeof, abort },
+/* IS_TRUE_PREFIX */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
+ print, Eeof, abort },
+/* IS_PASS_MIDDLE */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif,
+ print, Eeof, abort },
+/* IS_FALSE_MIDDLE */
+{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
+ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
+ drop, Eeof, abort },
+/* IS_TRUE_MIDDLE */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
+ print, Eeof, abort },
+/* IS_PASS_ELSE */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif,
+ print, Eeof, abort },
+/* IS_FALSE_ELSE */
+{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
+ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
+ drop, Eeof, abort },
+/* IS_TRUE_ELSE */
+{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
+ Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc,
+ print, Eeof, abort },
+/* IS_FALSE_TRAILER */
+{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
+ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
+ drop, Eeof, abort }
+/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF
+ TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY)
+ PLAIN EOF ERROR */
+};
+
+/*
+ * State machine utility functions
+ */
+static void
+ignoreoff(void)
+{
+ if (depth == 0)
+ abort(); /* bug */
+ ignoring[depth] = ignoring[depth-1];
+}
+static void
+ignoreon(void)
+{
+ ignoring[depth] = true;
+}
+static void
+keywordedit(const char *replacement)
+{
+ snprintf(keyword, tline + sizeof(tline) - keyword,
+ "%s%s", replacement, newline);
+ print();
+}
+static void
+nest(void)
+{
+ if (depth > MAXDEPTH-1)
+ abort(); /* bug */
+ if (depth == MAXDEPTH-1)
+ error("Too many levels of nesting");
+ depth += 1;
+ stifline[depth] = linenum;
+}
+static void
+unnest(void)
+{
+ if (depth == 0)
+ abort(); /* bug */
+ depth -= 1;
+}
+static void
+state(Ifstate is)
+{
+ ifstate[depth] = is;
+}
+
+/*
+ * Write a line to the output or not, according to command line options.
+ * If writing fails, closeout() will print the error and exit.
+ */
+static void
+flushline(bool keep)
+{
+ if (symlist)
+ return;
+ if (keep ^ complement) {
+ bool blankline = tline[strspn(tline, " \t\r\n")] == '\0';
+ if (blankline && compblank && blankcount != blankmax) {
+ delcount += 1;
+ blankcount += 1;
+ } else {
+ if (lnnum && delcount > 0 &&
+ fprintf(output, "#line %d%s", linenum, newline) < 0)
+ closeout();
+ if (fputs(tline, output) == EOF)
+ closeout();
+ delcount = 0;
+ blankmax = blankcount = blankline ? blankcount + 1 : 0;
+ }
+ } else {
+ if (lnblank && fputs(newline, output) == EOF)
+ closeout();
+ exitstat = 1;
+ delcount += 1;
+ blankcount = 0;
+ }
+ if (debugging && fflush(output) == EOF)
+ closeout();
+}
+
+/*
+ * The driver for the state machine.
+ */
+static void
+process(void)
+{
+ /* When compressing blank lines, act as if the file
+ is preceded by a large number of blank lines. */
+ blankmax = blankcount = 1000;
+ for (;;) {
+ Linetype lineval = parseline();
+ trans_table[ifstate[depth]][lineval]();
+ debug("process line %d %s -> %s depth %d",
+ linenum, linetype_name[lineval],
+ ifstate_name[ifstate[depth]], depth);
+ }
+}
+
+/*
+ * Flush the output and handle errors.
+ */
+static void
+closeout(void)
+{
+ if (symdepth && !zerosyms)
+ printf("\n");
+ if (ferror(output) || fclose(output) == EOF) {
+ if (overwriting) {
+ warn("couldn't write to temporary file");
+ unlink(tempname);
+ errx(2, "%s unchanged", ofilename);
+ } else {
+ err(2, "couldn't write to %s", ofilename);
+ }
+ }
+}
+
+/*
+ * Clean up and exit.
+ */
+static void
+done(void)
+{
+ if (incomment)
+ error("EOF in comment");
+ closeout();
+ if (overwriting && rename(tempname, ofilename) == -1) {
+ warn("couldn't rename temporary file");
+ unlink(tempname);
+ errx(2, "%s unchanged", ofilename);
+ }
+ exit(exitstat);
+}
+
+/*
+ * Parse a line and determine its type. We keep the preprocessor line
+ * parser state between calls in the global variable linestate, with
+ * help from skipcomment().
+ */
+static Linetype
+parseline(void)
+{
+ const char *cp;
+ int cursym;
+ int kwlen;
+ Linetype retval;
+ Comment_state wascomment;
+
+ linenum++;
+ if (fgets(tline, MAXLINE, input) == NULL) {
+ if (ferror(input))
+ error(strerror(errno));
+ else
+ return (LT_EOF);
+ }
+ if (newline == NULL) {
+ if (strrchr(tline, '\n') == strrchr(tline, '\r') + 1)
+ newline = newline_crlf;
+ else
+ newline = newline_unix;
+ }
+ retval = LT_PLAIN;
+ wascomment = incomment;
+ cp = skipcomment(tline);
+ if (linestate == LS_START) {
+ if (*cp == '#') {
+ linestate = LS_HASH;
+ firstsym = true;
+ cp = skipcomment(cp + 1);
+ } else if (*cp != '\0')
+ linestate = LS_DIRTY;
+ }
+ if (!incomment && linestate == LS_HASH) {
+ keyword = tline + (cp - tline);
+ cp = skipsym(cp);
+ kwlen = cp - keyword;
+ /* no way can we deal with a continuation inside a keyword */
+ if (strncmp(cp, "\\\r\n", 3) == 0 ||
+ strncmp(cp, "\\\n", 2) == 0)
+ Eioccc();
+ if (strlcmp("ifdef", keyword, kwlen) == 0 ||
+ strlcmp("ifndef", keyword, kwlen) == 0) {
+ cp = skipcomment(cp);
+ if ((cursym = findsym(cp)) < 0)
+ retval = LT_IF;
+ else {
+ retval = (keyword[2] == 'n')
+ ? LT_FALSE : LT_TRUE;
+ if (value[cursym] == NULL)
+ retval = (retval == LT_TRUE)
+ ? LT_FALSE : LT_TRUE;
+ if (ignore[cursym])
+ retval = (retval == LT_TRUE)
+ ? LT_TRUEI : LT_FALSEI;
+ }
+ cp = skipsym(cp);
+ } else if (strlcmp("if", keyword, kwlen) == 0)
+ retval = ifeval(&cp);
+ else if (strlcmp("elif", keyword, kwlen) == 0)
+ retval = ifeval(&cp) - LT_IF + LT_ELIF;
+ else if (strlcmp("else", keyword, kwlen) == 0)
+ retval = LT_ELSE;
+ else if (strlcmp("endif", keyword, kwlen) == 0)
+ retval = LT_ENDIF;
+ else {
+ linestate = LS_DIRTY;
+ retval = LT_PLAIN;
+ }
+ cp = skipcomment(cp);
+ if (*cp != '\0') {
+ linestate = LS_DIRTY;
+ if (retval == LT_TRUE || retval == LT_FALSE ||
+ retval == LT_TRUEI || retval == LT_FALSEI)
+ retval = LT_IF;
+ if (retval == LT_ELTRUE || retval == LT_ELFALSE)
+ retval = LT_ELIF;
+ }
+ if (retval != LT_PLAIN && (wascomment || incomment)) {
+ retval += LT_DODGY;
+ if (incomment)
+ linestate = LS_DIRTY;
+ }
+ /* skipcomment normally changes the state, except
+ if the last line of the file lacks a newline, or
+ if there is too much whitespace in a directive */
+ if (linestate == LS_HASH) {
+ size_t len = cp - tline;
+ if (fgets(tline + len, MAXLINE - len, input) == NULL) {
+ if (ferror(input))
+ error(strerror(errno));
+ /* append the missing newline at eof */
+ strcpy(tline + len, newline);
+ cp += strlen(newline);
+ linestate = LS_START;
+ } else {
+ linestate = LS_DIRTY;
+ }
+ }
+ }
+ if (linestate == LS_DIRTY) {
+ while (*cp != '\0')
+ cp = skipcomment(cp + 1);
+ }
+ debug("parser line %d state %s comment %s line", linenum,
+ comment_name[incomment], linestate_name[linestate]);
+ return (retval);
+}
+
+/*
+ * These are the binary operators that are supported by the expression
+ * evaluator.
+ */
+static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) {
+ if(at == LT_IF || bt == LT_IF) return (LT_IF);
+ return (*p = v, v ? LT_TRUE : LT_FALSE);
+}
+static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a < b, at, bt);
+}
+static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a > b, at, bt);
+}
+static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a <= b, at, bt);
+}
+static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a >= b, at, bt);
+}
+static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a == b, at, bt);
+}
+static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) {
+ return op_strict(p, a != b, at, bt);
+}
+static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) {
+ if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE))
+ return (*p = 1, LT_TRUE);
+ return op_strict(p, a || b, at, bt);
+}
+static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) {
+ if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE))
+ return (*p = 0, LT_FALSE);
+ return op_strict(p, a && b, at, bt);
+}
+
+/*
+ * An evaluation function takes three arguments, as follows: (1) a pointer to
+ * an element of the precedence table which lists the operators at the current
+ * level of precedence; (2) a pointer to an integer which will receive the
+ * value of the expression; and (3) a pointer to a char* that points to the
+ * expression to be evaluated and that is updated to the end of the expression
+ * when evaluation is complete. The function returns LT_FALSE if the value of
+ * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression
+ * depends on an unknown symbol, or LT_ERROR if there is a parse failure.
+ */
+struct ops;
+
+typedef Linetype eval_fn(const struct ops *, int *, const char **);
+
+static eval_fn eval_table, eval_unary;
+
+/*
+ * The precedence table. Expressions involving binary operators are evaluated
+ * in a table-driven way by eval_table. When it evaluates a subexpression it
+ * calls the inner function with its first argument pointing to the next
+ * element of the table. Innermost expressions have special non-table-driven
+ * handling.
+ */
+static const struct ops {
+ eval_fn *inner;
+ struct op {
+ const char *str;
+ Linetype (*fn)(int *, Linetype, int, Linetype, int);
+ } op[5];
+} eval_ops[] = {
+ { eval_table, { { "||", op_or } } },
+ { eval_table, { { "&&", op_and } } },
+ { eval_table, { { "==", op_eq },
+ { "!=", op_ne } } },
+ { eval_unary, { { "<=", op_le },
+ { ">=", op_ge },
+ { "<", op_lt },
+ { ">", op_gt } } }
+};
+
+/*
+ * Function for evaluating the innermost parts of expressions,
+ * viz. !expr (expr) number defined(symbol) symbol
+ * We reset the constexpr flag in the last two cases.
+ */
+static Linetype
+eval_unary(const struct ops *ops, int *valp, const char **cpp)
+{
+ const char *cp;
+ char *ep;
+ int sym;
+ bool defparen;
+ Linetype lt;
+
+ cp = skipcomment(*cpp);
+ if (*cp == '!') {
+ debug("eval%d !", ops - eval_ops);
+ cp++;
+ lt = eval_unary(ops, valp, &cp);
+ if (lt == LT_ERROR)
+ return (LT_ERROR);
+ if (lt != LT_IF) {
+ *valp = !*valp;
+ lt = *valp ? LT_TRUE : LT_FALSE;
+ }
+ } else if (*cp == '(') {
+ cp++;
+ debug("eval%d (", ops - eval_ops);
+ lt = eval_table(eval_ops, valp, &cp);
+ if (lt == LT_ERROR)
+ return (LT_ERROR);
+ cp = skipcomment(cp);
+ if (*cp++ != ')')
+ return (LT_ERROR);
+ } else if (isdigit((unsigned char)*cp)) {
+ debug("eval%d number", ops - eval_ops);
+ *valp = strtol(cp, &ep, 0);
+ if (ep == cp)
+ return (LT_ERROR);
+ lt = *valp ? LT_TRUE : LT_FALSE;
+ cp = skipsym(cp);
+ } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {
+ cp = skipcomment(cp+7);
+ debug("eval%d defined", ops - eval_ops);
+ if (*cp == '(') {
+ cp = skipcomment(cp+1);
+ defparen = true;
+ } else {
+ defparen = false;
+ }
+ sym = findsym(cp);
+ if (sym < 0) {
+ lt = LT_IF;
+ } else {
+ *valp = (value[sym] != NULL);
+ lt = *valp ? LT_TRUE : LT_FALSE;
+ }
+ cp = skipsym(cp);
+ cp = skipcomment(cp);
+ if (defparen && *cp++ != ')')
+ return (LT_ERROR);
+ constexpr = false;
+ } else if (!endsym(*cp)) {
+ debug("eval%d symbol", ops - eval_ops);
+ sym = findsym(cp);
+ cp = skipsym(cp);
+ if (sym < 0) {
+ lt = LT_IF;
+ cp = skipargs(cp);
+ } else if (value[sym] == NULL) {
+ *valp = 0;
+ lt = LT_FALSE;
+ } else {
+ *valp = strtol(value[sym], &ep, 0);
+ if (*ep != '\0' || ep == value[sym])
+ return (LT_ERROR);
+ lt = *valp ? LT_TRUE : LT_FALSE;
+ cp = skipargs(cp);
+ }
+ constexpr = false;
+ } else {
+ debug("eval%d bad expr", ops - eval_ops);
+ return (LT_ERROR);
+ }
+
+ *cpp = cp;
+ debug("eval%d = %d", ops - eval_ops, *valp);
+ return (lt);
+}
+
+/*
+ * Table-driven evaluation of binary operators.
+ */
+static Linetype
+eval_table(const struct ops *ops, int *valp, const char **cpp)
+{
+ const struct op *op;
+ const char *cp;
+ int val;
+ Linetype lt, rt;
+
+ debug("eval%d", ops - eval_ops);
+ cp = *cpp;
+ lt = ops->inner(ops+1, valp, &cp);
+ if (lt == LT_ERROR)
+ return (LT_ERROR);
+ for (;;) {
+ cp = skipcomment(cp);
+ for (op = ops->op; op->str != NULL; op++)
+ if (strncmp(cp, op->str, strlen(op->str)) == 0)
+ break;
+ if (op->str == NULL)
+ break;
+ cp += strlen(op->str);
+ debug("eval%d %s", ops - eval_ops, op->str);
+ rt = ops->inner(ops+1, &val, &cp);
+ if (rt == LT_ERROR)
+ return (LT_ERROR);
+ lt = op->fn(valp, lt, *valp, rt, val);
+ }
+
+ *cpp = cp;
+ debug("eval%d = %d", ops - eval_ops, *valp);
+ debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]);
+ return (lt);
+}
+
+/*
+ * Evaluate the expression on a #if or #elif line. If we can work out
+ * the result we return LT_TRUE or LT_FALSE accordingly, otherwise we
+ * return just a generic LT_IF.
+ */
+static Linetype
+ifeval(const char **cpp)
+{
+ int ret;
+ int val = 0;
+
+ debug("eval %s", *cpp);
+ constexpr = killconsts ? false : true;
+ ret = eval_table(eval_ops, &val, cpp);
+ debug("eval = %d", val);
+ return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
+}
+
+/*
+ * Skip over comments, strings, and character literals and stop at the
+ * next character position that is not whitespace. Between calls we keep
+ * the comment state in the global variable incomment, and we also adjust
+ * the global variable linestate when we see a newline.
+ * XXX: doesn't cope with the buffer splitting inside a state transition.
+ */
+static const char *
+skipcomment(const char *cp)
+{
+ if (text || ignoring[depth]) {
+ for (; isspace((unsigned char)*cp); cp++)
+ if (*cp == '\n')
+ linestate = LS_START;
+ return (cp);
+ }
+ while (*cp != '\0')
+ /* don't reset to LS_START after a line continuation */
+ if (strncmp(cp, "\\\r\n", 3) == 0)
+ cp += 3;
+ else if (strncmp(cp, "\\\n", 2) == 0)
+ cp += 2;
+ else switch (incomment) {
+ case NO_COMMENT:
+ if (strncmp(cp, "/\\\r\n", 4) == 0) {
+ incomment = STARTING_COMMENT;
+ cp += 4;
+ } else if (strncmp(cp, "/\\\n", 3) == 0) {
+ incomment = STARTING_COMMENT;
+ cp += 3;
+ } else if (strncmp(cp, "/*", 2) == 0) {
+ incomment = C_COMMENT;
+ cp += 2;
+ } else if (strncmp(cp, "//", 2) == 0) {
+ incomment = CXX_COMMENT;
+ cp += 2;
+ } else if (strncmp(cp, "\'", 1) == 0) {
+ incomment = CHAR_LITERAL;
+ linestate = LS_DIRTY;
+ cp += 1;
+ } else if (strncmp(cp, "\"", 1) == 0) {
+ incomment = STRING_LITERAL;
+ linestate = LS_DIRTY;
+ cp += 1;
+ } else if (strncmp(cp, "\n", 1) == 0) {
+ linestate = LS_START;
+ cp += 1;
+ } else if (strchr(" \r\t", *cp) != NULL) {
+ cp += 1;
+ } else
+ return (cp);
+ continue;
+ case CXX_COMMENT:
+ if (strncmp(cp, "\n", 1) == 0) {
+ incomment = NO_COMMENT;
+ linestate = LS_START;
+ }
+ cp += 1;
+ continue;
+ case CHAR_LITERAL:
+ case STRING_LITERAL:
+ if ((incomment == CHAR_LITERAL && cp[0] == '\'') ||
+ (incomment == STRING_LITERAL && cp[0] == '\"')) {
+ incomment = NO_COMMENT;
+ cp += 1;
+ } else if (cp[0] == '\\') {
+ if (cp[1] == '\0')
+ cp += 1;
+ else
+ cp += 2;
+ } else if (strncmp(cp, "\n", 1) == 0) {
+ if (incomment == CHAR_LITERAL)
+ error("unterminated char literal");
+ else
+ error("unterminated string literal");
+ } else
+ cp += 1;
+ continue;
+ case C_COMMENT:
+ if (strncmp(cp, "*\\\r\n", 4) == 0) {
+ incomment = FINISHING_COMMENT;
+ cp += 4;
+ } else if (strncmp(cp, "*\\\n", 3) == 0) {
+ incomment = FINISHING_COMMENT;
+ cp += 3;
+ } else if (strncmp(cp, "*/", 2) == 0) {
+ incomment = NO_COMMENT;
+ cp += 2;
+ } else
+ cp += 1;
+ continue;
+ case STARTING_COMMENT:
+ if (*cp == '*') {
+ incomment = C_COMMENT;
+ cp += 1;
+ } else if (*cp == '/') {
+ incomment = CXX_COMMENT;
+ cp += 1;
+ } else {
+ incomment = NO_COMMENT;
+ linestate = LS_DIRTY;
+ }
+ continue;
+ case FINISHING_COMMENT:
+ if (*cp == '/') {
+ incomment = NO_COMMENT;
+ cp += 1;
+ } else
+ incomment = C_COMMENT;
+ continue;
+ default:
+ abort(); /* bug */
+ }
+ return (cp);
+}
+
+/*
+ * Skip macro arguments.
+ */
+static const char *
+skipargs(const char *cp)
+{
+ const char *ocp = cp;
+ int level = 0;
+ cp = skipcomment(cp);
+ if (*cp != '(')
+ return (cp);
+ do {
+ if (*cp == '(')
+ level++;
+ if (*cp == ')')
+ level--;
+ cp = skipcomment(cp+1);
+ } while (level != 0 && *cp != '\0');
+ if (level == 0)
+ return (cp);
+ else
+ /* Rewind and re-detect the syntax error later. */
+ return (ocp);
+}
+
+/*
+ * Skip over an identifier.
+ */
+static const char *
+skipsym(const char *cp)
+{
+ while (!endsym(*cp))
+ ++cp;
+ return (cp);
+}
+
+/*
+ * Look for the symbol in the symbol table. If it is found, we return
+ * the symbol table index, else we return -1.
+ */
+static int
+findsym(const char *str)
+{
+ const char *cp;
+ int symind;
+
+ cp = skipsym(str);
+ if (cp == str)
+ return (-1);
+ if (symlist) {
+ if (symdepth && firstsym)
+ printf("%s%3d", zerosyms ? "" : "\n", depth);
+ firstsym = zerosyms = false;
+ printf("%s%.*s%s",
+ symdepth ? " " : "",
+ (int)(cp-str), str,
+ symdepth ? "" : "\n");
+ /* we don't care about the value of the symbol */
+ return (0);
+ }
+ for (symind = 0; symind < nsyms; ++symind) {
+ if (strlcmp(symname[symind], str, cp-str) == 0) {
+ debug("findsym %s %s", symname[symind],
+ value[symind] ? value[symind] : "");
+ return (symind);
+ }
+ }
+ return (-1);
+}
+
+/*
+ * Add a symbol to the symbol table.
+ */
+static void
+addsym(bool ignorethis, bool definethis, char *sym)
+{
+ int symind;
+ char *val;
+
+ symind = findsym(sym);
+ if (symind < 0) {
+ if (nsyms >= MAXSYMS)
+ errx(2, "too many symbols");
+ symind = nsyms++;
+ }
+ symname[symind] = sym;
+ ignore[symind] = ignorethis;
+ val = sym + (skipsym(sym) - sym);
+ if (definethis) {
+ if (*val == '=') {
+ value[symind] = val+1;
+ *val = '\0';
+ } else if (*val == '\0')
+ value[symind] = "1";
+ else
+ usage();
+ } else {
+ if (*val != '\0')
+ usage();
+ value[symind] = NULL;
+ }
+ debug("addsym %s=%s", symname[symind],
+ value[symind] ? value[symind] : "undef");
+}
+
+/*
+ * Compare s with n characters of t.
+ * The same as strncmp() except that it checks that s[n] == '\0'.
+ */
+static int
+strlcmp(const char *s, const char *t, size_t n)
+{
+ while (n-- && *t != '\0')
+ if (*s != *t)
+ return ((unsigned char)*s - (unsigned char)*t);
+ else
+ ++s, ++t;
+ return ((unsigned char)*s);
+}
+
+/*
+ * Diagnostics.
+ */
+static void
+debug(const char *msg, ...)
+{
+ va_list ap;
+
+ if (debugging) {
+ va_start(ap, msg);
+ vwarnx(msg, ap);
+ va_end(ap);
+ }
+}
+
+static void
+error(const char *msg)
+{
+ if (depth == 0)
+ warnx("%s: %d: %s", filename, linenum, msg);
+ else
+ warnx("%s: %d: %s (#if line %d depth %d)",
+ filename, linenum, msg, stifline[depth], depth);
+ closeout();
+ errx(2, "output may be truncated");
+}
diff --git a/developer_cmds/unifdef/unifdefall.sh b/developer_cmds/unifdef/unifdefall.sh
new file mode 100644
index 0000000..6d6165a
--- /dev/null
+++ b/developer_cmds/unifdef/unifdefall.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# unifdefall: remove all the #if's from a source file
+#
+# Copyright (c) 2002 - 2010 Tony Finch <dot@dotat.at>
+# Copyright (c) 2009 - 2010 Jonathan Nieder <jrnieder@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD: src/usr.bin/unifdef/unifdefall.sh,v 1.7 2010/03/12 17:55:29 fanf Exp $
+
+set -e
+
+unifdef="$(dirname "$0")/unifdef"
+if [ ! -e "$unifdef" ]
+then
+ unifdef=unifdef
+fi
+
+case "$@" in
+"-d "*) echo DEBUGGING 1>&2
+ debug=-d
+ shift
+esac
+
+basename=$(basename "$0")
+tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2
+trap 'rm -r "$tmp" || exit 2' EXIT
+
+export LC_ALL=C
+
+# list of all controlling macros
+"$unifdef" $debug -s "$@" | sort | uniq >"$tmp/ctrl"
+# list of all macro definitions
+cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs"
+# list of defined macro names
+sed 's/[^A-Za-z0-9_].*$//' <"$tmp/hashdefs" >"$tmp/alldef"
+# list of undefined and defined controlling macros
+comm -23 "$tmp/ctrl" "$tmp/alldef" >"$tmp/undef"
+comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tmp/def"
+# create a sed script that extracts the controlling macro definitions
+# and converts them to unifdef command-line arguments
+sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
+# create the final unifdef command
+{ echo "$unifdef" $debug -k '\'
+ # convert the controlling undefined macros to -U arguments
+ sed 's/.*/-U& \\/' <"$tmp/undef"
+ # convert the controlling defined macros to quoted -D arguments
+ sed -nf "$tmp/script" <"$tmp/hashdefs" |
+ sed "s/'/'\\\\''/g;s/.*/'&' \\\\/"
+ echo '"$@"'
+} >"$tmp/cmd"
+case $debug in
+-d) for i in ctrl hashdefs alldef undef def script cmd
+ do echo ==== $i
+ cat "$tmp/$i"
+ done 1>&2
+esac
+# run the command we just created
+sh "$tmp/cmd" "$@"
diff --git a/developer_cmds/xcodescripts/install-lorder.sh b/developer_cmds/xcodescripts/install-lorder.sh
new file mode 100644
index 0000000..8da52b7
--- /dev/null
+++ b/developer_cmds/xcodescripts/install-lorder.sh
@@ -0,0 +1,7 @@
+set -ex
+
+BINDIR="$DSTROOT"/"$DT_TOOLCHAIN_DIR"/usr/bin
+
+install -c -o root -g wheel -m 0755 \
+ "$PROJECT_DIR"/lorder/lorder.sh \
+ "$BINDIR"/lorder
diff --git a/developer_cmds/xcodescripts/install-unifdefall.sh b/developer_cmds/xcodescripts/install-unifdefall.sh
new file mode 100644
index 0000000..7424b3f
--- /dev/null
+++ b/developer_cmds/xcodescripts/install-unifdefall.sh
@@ -0,0 +1,9 @@
+set -e -x
+
+BINDIR="$DSTROOT"/"$DT_TOOLCHAIN_DIR"/usr/bin
+MANDIR="$DSTROOT"/"$DT_TOOLCHAIN_DIR"/usr/share/man/man1
+
+ln -f "$MANDIR"/unifdef.1 "$MANDIR"/unifdefall.1
+install -c -o root -g wheel -m 0755 \
+ "$PROJECT_DIR"/unifdef/unifdefall.sh \
+ "$BINDIR"/unifdefall