| /* |
| * |
| * General purpose routines. |
| * |
| */ |
| |
| #include <u.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <ctype.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <string.h> |
| |
| #include "gen.h" |
| #include "ext.h" |
| #include "path.h" |
| |
| int nolist = 0; /* number of specified ranges */ |
| int olist[50]; /* processing range pairs */ |
| |
| int str_convert(char **str, int err); |
| void error(int kind, char *mesg, unsigned int a1, unsigned int a2, unsigned int a3); |
| int cat(char *file); |
| |
| /*****************************************************************************/ |
| |
| void |
| out_list(str) |
| |
| char *str; |
| |
| { |
| |
| int start, stop; |
| |
| /* |
| * |
| * Grab page ranges from str, save them in olist[], and update the nolist |
| * count. Range syntax matches nroff/troff syntax. |
| * |
| */ |
| |
| while ( *str && nolist < sizeof(olist) - 2 ) { |
| start = stop = str_convert(&str, 0); |
| |
| if ( *str == '-' && *str++ ) |
| stop = str_convert(&str, 9999); |
| |
| if ( start > stop ) |
| error(FATAL, "illegal range %d-%d", start, stop, 0); |
| |
| olist[nolist++] = start; |
| olist[nolist++] = stop; |
| |
| if ( *str != '\0' ) str++; |
| } /* End while */ |
| |
| olist[nolist] = 0; |
| |
| } /* End of out_list */ |
| |
| /*****************************************************************************/ |
| int |
| in_olist(num) |
| |
| int num; |
| |
| { |
| |
| int i; |
| |
| /* |
| * |
| * Return ON if num is in the current page range list. Print everything if |
| * there's no list. |
| * |
| */ |
| if ( nolist == 0 ) |
| return(ON); |
| |
| for ( i = 0; i < nolist; i += 2 ) |
| if ( num >= olist[i] && num <= olist[i+1] ) |
| return(ON); |
| |
| return(OFF); |
| |
| } /* End of in_olist */ |
| |
| /*****************************************************************************/ |
| void |
| setencoding(name) |
| |
| char *name; |
| |
| { |
| |
| char path[150]; |
| |
| /* |
| * |
| * Include the font encoding file selected by name. It's a full pathname if |
| * it begins with /, otherwise append suffix ".enc" and look for the file in |
| * ENCODINGDIR. Missing files are silently ignored. |
| * |
| */ |
| |
| if ( name == NULL ) |
| name = "Default"; |
| |
| if ( *name == '/' ) |
| strcpy(path, name); |
| else sprintf(path, "%s/%s.enc", ENCODINGDIR, name); |
| |
| if ( cat(path) == TRUE ) |
| writing = strncmp(name, "UTF", 3) == 0; |
| |
| } /* End of setencoding */ |
| |
| /*****************************************************************************/ |
| int |
| cat(file) |
| |
| char *file; |
| |
| { |
| |
| int fd_in; |
| int fd_out; |
| char buf[512]; |
| int count; |
| |
| /* |
| * |
| * Copy *file to stdout. Return FALSE is there was a problem. |
| * |
| */ |
| |
| fflush(stdout); |
| |
| if ( (fd_in = open(file, O_RDONLY)) == -1 ) |
| return(FALSE); |
| |
| fd_out = fileno(stdout); |
| while ( (count = read(fd_in, buf, sizeof(buf))) > 0 ) |
| write(fd_out, buf, count); |
| |
| close(fd_in); |
| |
| return(TRUE); |
| |
| } /* End of cat */ |
| |
| /*****************************************************************************/ |
| |
| int |
| str_convert(str, err) |
| |
| char **str; |
| int err; |
| |
| { |
| |
| int i; |
| |
| /* |
| * |
| * Grab the next integer from **str and return its value or err if *str |
| * isn't an integer. *str is modified after each digit is read. |
| * |
| */ |
| |
| if ( ! isdigit((uchar)**str) ) |
| return(err); |
| |
| for ( i = 0; isdigit((uchar)**str); *str += 1 ) |
| i = 10 * i + **str - '0'; |
| |
| return(i); |
| |
| } /* End of str_convert */ |
| |
| /*****************************************************************************/ |
| |
| void |
| error(kind, mesg, a1, a2, a3) |
| |
| int kind; |
| char *mesg; |
| unsigned a1, a2, a3; |
| |
| { |
| |
| /* |
| * |
| * Print an error message and quit if kind is FATAL. |
| * |
| */ |
| |
| if ( mesg != NULL && *mesg != '\0' ) { |
| fprintf(stderr, "%s: ", prog_name); |
| fprintf(stderr, mesg, a1, a2, a3); |
| if ( lineno > 0 ) |
| fprintf(stderr, " (line %ld)", lineno); |
| if ( position > 0 ) |
| fprintf(stderr, " (near byte %ld)", position); |
| putc('\n', stderr); |
| } /* End if */ |
| |
| if ( kind == FATAL && ignore == OFF ) { |
| if ( temp_file != NULL ) |
| unlink(temp_file); |
| exit(x_stat | 01); |
| } /* End if */ |
| |
| } /* End of error */ |
| |
| /*****************************************************************************/ |
| |
| void interrupt(sig) |
| |
| int sig; |
| |
| { |
| |
| /* |
| * |
| * Signal handler for translators. |
| * |
| */ |
| |
| if ( temp_file != NULL ) |
| unlink(temp_file); |
| |
| exit(1); |
| |
| } /* End of interrupt */ |
| |
| /*****************************************************************************/ |
| |