1219b2ee8SDavid du Colombier /*
2219b2ee8SDavid du Colombier * General purpose routines.
3219b2ee8SDavid du Colombier */
4219b2ee8SDavid du Colombier
5*14f51593SDavid du Colombier #define _BSD_EXTENSION
6*14f51593SDavid du Colombier
7219b2ee8SDavid du Colombier #include <stdio.h>
8*14f51593SDavid du Colombier #include <stdlib.h>
9*14f51593SDavid du Colombier #include <string.h>
10*14f51593SDavid du Colombier #include <unistd.h>
11219b2ee8SDavid du Colombier #include <ctype.h>
12219b2ee8SDavid du Colombier #include <sys/types.h>
13219b2ee8SDavid du Colombier #include <fcntl.h>
14219b2ee8SDavid du Colombier
15219b2ee8SDavid du Colombier #include "gen.h"
16219b2ee8SDavid du Colombier #include "ext.h"
17219b2ee8SDavid du Colombier #include "path.h"
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier int nolist = 0; /* number of specified ranges */
20219b2ee8SDavid du Colombier int olist[50]; /* processing range pairs */
21219b2ee8SDavid du Colombier
22*14f51593SDavid du Colombier int
out_list(str)23219b2ee8SDavid du Colombier out_list(str)
24219b2ee8SDavid du Colombier char *str;
25219b2ee8SDavid du Colombier {
26219b2ee8SDavid du Colombier int start, stop;
27219b2ee8SDavid du Colombier
28219b2ee8SDavid du Colombier /*
29219b2ee8SDavid du Colombier * Grab page ranges from str, save them in olist[], and update the nolist
30219b2ee8SDavid du Colombier * count. Range syntax matches nroff/troff syntax.
31219b2ee8SDavid du Colombier */
32219b2ee8SDavid du Colombier
33219b2ee8SDavid du Colombier while ( *str && nolist < sizeof(olist) - 2 ) {
34219b2ee8SDavid du Colombier start = stop = str_convert(&str, 0);
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier if ( *str == '-' && *str++ )
37219b2ee8SDavid du Colombier stop = str_convert(&str, 9999);
38219b2ee8SDavid du Colombier
39219b2ee8SDavid du Colombier if ( start > stop )
40*14f51593SDavid du Colombier error(FATAL, "illegal range %d-%d", start, stop, 0);
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier olist[nolist++] = start;
43219b2ee8SDavid du Colombier olist[nolist++] = stop;
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier if ( *str != '\0' ) str++;
46*14f51593SDavid du Colombier }
47219b2ee8SDavid du Colombier olist[nolist] = 0;
48*14f51593SDavid du Colombier return 0;
49*14f51593SDavid du Colombier }
50219b2ee8SDavid du Colombier
in_olist(num)51219b2ee8SDavid du Colombier in_olist(num)
52219b2ee8SDavid du Colombier int num;
53219b2ee8SDavid du Colombier {
54219b2ee8SDavid du Colombier int i;
55219b2ee8SDavid du Colombier
56219b2ee8SDavid du Colombier /*
57219b2ee8SDavid du Colombier * Return ON if num is in the current page range list. Print everything if
58219b2ee8SDavid du Colombier * there's no list.
59219b2ee8SDavid du Colombier */
60219b2ee8SDavid du Colombier if ( nolist == 0 )
61219b2ee8SDavid du Colombier return(ON);
62219b2ee8SDavid du Colombier
63219b2ee8SDavid du Colombier for ( i = 0; i < nolist; i += 2 )
64219b2ee8SDavid du Colombier if ( num >= olist[i] && num <= olist[i+1] )
65219b2ee8SDavid du Colombier return(ON);
66219b2ee8SDavid du Colombier return(OFF);
67*14f51593SDavid du Colombier }
68219b2ee8SDavid du Colombier
69*14f51593SDavid du Colombier int
setencoding(name)70219b2ee8SDavid du Colombier setencoding(name)
71219b2ee8SDavid du Colombier char *name;
72219b2ee8SDavid du Colombier {
73219b2ee8SDavid du Colombier char path[150];
74219b2ee8SDavid du Colombier
75219b2ee8SDavid du Colombier /*
76219b2ee8SDavid du Colombier * Include the font encoding file selected by name. It's a full pathname if
77219b2ee8SDavid du Colombier * it begins with /, otherwise append suffix ".enc" and look for the file in
78219b2ee8SDavid du Colombier * ENCODINGDIR. Missing files are silently ignored.
79219b2ee8SDavid du Colombier */
80219b2ee8SDavid du Colombier
81219b2ee8SDavid du Colombier if ( name == NULL )
82219b2ee8SDavid du Colombier name = "Default";
83219b2ee8SDavid du Colombier
84219b2ee8SDavid du Colombier if ( *name == '/' )
85219b2ee8SDavid du Colombier strcpy(path, name);
86219b2ee8SDavid du Colombier else sprintf(path, "%s/%s.enc", ENCODINGDIR, name);
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier if ( cat(path) == TRUE )
89219b2ee8SDavid du Colombier writing = strncmp(name, "UTF", 3) == 0;
90*14f51593SDavid du Colombier return 0;
91*14f51593SDavid du Colombier }
92219b2ee8SDavid du Colombier
cat(file)93219b2ee8SDavid du Colombier cat(file)
94219b2ee8SDavid du Colombier char *file;
95219b2ee8SDavid du Colombier {
96219b2ee8SDavid du Colombier int fd_in;
97219b2ee8SDavid du Colombier int fd_out;
98219b2ee8SDavid du Colombier char buf[512];
99219b2ee8SDavid du Colombier int count;
100219b2ee8SDavid du Colombier
101219b2ee8SDavid du Colombier /*
102219b2ee8SDavid du Colombier * Copy *file to stdout. Return FALSE is there was a problem.
103219b2ee8SDavid du Colombier */
104219b2ee8SDavid du Colombier
105219b2ee8SDavid du Colombier fflush(stdout);
106219b2ee8SDavid du Colombier if ( (fd_in = open(file, O_RDONLY)) == -1 )
107219b2ee8SDavid du Colombier return(FALSE);
108219b2ee8SDavid du Colombier fd_out = fileno(stdout);
109219b2ee8SDavid du Colombier while ( (count = read(fd_in, buf, sizeof(buf))) > 0 )
110219b2ee8SDavid du Colombier write(fd_out, buf, count);
111219b2ee8SDavid du Colombier close(fd_in);
112219b2ee8SDavid du Colombier return(TRUE);
113*14f51593SDavid du Colombier }
114219b2ee8SDavid du Colombier
str_convert(str,err)115219b2ee8SDavid du Colombier str_convert(str, err)
116219b2ee8SDavid du Colombier char **str;
117219b2ee8SDavid du Colombier int err;
118219b2ee8SDavid du Colombier {
119219b2ee8SDavid du Colombier int i;
120219b2ee8SDavid du Colombier
121219b2ee8SDavid du Colombier /*
122219b2ee8SDavid du Colombier *
123219b2ee8SDavid du Colombier * Grab the next integer from **str and return its value or err if *str
124219b2ee8SDavid du Colombier * isn't an integer. *str is modified after each digit is read.
125219b2ee8SDavid du Colombier *
126219b2ee8SDavid du Colombier */
127219b2ee8SDavid du Colombier
128219b2ee8SDavid du Colombier if ( ! isdigit(**str) )
129219b2ee8SDavid du Colombier return(err);
130219b2ee8SDavid du Colombier
131219b2ee8SDavid du Colombier for ( i = 0; isdigit(**str); *str += 1 )
132219b2ee8SDavid du Colombier i = 10 * i + **str - '0';
133219b2ee8SDavid du Colombier
134219b2ee8SDavid du Colombier return(i);
135*14f51593SDavid du Colombier }
136219b2ee8SDavid du Colombier
137*14f51593SDavid du Colombier void
error(int kind,char * fmt,...)138*14f51593SDavid du Colombier error(int kind, char *fmt, ...)
139219b2ee8SDavid du Colombier {
140*14f51593SDavid du Colombier char buf[256];
141*14f51593SDavid du Colombier va_list arg;
142219b2ee8SDavid du Colombier
143*14f51593SDavid du Colombier if (fmt) {
144*14f51593SDavid du Colombier va_start(arg, fmt);
145*14f51593SDavid du Colombier vsnprintf(buf, sizeof buf, fmt, arg);
146*14f51593SDavid du Colombier va_end(arg);
147*14f51593SDavid du Colombier fprintf(stderr, "%s: %s", prog_name, buf);
148219b2ee8SDavid du Colombier if (lineno > 0)
149219b2ee8SDavid du Colombier fprintf(stderr, " (line %d)", lineno);
150219b2ee8SDavid du Colombier if (position > 0)
151219b2ee8SDavid du Colombier fprintf(stderr, " (near byte %d)", position);
152219b2ee8SDavid du Colombier putc('\n', stderr);
153*14f51593SDavid du Colombier }
154219b2ee8SDavid du Colombier if (kind == FATAL && ignore == OFF) {
155219b2ee8SDavid du Colombier if (temp_file != NULL)
156219b2ee8SDavid du Colombier unlink(temp_file);
157219b2ee8SDavid du Colombier exit(x_stat | 01);
158*14f51593SDavid du Colombier }
159*14f51593SDavid du Colombier }
160219b2ee8SDavid du Colombier
161219b2ee8SDavid du Colombier /*
162219b2ee8SDavid du Colombier * Signal handler for translators.
163219b2ee8SDavid du Colombier */
164*14f51593SDavid du Colombier void
interrupt(int sig)165*14f51593SDavid du Colombier interrupt(int sig)
166*14f51593SDavid du Colombier {
167*14f51593SDavid du Colombier USED(sig);
168219b2ee8SDavid du Colombier if ( temp_file != NULL )
169219b2ee8SDavid du Colombier unlink(temp_file);
170219b2ee8SDavid du Colombier exit(1);
171*14f51593SDavid du Colombier }
172