int main(int argc, char **argv) { program_name = argv[0]; static char stderr_buf[BUFSIZ]; setbuf(stderr, stderr_buf); int opt; int load_startup_file = 1; static const struct option long_options[] = { { "help", no_argument, 0, CHAR_MAX + 1 }, { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; while ((opt = getopt_long(argc, argv, "DCRvd:f:p:s:m:T:M:rN", long_options, NULL)) != EOF) switch (opt) { case 'C': compatible_flag = 1; break; case 'R': // don't load eqnrc load_startup_file = 0; break; case 'M': config_macro_path.command_line_dir(optarg); break; case 'v': printf("GNU eqn (groff) version %s\n", Version_string); exit(0); break; case 'd': if (optarg[0] == '\0' || optarg[1] == '\0') error("-d requires two character argument"); else if (invalid_input_char(optarg[0])) error("bad delimiter `%1'", optarg[0]); else if (invalid_input_char(optarg[1])) error("bad delimiter `%1'", optarg[1]); else { start_delim = optarg[0]; end_delim = optarg[1]; } break; case 'f': set_gfont(optarg); break; case 'T': device = optarg; if (strcmp(device, "ps:html") == 0) { device = "ps"; html = 1; } else if (strcmp(device, "MathML") == 0) { output_format = mathml; load_startup_file = 0; } else if (strcmp(device, "mathml:xhtml") == 0) { device = "MathML"; output_format = mathml; load_startup_file = 0; xhtml = 1; } break; case 's': if (!set_gsize(optarg)) error("invalid size `%1'", optarg); break; case 'p': { int n; if (sscanf(optarg, "%d", &n) == 1) set_script_reduction(n); else error("bad size `%1'", optarg); } break; case 'm': { int n; if (sscanf(optarg, "%d", &n) == 1) set_minimum_size(n); else error("bad size `%1'", optarg); } break; case 'r': one_size_reduction_flag = 1; break; case 'D': warning("-D option is obsolete: use `set draw_lines 1' instead"); draw_flag = 1; break; case 'N': no_newline_in_delim_flag = 1; break; case CHAR_MAX + 1: // --help usage(stdout); exit(0); break; case '?': usage(stderr); exit(1); break; default: assert(0); } init_table(device); init_char_table(); if (output_format == troff) { printf(".if !'\\*(.T'%s' " ".if !'\\*(.T'html' " // the html device uses `-Tps' to render // equations as images ".tm warning: %s should have been given a `-T\\*(.T' option\n", device, program_name); printf(".if '\\*(.T'html' " ".if !'%s'ps' " ".tm warning: %s should have been given a `-Tps' option\n", device, program_name); printf(".if '\\*(.T'html' " ".if !'%s'ps' " ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n", device); } if (load_startup_file) { char *path; FILE *fp = config_macro_path.open_file(STARTUP_FILE, &path); if (fp) { do_file(fp, path); fclose(fp); a_delete path; } } if (optind >= argc) do_file(stdin, "-"); else for (int i = optind; i < argc; i++) if (strcmp(argv[i], "-") == 0) do_file(stdin, "-"); else { errno = 0; FILE *fp = fopen(argv[i], "r"); if (!fp) fatal("can't open `%1': %2", argv[i], strerror(errno)); else { do_file(fp, argv[i]); fclose(fp); } } if (ferror(stdout) || fflush(stdout) < 0) fatal("output error"); return 0; }
/* process directives from file */ int process_c_callback(char *filename){ int oo, errors=0; int i, nrange, start_of_list=0; int status; wordint wstatus; int cmd_end = ')'; unsigned char cmd_strt; if(INIT) init_char_table(); INIT = 0; /* open input file if a name was specified, use stdin otherwise */ streamd=stdin; if(filename != NULL) streamd=fopen(filename,"r"); if (streamd == NULL) { fprintf(stderr,"process_c_callback: Cannot Open File -%s-\n",filename); goto error; } while(Verb(token)>0){ /* collect "verb" (command name) */ ARGLEN=0; ARGC=0; ARGV[0]=token; Skip_Blanks(0); if(cur_char_typ != 32 ) { fprintf(stderr,"Badly formed command \n"); goto error; } cmd_strt = cur_char; cmd_end = ( cur_char == '(' ) ? ')' : ';' ; /* assign proper terminator to command */ Next_Char(0); /* collect comma separated command arguments */ while(1){ collect_arg: ARGC++; ARGV[ARGC]=&ARGTXT[ARGLEN]; if((oo=Argument(ARGTXT+ARGLEN)) <= 0 ) { fprintf(stderr,"TOKEN error in argument\n"); goto error; } if((ARGC>=MAXARGS-1) || (ARGLEN+oo>=MAXARGLEN-1)) { fprintf(stderr,"Too many arguments or arguments too long \n"); fprintf(stderr,"ARGC=%d, ARGLEN=%d, oo=%d \n",ARGC,ARGLEN,oo); goto error; } if(*ARGV[ARGC]=='[') { /* Argument is '[ ', will become [nnn */ /* printf("Start of list at ARGC=%d\n",ARGC); */ ARGTXT[ARGLEN+1] = '0'; ARGTXT[ARGLEN+2] = '0'; ARGTXT[ARGLEN+3] = '0'; ARGTXT[ARGLEN+4] = ']'; ARGTXT[ARGLEN+5] = '\0'; ARGLEN=ARGLEN+6; if(start_of_list!=0) { fprintf(stderr,"List already open \n"); goto error; } start_of_list=ARGC; goto collect_arg; } ARGTXT[ARGLEN+oo]='\0'; ARGLEN=ARGLEN+oo+1; if(*ARGV[ARGC]=='>'){ /* range detected */ double dble0,dble1,dble2; char term; char pad[1024]; int nargs; nargs=sscanf(ARGV[ARGC]," > %lf , %lf , %lf%[%> ]%c",&dble0,&dble1,&dble2,pad); /* printf("Range detected, nargs=%d,pad=:%s:,from %f to %f by %f\n",nargs,pad,dble0,dble1,dble2); */ if(nargs!=4 || pad[strlen(pad)-1]!='>') { fprintf(stderr,"bad range\n"); goto error;} ARGLEN=ARGLEN-oo-1;ARGC--; nrange=(dble1-dble0)/dble2; if(nrange<0) nrange=0; while(nrange-->=0) { /* expand range into argument list */ if((ARGC>=MAXARGS-1) || (ARGLEN+oo>=MAXARGLEN-30)) { fprintf(stderr,"Too many arguments or arguments too long \n"); fprintf(stderr,"nrange:ARGC=%d, ARGLEN=%d, oo=%d \n",ARGC,ARGLEN,oo); goto error; } ARGC++; ARGV[ARGC]=ARGTXT+ARGLEN; oo=sprintf(ARGV[ARGC],"%f",dble0); ARGTXT[ARGLEN+oo]='\0'; ARGLEN=ARGLEN+oo+1; dble0=dble0+dble2; } } again: Skip_Blanks(0); Current_Char(); if(cur_char == ']') { if(start_of_list==0) { fprintf(stderr,"Cannot close non existent list \n"); goto error; } /* printf("End of %d element list at ARGC=%d\n",ARGC-start_of_list,ARGC); */ sprintf(ARGV[start_of_list],"[%3d]",ARGC-start_of_list); start_of_list=0; Next_Char(0); goto again; } if(cur_char == cmd_end) break; /* command terminator found */ if(cur_char != ',') {fprintf(stderr,"bad separator :%c:\n",cur_char); goto error;} Next_Char(0); } Next_Char(0); Skip_Blanks(0); if(start_of_list!=0) { fprintf(stderr,"Unmatched [ \n"); goto error; } if( (oo=Find_Callback(token)) >= 0 ) { if(callback_table[oo].is_ftn){ int max_arg_lng=0; int i; int arg_lng; char *F_ARGV; int j; char *temp; for (i=0 ; i<=ARGC ; i++) { /* find the length of the longest argument */ arg_lng=strlen(ARGV[i]); max_arg_lng=arg_lng>max_arg_lng?arg_lng:max_arg_lng; } F_ARGV=(char *)malloc(max_arg_lng*(1+ARGC)); /* allocate FORTRAN string space */ for (i=0 ; i<max_arg_lng*(1+ARGC) ; i++) F_ARGV[i]=' '; temp=F_ARGV; for (j=0;j<=ARGC;j++) { /* copy strings from C strings to FORTRAN strings */ arg_lng=strlen(ARGV[j]); for (i=0 ; i<max_arg_lng ; i++) { if(i<arg_lng)*temp=ARGV[j][i]; temp++; } } wstatus=callback_table[oo].command(&ARGC,F_ARGV,&cmd_strt, callback_table[oo].private_data, callback_table[oo].private_data_2,max_arg_lng,1); status=wstatus; free(F_ARGV); } else { status=callback_table[oo].command(ARGC,ARGV,cmd_strt, callback_table[oo].private_data, callback_table[oo].private_data_2); } if(status!=0) goto error; }else{ fprintf(stderr,"Command %s NOT FOUND\n",token); } continue; error: fprintf(stderr,"skipping rest of line\n"); errors++; buffer_out=buffer_in; start_of_list=0; if(abort_on_error) return(errors); } /* while verb */ return (errors); }