int main(int _argc, char **_argv) { /* clear shell variables and re-assign a minimum set */ clearenv(); setenv("PATH", ":/bin:/usr/bin", 1); setenv("PROMPT", "$ ", 1); setenv("SHELL", _argv[0], 1); signal(SIGINT, SIG_IGN); /* ignore ^C */ while(1) { printf("%s", getenv("PROMPT")); if(!read_command()) break; split_command(); if(!argc) continue; expand_args(); /* process builtin commands */ if(!strcmp(argv[0],"exit")) { break; } else if(!strcmp(argv[0],"set")) { if(argc!=3) { fprintf(stderr, "set: two arguments required\n"); continue; } setenv(argv[1], argv[2], 1); } else if(!strcmp(argv[0], "cd")) { if(argc!=2) { fprintf(stderr, "cd: one argument required\n"); continue; } if(chdir(argv[1])==-1) { perror("cd"); } } else if(!strcmp(argv[0], "pwd")) { if(argc!=1) { fprintf(stderr, "pwd: no arguments allowed\n"); continue; } printf("%s\n", getcwd(command, BUF_LEN)); } else { /* run external command */ run_program(); } free_args(); } printf("\n"); return 0; }
static char * parse_cmd(int type, char *cmd, const char *repo, struct file_info_list *file_info) { int expanded = 0; char argbuf[2] = { '\0', '\0' }; char *allowed_args, *default_args, *args, *file, *p, *q = NULL; size_t pos; BUF *buf; switch (type) { case CVS_TRIGGER_COMMITINFO: allowed_args = "prsS{}"; default_args = " %p/%r %S"; file = CVS_PATH_COMMITINFO; break; case CVS_TRIGGER_LOGINFO: allowed_args = "prsSvVt{}"; default_args = NULL; file = CVS_PATH_LOGINFO; break; case CVS_TRIGGER_VERIFYMSG: allowed_args = "l"; default_args = " %l"; file = CVS_PATH_VERIFYMSG; break; case CVS_TRIGGER_TAGINFO: allowed_args = "btoprsSvV{}"; default_args = " %t %o %p/%r %{sv}"; file = CVS_PATH_TAGINFO; break; default: return (NULL); } /* before doing any stuff, check if the command starts with % */ for (p = cmd; *p != '%' && !isspace((unsigned char)*p) && *p != '\0'; p++) ; if (*p == '%') return (NULL); buf = buf_alloc(1024); p = cmd; again: for (; *p != '\0'; p++) { if ((pos = strcspn(p, "$%")) != 0) { buf_append(buf, p, pos); p += pos; } q = NULL; if (*p == '\0') break; if (*p++ == '$') { if (*p == '{') { pos = strcspn(++p, "}"); if (p[pos] == '\0') goto bad; } else { for (pos = 0; isalpha(p[pos]); pos++) ; if (pos == 0) { cvs_log(LP_ERR, "unrecognized variable syntax"); goto bad; } } q = xmalloc(pos + 1); memcpy(q, p, pos); q[pos] = '\0'; if (expand_var(buf, q)) goto bad; p += pos - (*(p - 1) == '{' ? 0 : 1); } else { switch (*p) { case '\0': goto bad; case '{': if (strchr(allowed_args, '{') == NULL) goto bad; pos = strcspn(++p, "}"); if (p[pos] == '\0') goto bad; q = xmalloc(pos + 1); memcpy(q, p, pos); q[pos] = '\0'; args = q; p += pos; break; default: argbuf[0] = *p; args = argbuf; break; } if (expand_args(buf, file_info, repo, allowed_args, args)) goto bad; expanded = 1; } free(q); } if (!expanded && default_args != NULL) { p = default_args; expanded = 1; goto again; } buf_putc(buf, '\0'); return (buf_release(buf)); bad: free(q); cvs_log(LP_NOTICE, "%s contains malformed command '%s'", file, cmd); buf_free(buf); return (NULL); }
int exec_write(struct exec_info **info,const char *program, const char *args_in,const char *name,int writeonly,int binary) { int ret=G10ERR_GENERAL; if(opt.exec_disable && !opt.no_perm_warn) { log_info(_("external program calls are disabled due to unsafe " "options file permissions\n")); return ret; } #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) /* There should be no way to get to this spot while still carrying setuid privs. Just in case, bomb out if we are. */ if ( getuid () != geteuid ()) BUG (); #endif if(program==NULL && args_in==NULL) BUG(); *info=xmalloc_clear(sizeof(struct exec_info)); if(name) (*info)->name=xstrdup(name); (*info)->flags.binary=binary; (*info)->flags.writeonly=writeonly; /* Expand the args, if any */ if(args_in && expand_args(*info,args_in)) goto fail; #ifdef EXEC_TEMPFILE_ONLY if(!(*info)->flags.use_temp_files) { log_error(_("this platform requires temporary files when calling" " external programs\n")); goto fail; } #else /* !EXEC_TEMPFILE_ONLY */ /* If there are no args, or there are args, but no temp files, we can use fork/exec/pipe */ if(args_in==NULL || (*info)->flags.use_temp_files==0) { int to[2],from[2]; if(pipe(to)==-1) goto fail; if(pipe(from)==-1) { close(to[0]); close(to[1]); goto fail; } if(((*info)->child=fork())==-1) { close(to[0]); close(to[1]); close(from[0]); close(from[1]); goto fail; } if((*info)->child==0) { char *shell=getenv("SHELL"); if(shell==NULL) shell="/bin/sh"; /* I'm the child */ /* If the program isn't going to respond back, they get to keep their stdout/stderr */ if(!(*info)->flags.writeonly) { /* implied close of STDERR */ if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1) _exit(1); /* implied close of STDOUT */ close(from[0]); if(dup2(from[1],STDOUT_FILENO)==-1) _exit(1); } /* implied close of STDIN */ close(to[1]); if(dup2(to[0],STDIN_FILENO)==-1) _exit(1); if(args_in==NULL) { if(DBG_EXTPROG) log_debug("execlp: %s\n",program); execlp(program,program,(void *)NULL); } else { if(DBG_EXTPROG) log_debug("execlp: %s -c %s\n",shell,(*info)->command); execlp(shell,shell,"-c",(*info)->command,(void *)NULL); } /* If we get this far the exec failed. Clean up and return. */ if(args_in==NULL) log_error(_("unable to execute program `%s': %s\n"), program,strerror(errno)); else log_error(_("unable to execute shell `%s': %s\n"), shell,strerror(errno)); /* This mimics the POSIX sh behavior - 127 means "not found" from the shell. */ if(errno==ENOENT) _exit(127); _exit(1); } /* I'm the parent */ close(to[0]); (*info)->tochild=fdopen(to[1],binary?"wb":"w"); if((*info)->tochild==NULL) { ret = gpg_error_from_syserror (); close(to[1]); goto fail; } close(from[1]); (*info)->fromchild=iobuf_fdopen(from[0],"r"); if((*info)->fromchild==NULL) { ret = gpg_error_from_syserror (); close(from[0]); goto fail; } /* fd iobufs are cached?! */ iobuf_ioctl((*info)->fromchild,3,1,NULL); return 0; } #endif /* !EXEC_TEMPFILE_ONLY */ if(DBG_EXTPROG) log_debug("using temp file `%s'\n",(*info)->tempfile_in); /* It's not fork/exec/pipe, so create a temp file */ if( is_secured_filename ((*info)->tempfile_in) ) { (*info)->tochild = NULL; errno = EPERM; } else (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); if((*info)->tochild==NULL) { ret = gpg_error_from_syserror (); log_error(_("can't create `%s': %s\n"), (*info)->tempfile_in,strerror(errno)); goto fail; } ret=0; fail: if (ret) { xfree (*info); *info = NULL; } return ret; }
/* evaluate a simple command (3.9.1) * * this function doesn't put stuff in background, it always wait()s, so * it only needs to fork() real programs * ----------------------------------------------------------------------- */ int eval_simple_command(struct eval *e, struct ncmd *ncmd) { union node *nptr; int argc; char **argv; int status; union node *args = NULL; union node *assigns = NULL; union command cmd = { NULL }; enum hash_id id = H_BUILTIN; struct vartab vars; /* struct fdstack io;*/ union node *r; union node *redir = ncmd->rdir; /* expand arguments, if there are arguments we start a hashed search for the command */ if(expand_args(ncmd->args, &args, 0)) { stralloc_nul(&args->narg.stra); cmd = exec_hash(args->narg.stra.s, &id); } /* expand and set the variables, mark them for export if we're gonna execute a command */ if(expand_vars(ncmd->vars, &assigns)) { /* if we don't exit after the command, have a command and not a special builtin the variable changes should be temporary */ if(!(e->flags & E_EXIT) && cmd.ptr && id != H_SBUILTIN) vartab_push(&vars); for(nptr = assigns; nptr; nptr = nptr->list.next) var_setsa(&nptr->narg.stra, (cmd.ptr ? V_EXPORT : V_DEFAULT)); tree_free(assigns); } /* do redirections if present */ /* if(redir && id != H_SBUILTIN && id != H_EXEC) fdstack_push(&io);*/ if(redir/* && id != H_PROGRAM*/) { for(r = redir; r; r = r->list.next) { struct fd *fd = NULL; /* if its the exec special builtin the new fd needs to be persistent */ if(id != H_EXEC) fd_alloca(fd); /* return if a redirection failed */ if(redir_eval(&r->nredir, fd, (id == H_EXEC ? R_NOW : 0))) { status = 1; goto end; } /* check if we need to initialize fd buffers for the new redirection */ if(fd_needbuf(r->nredir.fd)) { /* if its not exec then set up buffers for temporary redirections on the stack */ if(id != H_EXEC) fd_setbuf(r->nredir.fd, alloca(FD_BUFSIZE), FD_BUFSIZE); else fd_allocbuf(r->nredir.fd, FD_BUFSIZE); } } } /* if there is no command we can return after setting the vars and doing the redirections */ if(args == NULL) { status = 0; goto end; } /* when the command wasn't found we abort */ if(cmd.ptr == NULL) { sh_error(args->narg.stra.s); status = exec_error(); goto end; } /* assemble argument list */ argc = tree_count(args); argv = alloca((argc + 1) * sizeof(char *)); expand_argv(args, argv); /* execute the command, this may or may not return, depending on E_EXIT */ status = exec_command(id, cmd, argc, argv, (e->flags & E_EXIT), redir); end: /* restore variable stack */ if(varstack == &vars) vartab_pop(&vars); if(args) tree_free(args); /* undo redirections */ if(id != H_EXEC) { for(r = redir; r; r = r->list.next) fd_pop(r->nredir.fd); } /* if(fdstack == &io) fdstack_pop(&io);*/ return status; }
int main( int argc, char **argv ) { int badopt= 0; int numfiles= 0; char *outfmt; #ifdef _DCC /* Dice */ expand_args(argc,argv, &argc,&argv); #endif /* _DCC */ infile= outfmt= (char *)0L; whoami= *argv; fin= stdin; fout= stdout; ferr= stderr; while(--argc>0 && !badopt) { char *arg= *++argv; if(*arg=='-') { if(arg[1]=='-') arg= convert_args(*argv); switch(*++arg) { /*-d*/ case 'd': #ifdef DEBUG debuglevel= 1; #else echo("not compiled w/ a symbol DEBUG defined. No debugging information available -- Sorry."); #endif break; /*-E*/ case 'E': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0L; if(arg && *arg) { if(ferr != stderr) { warn("warning: option `%s' has already been seen!",*argv); fclose(ferr); } ferr= fopen(arg,"w"); if(!ferr) { warn("can't direct error output to `%s' -- will use stderr",arg); ferr= stderr; } } else { warn("missing filename after `%s' option",*argv); ++badopt; } break; /*-?*/ case '?': /*-h*/ case 'h': fprintf(stderr, "usage: %s [options] [-o|>] [outfile] [<] [infiles..]\n\n",whoami); display_args(); badopt= 1; /* hack: means exit. */ break; /*-o*/ case 'o': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0L; if(arg && *arg) { if(outfmt) warn("option `%s' has already been seen!",*argv); outfmt= arg; } else { warn("missing output filename after `%s' option",*argv); ++badopt; } break; /*-s*/ case 's': warn("silent option `%s' is not yet implemented -- sorry.",*argv); break; /*-v*/ case 'v': display_version_information(); badopt= 1; /* hack: means exit. */ break; /*??*/ default: warn("unrecognized option `%s'",*argv); ++badopt; break; } } else { if(arg && *arg) { if( chain_fname(arg) ) { warn("out of memory... aaaiiiiiieeeeeeeee!"); ++badopt; } else ++numfiles; } else { warn("command line error: can't parse `%s'",arg); ++badopt; } } } if(numfiles) { while( !badopt && (infile= unchain_fname()) ) { if( fin= fopen(infile,"rb") ) { if( fout= outfmt ? fmtopen(outfmt, infile) : stdout ) { badopt= dothehardpart(); if(fout != stdout) fclose(fout); } else ++badopt; /* fmtopen() has already warned */ fclose(fin); } else { warn("can't access your input file `%s'",infile); ++badopt; } } purge_flist(); } else if( !badopt ) { if( fout= outfmt ? fmtopen(outfmt, "stdin") : stdout ) { badopt= dothehardpart(); if(fout != stdout) fclose(fout); } else ++badopt; /* fmtopen() has already warned */ } if(fin && fin != stdin) fclose(fin); if(fout && fout != stdout) fclose(fout); if(ferr && ferr != stderr) fclose(ferr); exit( badopt ? 1:0 ); }
int main(int argc, char *argv[]) { int err= 0; /* return code */ char *outfile = (char *)0; /* --output-file */ char *errfile = (char *)0; /* --error-file */ char *headerfile = (char *)0; /* --texi-header-file */ char *yank_type = "*"; /* --yank-type */ char *body_env = "smallexample"; /* -B<environment> */ int page_width = 80; /* --page-width */ int tabsize = 8; /* --tab-size */ int tabs_to_spaces = 0; /* --tabs-to-spaces */ int output_type = 1; /* --output-type */ int table_of_contents = 0; /* --table-of-contents */ int sort_entries = 1; /* --preserve-order */ int texi_flags = TEXI_CREATE_HEADER | TEXI_PARSE_REFERENCES | TEXI_ITEMIZE_REFERENCES; int adoc_flags = ADOC_FORM_FEEDS; int warn_mask = WARN_NORMAL; int scanner_flags = 0; /* --indented-comments */ /* --unindent-bodytext */ int minimum_indentation = -1; /* --reindent-bodytext */ /* handles for the macro tables */ int texi_macros = 0; int body_macros = 0; #ifdef _DCC /* Dice */ expand_args(argc,argv, &argc,&argv); #endif /* _DCC */ /* filenames on MS-DOG systems look very ugly: all uppercase and * backslashes. Perform some cosmetics */ #ifdef __MSDOS__ whoami= "adoc"; #else whoami= argv[0]; #endif /*__MSDOS__*/ /* set the debugging defaults */ D(bug_init(0,stdout)); /* initialize the default error stream */ ferr= stderr; if(err == 0) { /* prepare the texinfo macro table */ texi_macros= mactab_new( 4+10 ); if(!texi_macros) err= 1; } if(err == 0) { /* prepare the body-text macro table */ body_macros= mactab_new( 2 ); if(!body_macros) err= 2; } if(err) echo("error %d creating macro tables -- not enough memory?", err); else /* BEGIN scanning command line arguments */ while( (--argc > 0) && (err <= 0) ) { char *arg= *++argv; #ifdef DEBUG if(argc > 1) { D(bug("examining command line argument `%s' ( `%s', ... ) [%d]", argv[0], argv[1], argc-1)); } else { D(bug("examining command line argument `%s' ( ) [%d]", argv[0], argc-1)); } #endif /* DEBUG */ if(*arg=='-') { /* remember the original command-line option string */ char *opt= arg; if(arg[1]=='-') arg= convert_args(*argv); switch(*++arg) { /*-0*/ case '0': output_type= 0; break; /*-1*/ case '1': output_type= 1; break; /*-2*/ case '2': output_type= 2; tabs_to_spaces= 1; minimum_indentation= 0; break; /*-b*/ case 'b': texi_flags |= TEXI_TABLE_FUNCTIONS; break; /*-B*/ case 'B': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { body_env= arg; } else { echo("missing texinfo body text environment after %s option",opt); err= 1; } break; /*-c*/ case 'c': err= mactab_add(body_macros, "\\*", "/*", "*\\", "*/", (char *)0); if(err) echo("error %d adding comment convertion macros",err); break; /*-d*/ case 'd': #ifdef DEBUG if(arg[1]) { D(bug_level= atoi( &(arg[1]) )); } else { D(bug_level= 1); } #else /* !DEBUG */ echo("not compiled w/ -DDEBUG. No debug information available -- Sorry"); /* no error */ #endif /* DEBUG */ break; /*-D*/ case 'D': if(arg[1] && --argc > 0) { char *lhs= &arg[1]; char *rhs= *(++argv); err= mactab_add(texi_macros, lhs, rhs, (char *)0); if(err) echo("error adding texinfo macro `%s' = `%s'", lhs, rhs); } else { echo("missing macro %s after `%s' option",(arg[1] ? "value":"name"),opt); err= 1; } break; /*-E*/ case 'E': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { if(errfile) { echo("warning: option `%s' has already been seen", opt); D(bug("%s \"%s\" superseeds -E \"%s\"", opt, arg, errfile)); } /*errfile= strcmp(arg,"-") ? arg : (char *)0;*/ errfile= arg; } else /* !(arg && *arg) */ { echo("missing filename after `%s' option", opt); err= 1; } break; /*-f*/ case 'f': if(arg[1]) { while(*++arg) switch(*arg) { case 'f': adoc_flags |= ADOC_FORM_FEEDS; texi_flags |= TEXI_FUNCTION_NEWPAGE; break; default: echo("unknown paging option: `%s'",opt); break; } } else /* !arg[1] */ { adoc_flags &= ~ADOC_FORM_FEEDS; texi_flags &= ~TEXI_FUNCTION_NEWPAGE; } break; /*-g*/ case 'g': if(arg[1]) { while(*++arg) switch(*arg) { case 's': texi_flags |= TEXI_GROUP_SECTIONS; break; default: echo("unknown grouping option: `%s'",opt); err= 1; break; } } else texi_flags &= ~TEXI_GROUP_SECTIONS; break; /*-H*/ case 'H': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { if(headerfile) { echo("warning: option `%s' has already been seen", opt); D(bug("%s \"%s\" superseeds -H \"%s\"", opt, arg, headerfile)); } headerfile= arg; } else /* !(arg && *arg) */ { echo("missing texinfo header filename after `%s' option", opt); err= 1; } break; /*-h*/ case 'h': printf("usage: %s [options] [-o outfile] [@ listfile] [infiles...]\n\n", whoami); display_args( arg[1] ? atoi(&arg[1]) : 3 ); err= -1; /* negative means exit w/o error */ break; /*-I*/ case 'I': table_of_contents= 1; break; /*-i*/ case 'i': yank_type= "i"; break; /*-j*/ case 'j': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { if( (minimum_indentation= atoi(arg)) < 0 ) { echo("illegal indentation: %d (must be >= 0)", minimum_indentation); err= 1; } } else /* !(arg && *arg) */ { echo("missing indentation after `%s' option", opt); err= 1; } break; /*-l*/ case 'l': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { page_width= atoi(arg); if(page_width < 1) { echo("illegal page width: `%s' (must be > 0)", arg); err= 1; } } else /* !(arg && *arg) */ { echo("missing page width after `%s' option", opt); err= 1; } break; /*-M*/ case 'M': if(arg[1] && --argc > 0) { char *lhs= &arg[1]; char *rhs= *(++argv); err= mactab_add(body_macros, lhs, rhs, (char *)0); if(err) echo("error adding body macro `%s' -> `%s'", lhs, rhs); } else { echo("missing macro %s after `%s' option",(arg[1] ? "value":"name"),opt); err= 1; } break; /*-n*/ case 'n': output_type= 0; break; /*-o*/ case 'o': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { if(outfile) echo("warning: option `%s' has already been seen", opt); outfile= arg; } else /* !(arg && *arg) */ { echo("missing filename after `%s' option", opt); err= 1; } break; /*-p*/ case 'p': sort_entries= arg[1] ? 1:0; break; /*-q*/ case 'q': break; /*-T*/ case 'T': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { tabs_to_spaces= 1; tabsize= atoi(arg); if(tabsize < 1) { echo("illegal tab step: `%d' (must be >= 1)", tabsize); err= 1; } } else /* !(arg && *arg) */ { echo("missing tab size after `%s' option", opt); err= 1; } break; /*-t*/ case 't': tabs_to_spaces= arg[1] ? atoi(&arg[1]) : 1; break; /*-U*/ case 'U': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0; if(arg && *arg) { mactab_remove(texi_macros, arg, (char *)0); mactab_remove(body_macros, arg, (char *)0); } else /* !(arg && *arg) */ { echo("missing macro after `%s' option", opt); err= 1; } break; /*-u*/ case 'u': if(arg[1]) { scanner_flags &= ~SCANNER_UNINDENT_BODYTEXT; minimum_indentation= -1; } else scanner_flags |= SCANNER_UNINDENT_BODYTEXT; break; /*-v*/ case 'v': printf("ADOC Version " VERSION " (compiled " __DATE__ ", " __TIME__ ")\n" "(c)Copyright 1995 by Tobias Ferber, All Rights Reserved\n" ); err= -1; break; /*-W*/ case 'W': if(arg[1]) { ++arg; if( isdigit(*arg) ) warn_mask |= atoi(arg); else switch( strarg(arg, "none", /* 1 */ "arnings", /* 2 */ "keywords", /* 3 */ "absence", /* 4 */ "untitled", /* 5 */ "all", "") ) /* 6 */ { case 1: warn_mask = WARN_NONE; break; case 2: warn_mask |= WARN_NORMAL; break; case 3: warn_mask |= WARN_UNKNOWN_KEYWORDS; break; case 4: warn_mask |= WARN_MISSING_KEYWORDS; break; case 5: warn_mask |= WARN_UNTITLED_SECTION; break; case 6: warn_mask |= WARN_ALL; break; default: echo("unknown warning method: `%s'",opt); err= 1; break; } } else warn_mask= WARN_NONE; break; /*-x*/ case 'x': if(arg[1]) { switch( strarg(++arg, "off", /* 1 */ "on", /* 2 */ "itemize", /* 3 */ "", "") ) /* 4 */ { case 1: texi_flags &= ~TEXI_PARSE_REFERENCES; texi_flags &= ~TEXI_ITEMIZE_REFERENCES; break; case 2: texi_flags |= TEXI_PARSE_REFERENCES; texi_flags &= ~TEXI_ITEMIZE_REFERENCES; break; case 3: texi_flags |= TEXI_PARSE_REFERENCES; texi_flags |= TEXI_ITEMIZE_REFERENCES; break; default: echo("unknown reference handlig option: `%s'",opt); err= 1; break; } } else texi_flags &= ~(TEXI_PARSE_REFERENCES | TEXI_ITEMIZE_REFERENCES); break; /*-Y*/ case 'Y': if(arg[1]) scanner_flags &= ~SCANNER_ALLOW_INDENTED_COMMENTS; else scanner_flags |= SCANNER_ALLOW_INDENTED_COMMENTS; break; /*-y*/ case 'y': if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0L; if(arg && *arg) yank_type= arg; else /* !(arg && *arg) */ { echo("missing comment type string after `%s' option", opt); err= 1; } break; /*-z*/ case 'z': texi_flags &= ~TEXI_CREATE_HEADER; break; /*-Z*/ case 'Z': if(arg[1]) texi_flags &= ~TEXI_NO_INDEX; else texi_flags |= TEXI_NO_INDEX; break; /* * The following options are ignored for compatibility * with Bill Koester's original version `autodoc' which * is part of C=ommodore's Native Developer Kit (NDK). */ /*-C*/ case 'C': /*-F*/ case 'F': /*-s*/ case 's': /*-a*/ case 'a': /*-r*/ case 'r': /*-w*/ case 'w': echo("warning: option `%s' ignored for compatibility", opt); break; /*- */ case '\0': if( (err= flist_addfile("")) ) echo("out of memory... hmmmmmmmmmpf!"); break; /*??*/ default: echo("unrecognized option `%s'", opt); err= 1; break; } } else if(*arg=='@') { if(arg[1]) ++arg; else arg= (--argc > 0) ? *(++argv) : (char *)0L; if(arg && *arg) { if( (err= flist_from_file(arg)) ) echo("out of memory... aaarrrrrrgggggghh!"); } else /* !(arg && *arg) */ { echo("missing filename after `%s'", *argv); err= 1; } } else /* *arg != '@' */ { if(arg && *arg) { if( (err= flist_addfile(arg)) ) echo("out of memory... aaaiiiiiieeeeeeeee!"); } else echo("internal problem parsing command line arguments: arg is empty"); } } /* END scanning command line arguments */ D(bug("command line argument parsing done")); if(err == 0) { /* prepare the error stream */ if(errfile && *errfile) { D(bug("opening error stream `%s'",errfile)); if( !(ferr= fopen(errfile,"w")) ) { echo("could not write error messages to `%s'",errfile); err= __LINE__; } } /*else ferr is initialized to stderr */ /* if no filename is given then read from stdin */ if( !flist_getname() ) flist_addfile(""); /* read the input files (the scanner takes them from the flist queue) */ D(bug("reading autodocs of type `%s'", yank_type)); if(err == 0) err= read_source(yank_type, warn_mask, scanner_flags); if(err < 0) err= -err; /* I/O error */ D(bug("disposing file list")); flist_dispose(); /* */ if( (err == 0) && (minimum_indentation >= 0) ) { if( (err= funindent(minimum_indentation, tabsize)) ) echo("error %d reworking body text indentation -- not enough memory?",err); /* funindent() already performed that conversion */ else tabs_to_spaces= 0; } if( (err == 0) && (output_type > 0) ) { FILE *fout; /* prepare the output file */ if(outfile && *outfile) { D(bug("opening output stream `%s'",outfile)); if(!(fout= fopen(outfile,"w")) ) { echo("could not write to `%s'",outfile); err= __LINE__; } } else fout= stdout; if( fout && (err==0) ) { if(sort_entries) { D(bug("sorting entries")); funsort(); } switch(output_type) { case 1: /* --autodoc */ if(table_of_contents) { D(bug("writing table of contents")); err= gen_autodoc_toc(fout); } if(err == 0) { D(bug("writing autodocs")); err= gen_autodoc( fout, page_width, tabs_to_spaces ? tabsize : 0, adoc_flags, mactab(body_macros) ); } break; case 2: /* --texinfo */ if(texi_flags & TEXI_CREATE_HEADER) { D(bug("creating texinfo header")); err= gen_texinfo_header( fout, headerfile, mactab(texi_macros) ); } if(err == 0) { D(bug("adding texinfo body macros")); err= mactab_add( body_macros, "@", "@@", "{", "@{", "}", "@}", /* "...", "@dots{}", */ /* "TeX", "@TeX{}", */ "e.g. ", "e.g.@: ", "E.g. ", "E.g.@: ", "i.e. ", "i.e.@: ", "I.e. ", "I.e.@: ", (char *)0 ); } if(err == 0) { D(bug("creating texinfo output")); err+= gen_texinfo( fout, tabs_to_spaces ? tabsize : 0, texi_flags, body_env, mactab(body_macros) ); } if(err) echo("error creating texinfo output"); break; default: /* --dry-run */ break; } } if(fout && (fout != stdout)) fclose(fout); } D(bug("disposing libfun entries")); funfree(); } #ifdef DEBUG mactab_debug(bug_stream); #endif D(bug("disposing macro tables")); mactab_dispose(body_macros); mactab_dispose(texi_macros); /* */ if(err > 0) { echo("[%s] *** Error %d", (outfile && *outfile) ? outfile : "stdout", err); fprintf(ferr,"%s terminated abnormally (error %d)\n", whoami, err); } D(bug("closing I/O streams")); if( ferr && (ferr != stderr) && (ferr != stdout) ) fclose(ferr); D(bug("exiting adoc returning %d (%s)", (err>0) ? 1:0, (err>0) ? "error":"success" )); D(bug_exit()); #ifdef DEBUG if(bug_stream && (bug_stream != stdout)) fclose(bug_stream); #endif /*DEBUG*/ return (err > 0) ? 1:0; }