int main(int argc, char *argv[]) { Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); char buf[BUFSIZ]; const char *paper = NULL, *output = NULL; FILE *pf, *of; int overflow, nest, is_ps2write = -1, ps2write_state = 0; int colorize = 1, lighten = 1, newcoloropt = 0, random_random_seed = 1; int rotate = 0; uint32_t random_seed = 0; program_name = Clp_ProgramName(clp); while (1) { int opt = Clp_Next(clp); switch (opt) { case DIR_OPT: catdir(clp->vstr, 0, colorize, lighten, rotate); newcoloropt = 0; break; case FILE_OPT: addcat(clp->vstr, colorize, lighten, rotate); newcoloropt = 0; break; case PAPER_OPT: if (paper) { fprintf(stderr, "%s: `--paper` specified twice\n", program_name); usage_error(); } paper = clp->vstr; break; case OUTPUT_OPT: if (output) { fprintf(stderr, "%s: `--output` specified twice\n", program_name); usage_error(); } output = clp->vstr; break; case SEED_OPT: if (clp->negated) random_random_seed = -1; else if (!clp->have_val) random_random_seed = 1; else random_random_seed = 0, random_seed = clp->val.u; break; case COLORIZE_OPT: colorize = !clp->negated; newcoloropt = 1; break; case LIGHTEN_OPT: lighten = !clp->negated; newcoloropt = 1; break; case ROTATE_OPT: if (clp->negated) rotate = 0; else if (clp->have_val) rotate = clp->val.i; else rotate = 20; newcoloropt = 1; break; case NOCOLORIZE_OPT: colorize = 0; newcoloropt = 1; break; case NOLIGHTEN_OPT: lighten = 0; newcoloropt = 1; break; case MAXCATS_OPT: maxcats = clp->val.i; break; case HELP_OPT: usage(); exit(0); case VERSION_OPT: printf("yapteaparprfotci %s\n", VERSION); printf("Copyright (c) 2005-2016 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case Clp_NotOption: if (paper) { fprintf(stderr, "%s: too many arguments\n", program_name); usage_error(); } paper = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(); } } done: if (newcoloropt) fprintf(stderr, "%s: warning: last colorize/lighten options ignored\n(These options only affect subsequently-named cat imagery.)\n", program_name); if (!ncats) fprintf(stderr, "%s: warning: no cat imagery! (Try `-d DIR` or `-f FILE`.)\n", program_name); if (!paper || strcmp(paper, "-") == 0) { pf = stdin; paper = "<stdin>"; } else { pf = fopen(paper, "r"); if (!pf) { perror(paper); exit(1); } fclose(stdin); } // Set random seed if (random_random_seed == 0) srandom(random_seed); else if (random_random_seed > 0) { #if HAVE_SRANDOMDEV srandomdev(); #else int i; srandom(time(NULL)); for (i = 0; i < getpid() % 43; i++) (void) random(); #endif } // Check for PDF if (fgets(buf, sizeof(buf), pf) == NULL) { fprintf(stderr, "%s: Empty file\n", paper); exit(1); } int need_pdf = 0; if (memcmp(buf, "%PDF-", 5) == 0) { int pipe1[2]; if (pipe(pipe1) != 0) { perror(program_name); exit(1); } pid_t child = fork(); if (child == 0) { size_t nread; close(STDOUT_FILENO); close(pipe1[0]); dup2(pipe1[1], STDOUT_FILENO); close(pipe1[1]); FILE* p = popen("pdf2ps -dLanguageLevel=3 - -", "w"); if (!p) { perror("pdftops"); exit(1); } close(STDOUT_FILENO); fputs(buf, p); while ((nread = fread(buf, 1, sizeof(buf), pf))) fwrite(buf, 1, nread, p); pclose(p); exit(0); } else if (child < 0) { perror(program_name); exit(1); } fclose(pf); close(pipe1[1]); pf = fdopen(pipe1[0], "r"); if (fgets(buf, sizeof(buf), pf) == NULL) { fprintf(stderr, "%s: PDF conversion failed\n", paper); exit(1); } need_pdf = 1; } // Output if (need_pdf) { char* ocmd = malloc(strlen(output ? output : "-") * 2 + 20); char* opos; const char* ipos; strcpy(ocmd, "ps2pdf - "); opos = ocmd + strlen(ocmd); for (ipos = output ? output : "-"; *ipos; ++ipos) if (isalnum(*ipos) || *ipos == '/' || *ipos == '.') *opos++ = *ipos; else { *opos++ = '\\'; *opos++ = *ipos; } *opos++ = 0; of = popen(ocmd, "w"); free(ocmd); } else if (!output || strcmp(output, "-") == 0) of = stdout; else if (!(of = fopen(output, "w"))) { perror(output); exit(1); } // Actually process overflow = nest = 0; do { char *newline = strchr(buf, '\n'); if (is_ps2write > 0 && ps2write_state) ps2write_state = check_ps2write(ps2write_state, buf); else if (is_ps2write < 0) { if (buf[0] != '%') is_ps2write = 0; else if (memcmp(buf, "%%Creator:", 10) == 0) is_ps2write = strstr(buf, "ps2write") != 0; } fputs(buf, of); if (!overflow && newline && memcmp(buf, "%%BeginDocument:", 16) == 0) nest++; else if (!overflow && newline && memcmp(buf, "%%EndDocument", 13) == 0) nest--; if (!overflow && newline && memcmp(buf, "%%Page: ", 8) == 0 && nest == 0) { double bbox[4] = {0, 0, 612, 792}; if (fgets(buf, sizeof(buf), pf) != NULL && memcmp(buf, "%%PageBoundingBox: ", 19) == 0) sscanf(buf + 19, "%lg %lg %lg %lg", &bbox[0], &bbox[1], &bbox[2], &bbox[3]); cat(of, 0, bbox); ps2write_state = 1; continue; } overflow = (newline == NULL); } while (fgets(buf, sizeof(buf), pf) != NULL); if (need_pdf) pclose(of); else fclose(of); return 0; }
int main(int argc, char *argv[]) { int c; FILE *ifp = 0, *ofp = 0; const char *ifp_filename = "<stdin>"; struct font_reader fr; int max_blocklen = -1; Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = (char *)Clp_ProgramName(clp); /* interpret command line arguments using CLP */ while (1) { int opt = Clp_Next(clp); switch (opt) { case BLOCK_LEN_OPT: max_blocklen = clp->val.i; if (max_blocklen <= 0) { max_blocklen = 1; error("warning: block length raised to %d", max_blocklen); } break; output_file: case OUTPUT_OPT: if (ofp) fatal_error("output file already specified"); if (strcmp(clp->arg, "-") == 0) ofp = stdout; else { ofp = fopen(clp->arg, "wb"); if (!ofp) fatal_error("%s: %s", clp->arg, strerror(errno)); } break; case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("t1binary (LCDF t1utils) %s\n", VERSION); printf("Copyright (C) 1992-2003 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case Clp_NotOption: if (ifp && ofp) fatal_error("too many arguments"); else if (ifp) goto output_file; if (strcmp(clp->arg, "-") == 0) ifp = stdin; else { ifp_filename = clp->arg; ifp = fopen(clp->arg, "r"); if (!ifp) fatal_error("%s: %s", clp->arg, strerror(errno)); } break; case Clp_Done: goto done; case Clp_BadOption: short_usage(); exit(1); break; } } done: if (!ifp) ifp = stdin; if (!ofp) ofp = stdout; #if defined(_MSDOS) || defined(_WIN32) /* As we are processing a PFB (binary) output */ /* file, we must set its file mode to binary. */ _setmode(_fileno(ofp), _O_BINARY); #endif /* prepare font reader and pfb writer */ fr.output_ascii = pfb_output_ascii; fr.output_binary = pfb_output_binary; fr.output_end = pfb_output_end; init_pfb_writer(&w, max_blocklen, ofp); /* peek at first byte to see if it is the PFB marker 0x80 */ c = getc(ifp); ungetc(c, ifp); /* do the file */ if (c == PFB_MARKER) process_pfb(ifp, ifp_filename, &fr); else if (c == '%') process_pfa(ifp, ifp_filename, &fr); else fatal_error("%s does not start with font marker (`%%' or 0x80)", ifp_filename); fclose(ifp); fclose(ofp); if (!w.binary_blocks_written) fatal_error("no binary blocks written! Are you sure this was a font?"); return 0; }
int Clp_Next(Clp_Parser *clp) /* Gets and parses the next argument from the argument list. If there are no more arguments, returns Clp_Done. If the next argument isn't an option, returns Clp_NotOption; the argument is stored in clp->arg. If the next argument is an option, returns that option's option_id. If the next argument is an unrecognizable or ambiguous option, an error message is given and Clp_BadOption is returned. If an option has an argument, that argument is stored in clp->arg and clp->have_arg is set to 1. Furthermore, that argument's parsed value (according to its type) is stored in the clp->val union. If an option needs an argument but isn't given one; if it doesn't need an argument but IS given one; or if the argument is the wrong type, an error message is given and Clp_BadOption is returned. */ { Clp_Internal *cli = clp->internal; Clp_Option *opt; Clp_ParserState clpsave; int complain; /** Set up clp **/ cli->current_option = 0; cli->ambiguous = 0; /** Get the next argument or option **/ if (!next_argument(clp, cli->option_processing ? 0 : 2)) return clp->have_arg ? Clp_NotOption : Clp_Done; clp->negated = cli->whole_negated; if (cli->is_short) opt = find_short(clp, cli->text[0]); else opt = find_long(clp, cli->text); /** If there's ambiguity between long & short options, and we couldn't find a long option, look for a short option **/ if (!opt && cli->could_be_short) { switch_to_short_argument(clp); opt = find_short(clp, cli->text[0]); } /** If we didn't find an option... **/ if (!opt || (clp->negated && !TEST(opt, Clp_Negate))) { /* default processing for the "--" option: turn off option processing and return the next argument */ if (strcmp(cli->argv[0], "--") == 0) { Clp_SetOptionProcessing(clp, 0); return Clp_Next(clp); } /* otherwise, report some error or other */ if (cli->ambiguous) ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values, cli->opt, cli->option_chars, "option `%s%s' is ambiguous", cli->option_chars, cli->text); else if (cli->is_short && !cli->could_be_short) Clp_OptionError(clp, "unrecognized option `%s%c'", cli->option_chars, cli->text[0]); else Clp_OptionError(clp, "unrecognized option `%s%s'", cli->option_chars, cli->text); return Clp_BadOption; } /** Set the current option **/ cli->current_option = opt; cli->current_short = cli->is_short; cli->negated_by_no = clp->negated && !cli->whole_negated; /** The no-argument (or should-have-no-argument) case **/ if (clp->negated || !TEST(opt, Clp_AnyArgument)) { if (clp->have_arg) { Clp_OptionError(clp, "`%O' can't take an argument"); return Clp_BadOption; } else return opt->option_id; } /** Get an argument if we need one, or if it's optional **/ /* Sanity-check the argument type. */ if (opt->arg_type <= 0 || opt->arg_type >= cli->nargtype || cli->argtype[ opt->arg_type ].func == 0) return Clp_Error; /* complain == 1 only if the argument was explicitly given, or it is mandatory. */ complain = (clp->have_arg != 0) || TEST(opt, Clp_Mandatory); Clp_SaveParser(clp, &clpsave); if (TEST(opt, Clp_Mandatory) && !clp->have_arg) { /* Mandatory argument case */ /* Allow arguments to options to start with a dash, but only if the argument type allows it by not setting Clp_DisallowOptions */ int disallow = TEST(&cli->argtype[opt->arg_type], Clp_DisallowOptions); next_argument(clp, disallow ? 1 : 2); if (!clp->have_arg) { int got_option = cli->text != 0; Clp_RestoreParser(clp, &clpsave); if (got_option) Clp_OptionError(clp, "`%O' requires a non-option argument"); else Clp_OptionError(clp, "`%O' requires an argument"); return Clp_BadOption; } } else if (cli->is_short && !clp->have_arg && cli->text[1] != 0) /* The -[option]argument case: Assume that the rest of the current string is the argument. */ next_argument(clp, 1); /** Parse the argument **/ if (clp->have_arg) { Clp_ArgType *atr = &cli->argtype[ opt->arg_type ]; if (atr->func(clp, clp->arg, complain, atr->thunk) <= 0) { /* parser failed */ clp->have_arg = 0; if (TEST(opt, Clp_Mandatory)) return Clp_BadOption; else Clp_RestoreParser(clp, &clpsave); } } return opt->option_id; }