summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-02-11 22:08:51 +0000
committerobrien <obrien@FreeBSD.org>2002-02-11 22:08:51 +0000
commit3d70c20920e063b817578b2fb8a1dbaa87b1365e (patch)
treeb160e9aa983dee39129bc7887a4acbc00616458b /usr.sbin
parent37369620df3d22440dcb4976ad061fe320a01bcb (diff)
downloadFreeBSD-src-3d70c20920e063b817578b2fb8a1dbaa87b1365e.zip
FreeBSD-src-3d70c20920e063b817578b2fb8a1dbaa87b1365e.tar.gz
Replace makeobjops.pl in kernel building.
Submitted by: Diane Bruce <db@db.net>
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/makeobjops/Makefile6
-rw-r--r--usr.sbin/makeobjops/makeobjops.c988
2 files changed, 994 insertions, 0 deletions
diff --git a/usr.sbin/makeobjops/Makefile b/usr.sbin/makeobjops/Makefile
new file mode 100644
index 0000000..6de13ef
--- /dev/null
+++ b/usr.sbin/makeobjops/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+PROG= makeobjops
+NOMAN= true
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/makeobjops/makeobjops.c b/usr.sbin/makeobjops/makeobjops.c
new file mode 100644
index 0000000..1277c04
--- /dev/null
+++ b/usr.sbin/makeobjops/makeobjops.c
@@ -0,0 +1,988 @@
+/*
+ * Copyright (c) 1992, 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.
+ *
+ * From @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
+ * From @(#)makedevops.sh 1.1 1998/06/14 13:53:12 dfr Exp $
+ * From @(#)makedevops.sh ?.? 1998/10/05
+ * From src/sys/kern/makedevops.pl,v 1.12 1999/11/22 14:40:04 n_hibma Exp
+ * From FreeBSD: src/sys/kern/makeobjops.pl,v 1.2.2.1 2001/02/02 19:49:13 cg Exp
+ * $Id: makeobjops.c,v 1.3 2001/10/10 21:22:41 db Exp $
+ */
+
+/*
+ *
+ * Script to produce kobj front-end sugar.
+ *
+ */
+/*
+ * My personal preference would have been to use yacc/lex etc.
+ * However, this is part of the core when we don't even have yacc/lex yet..
+ * So, a simple recursive descent it is..
+ * -db
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void process_files(int argc, char *argv[], char *progname);
+static void print_headers(char *src, FILE *src_fp, FILE *hfile_fp,
+ char *prog_name);
+static void process_body(char *src, FILE *src_fp, FILE *cfile_fp,
+ FILE *hfile_fp, int line_count);
+static char *upper_case(char *name);
+static char *add_ext(char *prefix, char *suffix);
+static void usage(char *progname);
+static char *strip_ext(char *s, char *ext);
+static void emit_code_section(char *src, FILE *src_fp, FILE *cfile_fp);
+static void emit_c_body(char *src, FILE *src_fp, FILE *cfile_fp, char *mname,
+ char *dname);
+static void emit_h_body(char *src, FILE *hfile_fp, char *mtype,
+ char *mname, int max_list);
+static int parse_method(char *src,
+ FILE *src_fp, FILE *cfile_fp, FILE *hfile_fp,
+ char *input_buffer, int line_count);
+static void make_copy(char *fin, char *fout);
+static char* skip_spaces(char *s);
+static char* first_token(char *s);
+static char* next_token(char *s);
+static char* trim_name(char *name);
+static char* make_strdup(char *s);
+static char* make_malloc(int size);
+
+#define MAXLIST 32
+
+struct type_name {
+ int deref;
+ char *mtype;
+ char *mname;
+};
+
+struct type_name type_name_list[MAXLIST];
+
+int debug = 0;
+int cfile = 0; /* by default do not produce any file type */
+int hfile = 0;
+
+int keepcurrentdir = 1;
+int line_width = 80;
+
+#define MAXLINE 128
+
+/* Process the command line */
+main(int argc,char *argv[])
+{
+ char *progname;
+ int ch;
+
+ progname = argv[0];
+
+ /* Process the command line */
+
+ opterr = 0;
+
+ while ((ch = getopt(argc, argv, "chdpl:")) != -1) {
+ switch(ch) {
+
+ case 'c':
+ if(debug)
+ fprintf(stderr, "Producing .c output files\n");
+ cfile = 1;
+ break;
+
+ case 'h':
+ if(debug)
+ fprintf(stderr, "Producing .h output files\n");
+ hfile = 1;
+ break;
+
+ case 'd':
+ debug = 1;
+ break;
+
+ case 'p':
+ if(debug)
+ fprintf(stderr,
+ "Will produce files in original not in current directory\n");
+ keepcurrentdir = 0;
+ break;
+
+ case 'l':
+ line_width = atoi(optarg);
+ break;
+
+ case '?':
+ default:
+ usage(progname);
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+
+ if (!cfile && !hfile) {
+ usage(progname);
+ }
+
+ process_files(argc, argv, progname);
+}
+
+/*
+ * usage
+ *
+ * inputs - program name
+ * output - none
+ * side effects - prints usage summary then exits.
+ */
+static void
+usage(char *progname)
+{
+/* Validate the command line parameters */
+
+ fprintf(stderr,
+ "usage: %s [-d] [-p] [-l <nr>] [-c|-h] srcfile\n", progname);
+ fprintf(stderr,
+ "where -c produce only .c files\n");
+ fprintf(stderr,
+ " -h produce only .h files\n");
+ fprintf(stderr,
+ " -p use the path component in the source file for destination dir\n");
+ fprintf(stderr,
+ " -l set line width for output files [80]\n");
+ fprintf(stderr,
+ " -d switch on debugging\n");
+ exit(0);
+}
+
+/*
+ * find_tmp
+ *
+ * inputs - none
+ * output - pointer to valid tmp dir
+ * side effects - exits if none found
+ */
+static char *
+find_tmp(void)
+{
+ static char *tmpdir;
+ struct stat dstat;
+
+ if ((tmpdir = getenv("TMPDIR")) != NULL)
+ return (tmpdir);
+
+ if ((tmpdir = getenv("TMP")) != NULL)
+ return (tmpdir);
+
+ if ((tmpdir = getenv("TEMP")) != NULL)
+ return (tmpdir);
+
+ tmpdir = "/tmp";
+ if (stat (tmpdir, &dstat) >= 0)
+ return (tmpdir);
+
+ tmpdir = P_tmpdir;
+ if (stat (tmpdir, &dstat) >= 0)
+ return (tmpdir);
+
+ tmpdir = ".";
+ return (tmpdir);
+}
+
+/*
+ * mk_tmp
+ *
+ * inputs - pointer to tmp dir to use
+ * - pointer to basename
+ * - pointer to temp ext to use
+ * output - pointer to tmp file, tmp file name is formed
+ * - from dirname/basename.ext{pid}
+ * side effects - caller is responsible for freeing memory
+ */
+static char *
+mk_tmp(char *tmpdir, char *name, char *ext)
+{
+ char *tmpstr;
+
+ asprintf (&tmpstr, "%s/%s.%s%d", tmpdir, name, ext, getuid());
+ return (tmpstr);
+}
+
+/*
+ * process_files
+ *
+ * inputs - file count
+ * - pointer to (assumed) list of filenames
+ * - given program name
+ * output - none
+ * side effects - given files are processed
+ */
+static void process_files(int argc, char *argv[], char *progname)
+{
+ char *tmpdir;
+ char *ctmpname;
+ char *htmpname;
+ char *cname;
+ char *hname;
+ char *src; /* actual src file name */
+ char *src_base; /* file name minus any extension */
+ char *src_path;
+ FILE *cfile_fp, *hfile_fp, *src_fp;
+ int i, line_count;
+
+ line_count = 0;
+
+ if ((tmpdir = find_tmp()) == NULL)
+ err(0, "Cannot find a tmp dir");
+
+ for (i = 0; i < argc; i++) {
+
+ if ((src_base = basename(argv[i])) == NULL)
+ err(0, "can't find basename(%s)", argv[i]);
+
+ src_base = strip_ext(src_base, ".m");
+
+ if ((src_path = dirname(argv[i])) == NULL)
+ err(0, "can't find dirname(%s)", argv[i]);
+
+ ctmpname = mk_tmp(tmpdir, src_base, "ctmp");
+ htmpname = mk_tmp(tmpdir, src_base, "htmp");
+
+ /* The makefile wasn't clear... bah
+ * accept both file name with .m or without
+ */
+
+ if (strstr(argv[i], ".m"))
+ src = make_strdup(argv[i]);
+ else
+ src = add_ext(argv[i], "m");
+
+ cname = add_ext(src_base, "c");
+ hname = add_ext(src_base, "h");
+
+ if (cfile) {
+ if ((cfile_fp = fopen(ctmpname, "w")) == NULL)
+ err(0, "Could not open %s", cname);
+ }
+
+ if (hfile) {
+ if ((hfile_fp = fopen(htmpname, "w")) == NULL)
+ err(0, "Could not open %s", cname);
+ }
+
+ if ((src_fp = fopen(src, "r")) == NULL)
+ err(0, "Could not open %s", src);
+
+ print_headers(src, cfile_fp, hfile_fp, progname);
+
+ if (hfile) {
+ fprintf(hfile_fp, "#ifndef _%s_h_\n", src_base);
+ fprintf(hfile_fp, "#define _%s_h_\n\n", src_base);
+ }
+
+ process_body(src, src_fp, cfile_fp, hfile_fp, line_count);
+
+ if (hfile) {
+ fprintf(hfile_fp, "\n#endif /* _%s_h_ */\n", src_base);
+ }
+
+ if (cfile)
+ fclose(cfile_fp);
+ if (hfile)
+ fclose(hfile_fp);
+ fclose(src_fp);
+
+ /* copy files generated into position */
+
+/* XXX */
+ if (!keepcurrentdir)
+ if (chdir(src_path) < 0)
+ err(0, "can't chdir to %s", src_path);
+ if (cfile) {
+ make_copy(ctmpname, cname);
+ (void)unlink(ctmpname);
+ }
+
+ if (hfile) {
+ make_copy(htmpname, hname);
+ (void)unlink(htmpname);
+ }
+
+ free(ctmpname);
+ free(htmpname);
+ free(cname);
+ free(hname);
+ free(src);
+
+ }
+}
+
+/*
+ * add_ext
+ *
+ * inputs - pointer to prefix
+ * - pointer to suffix
+ * output - pointer to name as prefix.suffix
+ * side effects - caller is responsible for freeing memory
+ */
+static char *
+add_ext(char *prefix, char *suffix)
+{
+ char *tmpstr;
+
+ asprintf (&tmpstr, "%s.%s", prefix, suffix);
+ return (tmpstr);
+}
+
+/*
+ * make_strdup
+ *
+ * inputs - pointer to string to duplicate
+ * output - pointer duplicated string
+ * side effects - exits if unable to malloc
+ */
+static char*
+make_strdup(char *s)
+{
+ char *r;
+
+ if ((r = strdup(s)) == NULL)
+ err(0, "Out of memory");
+ return (r);
+}
+
+/*
+ * print_headers
+ *
+ * inputs - FILE pointer to cfile
+ * - FILE pointer to hfile
+ * - FILE pointer to source file
+ * - given program name
+ * output - none
+ * side effects - headers are printed to given temp files
+ */
+static void
+print_headers(char *src, FILE *cfile_fp, FILE *hfile_fp, char *prog_name)
+{
+ if (cfile) {
+ /* Produce the header of the C file */
+
+ fprintf(cfile_fp, "/*\n");
+ fprintf(cfile_fp, " * This file is produced automatically.\n");
+ fprintf(cfile_fp, " * Do not modify anything in here by hand.\n");
+ fprintf(cfile_fp, " *\n");
+ fprintf(cfile_fp, " * Created from source file\n");
+ fprintf(cfile_fp, " * %s\n",src);
+ fprintf(cfile_fp, " * with\n");
+ fprintf(cfile_fp, " * %s\n",prog_name);
+ fprintf(cfile_fp, " *\n");
+ fprintf(cfile_fp, " * See the source file for legal information\n");
+ fprintf(cfile_fp, " */\n\n");
+ fprintf(cfile_fp, "#include <sys/param.h>\n");
+ fprintf(cfile_fp, "#include <sys/kernel.h>\n");
+ fprintf(cfile_fp, "#include <sys/kobj.h>\n");
+ fprintf(cfile_fp, "#include <sys/queue.h>\n");
+ }
+
+ if (hfile) {
+ /* Produce the header of the H file */
+
+ fprintf(hfile_fp, "/*\n");
+ fprintf(hfile_fp, " * This file is produced automatically.\n");
+ fprintf(hfile_fp, " * Do not modify anything in here by hand.\n");
+ fprintf(hfile_fp, " *\n");
+ fprintf(hfile_fp, " * Created from source file\n");
+ fprintf(hfile_fp, " * %s\n",src);
+ fprintf(hfile_fp, " * with\n");
+ fprintf(hfile_fp, " * %s\n",prog_name);
+ fprintf(hfile_fp, " *\n");
+ fprintf(hfile_fp, " * See the source file for legal information\n");
+ fprintf(hfile_fp, " */\n\n");
+ }
+}
+
+/*
+ * process_body
+ *
+ * inputs - filename of src
+ * - FILE pointer of src
+ * - FILE pointer of cfile output
+ * - FILE pointer of hfile output
+ * output - NONE
+ * side effects - exits on error
+ */
+static void
+process_body(char *src, FILE *src_fp, FILE *cfile_fp, FILE *hfile_fp,
+ int line_count)
+{
+ char input_buffer[MAXLINE];
+ char *p;
+ char *s;
+ char *token;
+ char *src_noext;
+ int myheader;
+
+ myheader=0;
+
+ src_noext = strip_ext(src, ".m");
+
+ while (fgets(input_buffer, MAXLINE-1, src_fp) != NULL) {
+
+ /* strip newlines */
+ if ((p = strchr(input_buffer, '\n')) != NULL)
+ *p = '\0';
+ /* Now, why does someone have carriage returns in here? */
+ if ((p = strchr(input_buffer, '\r')) != NULL)
+ *p = '\0';
+
+ /* not fancy, but include include files for now */
+ if (strncmp(input_buffer, "#include", 8) == 0) {
+ if (cfile)
+ fprintf(cfile_fp, "%s\n", input_buffer);
+ continue;
+ }
+ /* Ignore comments */
+ if (input_buffer[0] == '#')
+ continue;
+
+ /* Ignore blank lines */
+ if (input_buffer[0] == '\0')
+ continue;
+
+ if (strncmp(input_buffer,"CODE", 4) == 0) {
+ if (cfile && !myheader) {
+ fprintf(cfile_fp, "#include \"%s.h\"\n\n",
+ src_noext);
+ myheader = 1;
+ }
+
+ emit_code_section(src, src_fp, cfile_fp);
+
+ } else if (strncmp(input_buffer, "METHOD", 6) == 0) {
+
+ if (cfile && !myheader) {
+ fprintf(cfile_fp, "#include \"%s.h\"\n\n",
+ src_noext);
+ myheader = 1;
+ }
+
+
+ line_count = parse_method(src_noext, src_fp, cfile_fp,
+ hfile_fp, input_buffer, line_count);
+ }
+ }
+
+ free(src_noext);
+}
+
+
+/*
+ * parse_method
+ *
+ * inputs - pointer to source file name
+ * - pointer to temp cfile name output
+ * - pointer to temp hfile name output
+ * - pointer to scratch input
+ * - line_count
+ * - given program name
+ * output - new line_count
+ * side effects - METHOD is parsed, correct code is emitted as necessary
+ */
+static int
+parse_method(char *src,
+ FILE *src_fp, FILE *cfile_fp, FILE *hfile_fp,
+ char *input_buffer, int line_count)
+{
+ char *uppercase_src;
+ char *uppercase_mname; /* method name */
+ char *token; /* currently being parsed token */
+ char *method; /* should always be 'METHOD' */
+ char *mtype;
+ char *dname;
+ char *tmp_type;
+ char *mname; /* method name */
+ char *p;
+ char *trim_src;
+ int cur_list; /* counter into type/names list */
+ int deref;
+
+ deref = cur_list = 0;
+
+ token = first_token(input_buffer); /* METHOD */
+ token = next_token(token); /* type or struct */
+
+ if (strcmp(token, "struct") == 0) {
+ token = next_token(token); /* type */
+ mtype = make_malloc(strlen("struct ") + strlen(token) + 1);
+ strcpy(mtype, "struct ");
+ /* Copy it into place, knowing where end of "struct " is */
+ strcpy(mtype + 7, token);
+ } else {
+ mtype = make_strdup(token);
+ }
+
+ token = next_token(token); /* name */
+ deref = 0;
+ if (*token == '*') {
+ deref = 1;
+ mname = make_strdup(token + 1);
+ } else {
+ if (strcmp(token, "*") == 0) {
+ deref = 1;
+ if((token = next_token(token)) == NULL) {
+ err(0, "Null");
+ }
+ }
+ }
+ mname = make_strdup(token);
+ if (debug)
+ printf("deref %d mtype [%s] mname [%s]\n", deref, mtype, mname);
+
+ while (fgets(input_buffer, MAXLINE-1, src_fp) != NULL) {
+ ++line_count;
+ if (input_buffer[0] == '#') {
+ continue;
+ }
+
+ trim_src = trim_name(src);
+
+ if (strchr(input_buffer, '}') != NULL) {
+ token = first_token(input_buffer);
+ token = next_token(token);
+
+ if (token != NULL) {
+ if (strcmp(token, "DEFAULT") == 0) {
+ dname = next_token(token);
+ }
+ if ((p = strchr(dname, ';')) != NULL)
+ *p = '\0';
+
+ } else dname = "0";
+
+ if (cfile)
+ emit_c_body(trim_src, src_fp, cfile_fp, mname,
+ dname);
+ if (hfile)
+ emit_h_body(trim_src, hfile_fp, mtype, mname,
+ cur_list);
+ break;
+ }
+
+ free(trim_src);
+
+ if ((p = strchr(input_buffer, '\n')) != NULL)
+ *p = '\0';
+
+ if ((p = strchr(input_buffer, ';')) != NULL)
+ *p = '\0';
+
+ if ((token = first_token(input_buffer)) == NULL) {
+ err(0, "parse error line number %d", line_count);
+ }
+
+ if (strcmp(token, "struct") == 0) {
+ if ((token = next_token(input_buffer)) == NULL) {
+ err(0, "parse error line number %d",
+ line_count);
+ }
+ tmp_type = make_malloc(strlen("struct ") + strlen(token) + 1);
+ /* Copy it into place, knowing where end of "struct " is */
+ strcpy(tmp_type, "struct ");
+ strcpy(tmp_type + 7, token);
+ } else {
+ tmp_type = make_strdup(token);
+ }
+ type_name_list[cur_list].mtype = tmp_type;
+
+ if ((token = next_token(token)) == NULL) {
+ err(0, "parse error line number %d", line_count);
+ }
+ if (*token == '*') {
+ type_name_list[cur_list].deref = 1;
+ type_name_list[cur_list].mname = make_strdup(token+1);
+ } else {
+ if (strcmp(token, "*") == 0) {
+ type_name_list[cur_list].deref = 1;
+ if ((token = next_token(token)) == NULL) {
+ err(0, "parse error line number %d",
+ line_count);
+ }
+ }
+ type_name_list[cur_list].mname = make_strdup(token);
+ }
+
+ cur_list++;
+ if (cur_list >= MAXLIST)
+ err(0, "parse error MAXLIST exceed line number %d",
+ line_count);
+ }
+
+ free(mtype);
+ free(mname);
+ return (line_count);
+
+}
+
+/*
+ * emit_code_section
+ *
+ * inputs - filename of src
+ * - FILE pointer of src
+ * - FILE pointer of cfile output
+ * output - NONE
+ * side effects - exits on error
+ */
+static void
+emit_code_section(char *src, FILE *src_fp, FILE *cfile_fp)
+{
+ char input_buffer[MAXLINE];
+
+ while (fgets(input_buffer, MAXLINE - 1, src_fp) != NULL) {
+
+/* XXX can do better then a simple strncmp
+ * can strchr both '}' and ';' if needed.
+ * could also count brace depth. i.e. - if } seen if reaches 0, done.
+ */
+ if (strncmp(input_buffer, "};", 2) == 0)
+ return;
+ if (cfile)
+ fprintf (cfile_fp, "%s", input_buffer);
+ }
+}
+
+/*
+ * upper_case
+ *
+ * inputs - pointer to name to upper case
+ * output - pointer to given string as upper case
+ * side effects - caller is responsible for freeing memory
+ */
+static char *
+upper_case(char *name)
+{
+ static char *upper;
+ char *p;
+
+ upper = make_strdup(name);
+
+ for (p = upper; *p; p++) {
+ *p = toupper(*p);
+ }
+
+ return (upper);
+}
+
+/*
+ * emit_c_body
+ *
+ * inputs - filename of src
+ * - FILE pointer of src
+ * - FILE pointer of cfile output
+ * - method name
+ * output - NONE
+ * side effects - exits on error
+ */
+static void
+emit_c_body(char *src, FILE *src_fp, FILE *cfile_fp, char *mname, char *dname)
+{
+ if (cfile) {
+ fprintf(cfile_fp, "struct kobjop_desc %s_%s_desc = {\n", src,
+ mname);
+ fprintf(cfile_fp, "\t0, (kobjop_t) %s\n", dname);
+ fprintf(cfile_fp, "};\n\n");
+ }
+
+}
+
+/*
+ * emit_h_body
+ *
+ * inputs - filename of src
+ * - FILE pointer of src
+ * - FILE pointer of hfile output
+ * - method name
+ * output - NONE
+ * side effects - exits on error
+ */
+static void
+emit_h_body(char *src, FILE *hfile_fp, char *mtype, char *mname, int max_list)
+{
+ char input_buffer[MAXLINE];
+ char *upper_case_src;
+ char *upper_case_mname;
+ int i;
+
+ upper_case_src = upper_case(src);
+ upper_case_mname = upper_case(mname);
+
+ fprintf(hfile_fp, "extern struct kobjop_desc %s_%s_desc;\n", src,
+ mname);
+ fprintf(hfile_fp, "typedef %s %s_%s_t(", mtype, src, mname);
+
+ for (i = 0; i < max_list; i++) {
+ if ((i+1) != max_list) {
+ fprintf (hfile_fp, "%s %s%s, ",
+ type_name_list[i].mtype,
+ type_name_list[i].deref ? "*" : "",
+ type_name_list[i].mname);
+
+ } else {
+ fprintf (hfile_fp, "%s %s%s);\n",
+ type_name_list[i].mtype,
+ type_name_list[i].deref ? "*" : "",
+ type_name_list[i].mname);
+ }
+ }
+
+ fprintf(hfile_fp,"static __inline %s %s_%s(", mtype, upper_case_src,
+ upper_case_mname);
+
+ for (i = 0; i < max_list; i++) {
+ if ((i+1) != max_list) {
+ fprintf (hfile_fp, "%s %s%s, ",
+ type_name_list[i].mtype,
+ type_name_list[i].deref ? "*" : "",
+ type_name_list[i].mname);
+
+ } else {
+ fprintf (hfile_fp, "%s %s%s)\n",
+ type_name_list[i].mtype,
+ type_name_list[i].deref ? "*" : "",
+ type_name_list[i].mname);
+ }
+ }
+
+ fprintf(hfile_fp, "{\n");
+ fprintf(hfile_fp, "\tkobjop_t _m;\n");
+ fprintf(hfile_fp, "\tKOBJOPLOOKUP(((kobj_t)%s)->ops,%s_%s);\n",
+ type_name_list[0].mname, src, mname);
+
+ if (strcmp(mtype,"void") != 0) {
+ fprintf(hfile_fp, "\treturn ((%s_%s_t *) _m)(", src, mname);
+ }
+
+ for (i = 0; i < max_list; i++) {
+ if ((i+1) != max_list) {
+ fprintf (hfile_fp, "%s, ",
+ type_name_list[i].mname);
+
+ } else {
+ fprintf (hfile_fp, "%s);\n",
+ type_name_list[i].mname);
+ }
+ }
+
+ fprintf(hfile_fp, "}\n");
+ fprintf(hfile_fp, "\n");
+
+ free(upper_case_src);
+ free(upper_case_mname);
+}
+
+
+/*
+ * make_copy
+ *
+ * inputs - file to copy from
+ * - file to copy to
+ * output - NONE
+ * side effects - exits on error
+ */
+static void
+make_copy(char *fin, char *fout)
+{
+ int fd_in;
+ int fd_out;
+ char buffer[MAXLINE];
+ int nread;
+
+ if ((fd_in = open(fin, O_RDONLY)) < 0)
+ err(0, "Cannot open %s for read", fin);
+
+ if ((fd_out = open(fout, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
+ err(0, "Cannot open %s for write", fout);
+
+
+ while ((nread = read(fd_in, buffer, MAXLINE)) > 0)
+ write(fd_out, buffer, nread);
+
+ close(fd_in);
+ close(fd_out);
+}
+
+/*
+ * strip_ext
+ *
+ * inputs - pointer to string
+ * output - pointer to string without extension
+ * side effects - NONE
+ */
+static char *
+strip_ext(char *s, char *ext)
+{
+ char *t;
+ char *p;
+
+ t = make_strdup(s);
+ if ((p = strstr(t, ext)) != NULL) {
+
+ /* The observant will note this leaves 2 extra bytes allocated
+ * unnecessarily. *tough* memory is cheap.
+ */
+ *p = '\0';
+ }
+ return (t);
+}
+
+/*
+ * skip_spaces
+ *
+ * inputs - pointer to string
+ * output - pointer to string without leading spaces
+ * side effects - NONE
+ */
+static char*
+skip_spaces(char *s)
+{
+ while (isspace(*s))
+ s++;
+
+ return (s);
+}
+
+/*
+ * first_token
+ *
+ * inputs - pointer to string
+ * output - pointer to next token
+ * side effects - NONE
+ */
+static char*
+first_token(char *s)
+{
+ char *t;
+
+ if (s == NULL)
+ return (NULL);
+ if (*s == '\0')
+ return (NULL);
+
+ while (isspace(*s))
+ s++;
+ t = s;
+ while (!isspace(*t))
+ t++;
+ *t = '\0';
+ return (s);
+}
+
+/*
+ * next_token
+ *
+ * inputs - pointer to string
+ * output - pointer to next token
+ * side effects - NONE
+ */
+static char*
+next_token(char *s)
+{
+ char *t;
+
+ if (s == NULL)
+ return (NULL);
+ while (*s != '\0')
+ s++;
+ s++;
+ if (*s == '\0')
+ return (NULL);
+
+ while (isspace(*s))
+ s++;
+ t = s;
+
+ while (!isspace(*t))
+ t++;
+ *t = '\0';
+
+ return (s);
+}
+
+/*
+ * trim_name
+ *
+ * inputs - pointer to name to trim
+ * output - pointer to static trimmed to first '_'
+ * i.e 'foo_h' trimmed to 'foo'
+ * side effects - NONE
+ */
+static char *
+trim_name(char *name)
+{
+ char *trimmed;
+ char *p;
+
+ trimmed = make_strdup(name);
+
+ if ((p = strchr(trimmed, '_')) != NULL)
+ *p = '\0';
+ return (trimmed);
+}
+
+/*
+ * make_malloc
+ *
+ * inputs - number of byte to allocate
+ * output - pointer to allocated memory
+ * side effects - exits if unable to malloc
+ */
+static char*
+make_malloc(int size)
+{
+ char *s;
+
+ s = malloc(size);
+
+ if (s == NULL)
+ err(0, "Out of memory");
+ return (s);
+}
OpenPOWER on IntegriCloud