summaryrefslogtreecommitdiff
path: root/xml2ag/fork.tpl
diff options
context:
space:
mode:
Diffstat (limited to 'xml2ag/fork.tpl')
-rw-r--r--xml2ag/fork.tpl223
1 files changed, 223 insertions, 0 deletions
diff --git a/xml2ag/fork.tpl b/xml2ag/fork.tpl
new file mode 100644
index 0000000..e882886
--- /dev/null
+++ b/xml2ag/fork.tpl
@@ -0,0 +1,223 @@
+[= AutoGen5 Template c=fork.c -*- Mode: C -*- =]
+[= # Time-stamp: "2012-04-07 09:56:01 bkorb"
+
+ * This file is part of AutoGen.
+ * AutoGen Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
+ *
+ * AutoGen is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AutoGen is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ =][=
+
+(define up-c-name (lambda (ag-name)
+ (string-upcase! (string->c-name! (get ag-name))) ))
+
+(dne " * " "/* ")=]
+ *
+ * This module will fire up autogen and have it read definitions
+ * from its standard-in.
+ */
+
+static char const zFsError[] = "%s fs ERROR %d (%s) on %s\n";
+
+static void
+add_arg(char const * arg, int ix)
+{
+ char ** arg_vec = xml2agOptions.origArgVect;
+ int arg_ct = xml2agOptions.origArgCt;
+
+ if (ix >= (int)arg_ct) {
+ arg_ct += 5;
+ arg_vec = realloc(arg_vec, sizeof(void*) * (arg_ct+1));
+ if (arg_vec == NULL) {
+ fprintf(stderr, "No memory for %d args\n", arg_ct);
+ exit(EXIT_FAILURE);
+ }
+ xml2agOptions.origArgVect = arg_vec;
+ }
+ arg_vec[ ix ] = (void*)arg;
+}
+
+static int
+become_child(int * fd, char const* pzInput)
+{
+ if (pipe(fd) != 0) {
+ fprintf(stderr, zFsError, xml2agOptions.pzProgName,
+ errno, strerror( errno ), "pipe(2)");
+ exit(EXIT_FAILURE);
+ }
+
+ fflush(stdout);
+ fflush(stdin);
+
+ switch (fork()) {
+ case -1:
+ fprintf(stderr, zFsError, xml2agOptions.pzProgName,
+ errno, strerror( errno ), "fork(2)");
+ exit(EXIT_FAILURE);
+
+ case 0:
+ fclose(stdin);
+ if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) {
+ fprintf(stderr, zFsError, xml2agOptions.pzProgName,
+ errno, strerror( errno ), "dup2(2) w/ STDIN_FILENO");
+ exit(EXIT_FAILURE);
+ }
+ close(fd[1]);
+ break;
+
+ default:
+ errno = 0;
+ outFp = fdopen(fd[1], "w");
+ if (outFp == NULL) {
+ fprintf(stderr, zFsError, xml2agOptions.pzProgName,
+ errno, strerror( errno ), "fdopen(2) w/ pipe[1]");
+ exit(EXIT_FAILURE);
+ }
+ close(fd[0]);
+ return 0;
+ }
+
+ if (! HAVE_OPT( BASE_NAME )) {
+ if (pzInput == NULL)
+ pzInput = "stdin";
+ else {
+ char* pz = strrchr(pzInput, '.');
+ if (pz != NULL) {
+ pzInput = pz = strdup(pzInput);
+ pz = strrchr(pz, '.');
+ *pz = '\0';
+ }
+ }
+ SET_OPT_BASE_NAME(pzInput);
+ }
+
+ return 1;
+}
+
+void
+forkAutogen(char const* pzInput)
+{
+ int fd[2];
+
+ if (! become_child(fd, pzInput))
+ return;
+
+ {
+ static char const zAg[] = "autogen";
+ char* pzArg;
+ int ix = 1;
+
+ {
+ char* pz = malloc(strlen( xml2agOptions.pzProgPath ) + 7);
+ char* p = strrchr(xml2agOptions.pzProgPath, '/');
+
+ if (p == NULL) {
+ strcpy(pz, zAg);
+ } else {
+ size_t len = (p - xml2agOptions.pzProgPath) + 1;
+ memcpy(pz, xml2agOptions.pzProgPath, len);
+ strcpy(pz + len, zAg);
+ }
+
+ add_arg(pz, 0);
+ }[=
+
+ FOR flag =][=
+ IF (define opt-name (up-c-name "name"))
+
+ (and
+ (not (~~ opt-name "OVERRIDE_TPL|OUTPUT"))
+ (not (exist? "documentation"))
+ ) =][=
+
+ INVOKE handle-option =][=
+ ENDIF (not override) =][=
+ ENDFOR =]
+
+ xml2agOptions.origArgVect[ix] = NULL;
+ execvp(xml2agOptions.origArgVect[0], xml2agOptions.origArgVect);
+
+ /*
+ * IF the first try fails, it may be because xml2ag and autogen have
+ * different paths. Try again with just plain "autogen" and let
+ * the OS search "PATH" for the program.
+ */
+ execvp(zAg, xml2agOptions.origArgVect);
+ fprintf(stderr, zFsError, xml2agOptions.pzProgName,
+ errno, strerror(errno), "execvp(2)");
+ exit(EXIT_FAILURE);
+ }
+}
+
+/*
+ * Local Variables:
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of [= (out-name) =] */
+[=
+
+DEFINE handle-option =]
+
+ if (HAVE_OPT([=(. opt-name)=])) {[=
+
+ CASE arg-type =][=
+
+ ==* key =]
+ static char const * kwlist[] = {
+[=(shellf "${CLexe:-columns} -I16 -f'\"%%s\"' -S, --spread=2 <<_EOF_\n%s\n_EOF_"
+ (join "\n" (stack "keyword")) )=] };
+ pzArg = malloc([= (+ 4 (string-length (get "name")))
+ =] + strlen( kwlist[ OPT_VALUE_[=(. opt-name)=] ] ));
+ sprintf(pzArg, "--[=name=]=%s", kwlist[ OPT_VALUE_[=
+ (. opt-name)=] ]);
+ add_arg(pzArg, ix++);[=
+
+ ==* num =]
+ pzArg = malloc((size_t)[= (+ 16 (string-length (get "name"))) =]);
+ sprintf(pzArg, "--[=name=]=%d", (int)OPT_VALUE_[=(. opt-name)=]);
+ add_arg(pzArg, ix++);[=
+
+ ==* bool =]
+ static char z[] = "--[=name=]=false";
+ if (OPT_VALUE_[=(. opt-name)=])
+ strcpy(z + [= (+ 3 (string-length (get "name"))) =], "true");
+ add_arg(z, ix++);[=
+
+ ==* str =][=
+ IF (exist? "max") =]
+ int optCt = STACKCT_OPT([=(. opt-name)=]);
+ char const ** ppOA = STACKLST_OPT([=(. opt-name)=]);
+ do {
+ char const * pA = *(ppOA++);
+ pzArg = malloc([= (+ 4 (string-length (get "name")))
+ =] + strlen(pA));
+ sprintf(pzArg, "--[=name=]=%s", pA);
+ add_arg(pzArg, ix++);
+ } while (--optCt > 0);[=
+ ELSE !exists-max =]
+ pzArg = malloc([= (+ 4 (string-length (get "name")))
+ =] + strlen( OPT_ARG( [=(. opt-name)=] )));
+ sprintf(pzArg, "--[=name=]=%s", OPT_ARG( [=(. opt-name)=] ));
+ add_arg(pzArg, ix++);[=
+ ENDIF exists-max =][=
+
+ == "" =]
+ add_arg("--[=name=]", ix++);[=
+
+ ESAC arg-type =]
+ }[=
+
+ENDDEF handle-option
+
+\=]