1 
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 
6 #include <sys/param.h>
7 
8 #include <ctype.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 
15 #include <paper.h>
16 
17 
18 /* needed for GNU/Hurd */
19 #ifndef MAXPATHLEN
20 #define MAXPATHLEN 4096
21 #endif
22 
usage(const char * name)23 static void usage(const char* name)
24 {
25     fprintf(stderr,
26 	"usage: %s [ [ -p ] papername | -d | -a ] [ -z ] [ -n | -N ] [ -s | -w | -h ] [ -c | -m | -i ]\n",
27 	    name);
28     exit(1);
29 }
30 
31 #define OPT_NAME	1
32 #define OPT_UPPERNAME	2
33 #define OPT_WIDTH	4
34 #define OPT_HEIGHT      8
35 #define OPT_CM         16
36 #define OPT_MM         32
37 #define OPT_INCH       64
38 #define OPT_CONTINUE  128
39 
40 #define OPT_UNIT      (OPT_CM | OPT_MM | OPT_INCH)
41 
42 #define INCHxCM 2.54
43 
printinfo(const struct paper * paper,int options)44 static void printinfo(const struct paper* paper, int options)
45 {
46     int pr = 0;
47 
48     if ((options & ~(OPT_CONTINUE)) == 0) {
49 	options = OPT_NAME;
50     }
51 
52     if (options & OPT_NAME) {
53 	printf("%s", papername(paper));
54 	pr = 1;
55     } else if (options & OPT_UPPERNAME) {
56 	if (islower(*papername(paper))) {
57 	    printf("%c%s", toupper(*papername(paper)), papername(paper) + 1);
58 	} else {
59 	    printf("%s", papername(paper));
60 	}
61 	pr = 1;
62     }
63 
64     if (options & OPT_WIDTH) {
65 	if (pr) putchar(' ');
66         if (options & OPT_CM)
67           printf("%g cm", paperpswidth(paper) / 72.0 * INCHxCM );
68 	else if (options & OPT_MM)
69           printf("%g mm", paperpswidth(paper) / 72.0 * 10 * INCHxCM );
70 	else if (options & OPT_INCH)
71           printf("%g\"", paperpswidth(paper) / 72.0 );
72 	else
73           printf("%g", paperpswidth(paper) );
74 	pr = 1;
75     }
76     if (options & OPT_HEIGHT) {
77 	if (pr) putchar(' ');
78         if (options & OPT_CM)
79           printf("%g cm", paperpsheight(paper) / 72.0 * INCHxCM );
80 	else if (options & OPT_MM)
81           printf("%g mm", paperpsheight(paper) / 72.0 * 10 * INCHxCM );
82 	else if (options & OPT_INCH)
83           printf("%g\"", paperpsheight(paper) / 72.0 );
84 	else
85           printf("%g", paperpsheight(paper) );
86 	pr = 1;
87     }
88 
89     putchar('\n');
90 }
91 
main(int argc,char ** argv)92 int main(int argc, char** argv)
93 {
94     int c;
95 
96     int all = 0;
97     const char* paper = 0;
98     unsigned options = 0;
99 
100     const char* progname;
101 
102     progname = strrchr(*argv, '/');
103     if (progname) {
104 	++progname;
105     } else {
106 	progname = *argv;
107     }
108 
109     while ((c = getopt(argc, argv, "adznNswhcmip:")) != EOF) {
110 	switch (c) {
111 	    case 'a':
112 		if (paper || all) {
113 		    usage(progname);
114 		}
115 		all = 1;
116 		break;
117 
118 	    case 'd':
119 		if (paper || all) {
120 		    usage(progname);
121 		}
122 		paper = defaultpapername();
123 		break;
124 
125 	    case 'p':
126 		if (paper || all) {
127 		    usage(progname);
128 		}
129 		paper = optarg;
130 		break;
131 
132 	    case 'z':
133 		options |= OPT_CONTINUE;
134 		break;
135 
136 	    case 'n':
137 		if (options & OPT_UPPERNAME) usage(progname);
138 		options |= OPT_NAME;
139 		break;
140 
141 	    case 'N':
142 		if (options & OPT_NAME) usage(progname);
143 		options |= OPT_UPPERNAME;
144 		break;
145 
146 	    case 's':
147 		options |= OPT_WIDTH | OPT_HEIGHT;
148 		break;
149 
150 	    case 'w':
151 		options |= OPT_WIDTH;
152 		break;
153 
154 	    case 'h':
155 		options |= OPT_HEIGHT;
156 		break;
157 
158 	    case 'c':
159 	        if (options & OPT_UNIT) usage(progname);
160 		options |= OPT_CM;
161 		break;
162 
163 	    case 'm':
164 	        if (options & OPT_UNIT) usage(progname);
165 		options |= OPT_MM;
166 		break;
167 
168 	    case 'i':
169 	        if (options & OPT_UNIT) usage(progname);
170 		options |= OPT_INCH;
171 		break;
172 
173 	    default:
174 		usage(progname);
175 	}
176     }
177 
178     if (optind < argc - 1 || (paper && optind != argc)) {
179 	usage(progname);
180     } else if (optind != argc) {
181 	paper = argv[optind];
182     }
183 
184     paperinit();
185 
186     if (all) {
187  	const struct paper* papers;
188 
189 	for (papers = paperfirst(); papers; papers = papernext(papers)) {
190 	    printinfo(papers, options);
191 	}
192     } else {
193         const struct paper* syspaper;
194 
195         if (!paper) paper = systempapername();
196         if (!paper) paper = defaultpapername();
197 	if (!paper) {
198 	    char errmsg[2 * MAXPATHLEN + 64];
199 
200 	    sprintf(errmsg, "%s: cannot get paper size from %s",
201 		progname, systempapersizefile());
202 
203 	    if (errno) {
204 		perror(errmsg);
205 	    } else {
206 	        fputs(errmsg, stderr);
207 	    }
208 
209 	    paperdone();
210 
211 	    exit(3);
212 	}
213 
214         syspaper = paperinfo(paper);
215 
216         if (syspaper) {
217             printinfo(syspaper, options);
218         } else {
219 	    fprintf(stderr, "%s: unknown paper `%s'\n", progname, paper);
220 	    if (options & OPT_CONTINUE) {
221 		puts(paper);
222 	    }
223 
224 	    paperdone();
225 
226 	    exit(2);
227         }
228     }
229 
230     paperdone();
231 
232     return 0;
233 }
234 
235