util.h - abc2ps - A powerful sheet setting tool using the simple abc notation | |
git clone git://vernunftzentrum.de/abc2ps.git | |
Log | |
Files | |
Refs | |
--- | |
util.h (10221B) | |
--- | |
1 /* | |
2 * This file is part of abc2ps, | |
3 * Copyright (C) 1996,1997,1998 Michael Methfessel | |
4 * See file abc2ps.c for details. | |
5 */ | |
6 | |
7 /* low-level utilities */ | |
8 | |
9 | |
10 /* ----- error warning ----- */ | |
11 void wng (msg, str) | |
12 char msg[],str[]; | |
13 { | |
14 printf ("+++ %s%s\n", msg, str); | |
15 } | |
16 | |
17 /* ----- error exit ----- */ | |
18 void rx (msg, str) | |
19 char msg[],str[]; | |
20 { | |
21 printf ("\n+++ %s%s\n", msg, str); | |
22 exit (1); | |
23 } | |
24 | |
25 void rx1 (msg, c) | |
26 char msg[]; | |
27 char c; | |
28 { | |
29 printf ("\n+++ %s%c\n", msg, c); | |
30 exit (1); | |
31 } | |
32 | |
33 void rxi (msg, i) | |
34 char msg[]; | |
35 int i; | |
36 { | |
37 printf ("\n+++ %s%d\n", msg, i); | |
38 exit (1); | |
39 } | |
40 | |
41 /* ----- bug: print message for internal error and maybe stop ----- */ | |
42 void bug (msg,fatal) | |
43 char msg[]; | |
44 int fatal; | |
45 { | |
46 printf ("\n\nThis cannot happen!"); | |
47 if (strlen(msg)>0) printf ("\nInternal error: %s.\n", msg); | |
48 if (fatal) { | |
49 printf ("Emergency stop.\n\n"); | |
50 exit (1); | |
51 } | |
52 else { | |
53 printf ("Trying to continue...\n\n"); | |
54 } | |
55 } | |
56 | |
57 /* ----- ranf(x1,x2): return random float between x1 and x2 --- */ | |
58 float ranf(x1,x2) | |
59 float x1,x2; | |
60 { | |
61 static int m=259200; /* generator constants */ | |
62 static int a=421; | |
63 static int c=54773; | |
64 static int j=1; /* seed */ | |
65 float r; | |
66 | |
67 j=(j*a+c)%m; | |
68 r=x1+(x2-x1)*(double)j/(double)m; | |
69 return r; | |
70 } | |
71 | |
72 | |
73 /* ----- getline ----- */ | |
74 /* | |
75 * Added by jc: | |
76 * This routine reads a line from fp into buf, and trims away any | |
77 * trailing whitespace. We are paranoid about whether isspace(c) | |
78 * returns true for CR, so this routine should work even if the input | |
79 * came from a DOS system. | |
80 */ | |
81 char * abc2ps_getline(buf,len,fp) | |
82 char* buf; | |
83 int len; | |
84 FILE* fp; | |
85 { char* rp; | |
86 int c, l; | |
87 if (rp = fgets(buf,len,fp)) { | |
88 l = strlen(buf); | |
89 while ((l > 0) && ((c = buf[l-1]) && isspace(c) || (c ==… | |
90 buf[--l] = 0; | |
91 } | |
92 return rp; | |
93 } | |
94 | |
95 | |
96 /* ----- strip: remove leading and trailing blanks ----- */ | |
97 void strip (str1,str) | |
98 char str[],str1[]; | |
99 { | |
100 int l,i,i1,i2; | |
101 l=strlen(str); | |
102 | |
103 i1=0; | |
104 for (i=0; i<l; i++) | |
105 if ((str[i]!=' ') && (str[i]!='\n')) { i1=i; break; } | |
106 i2=0; | |
107 for (i=l-1; i>=0; i--) | |
108 if ((str[i]!=' ') && (str[i]!='\n')) { i2=i+1; break; } | |
109 for (i=i1;i<i2;i++) str1[i-i1]=str[i]; | |
110 str1[i2-i1]=0; | |
111 /* printf (" l=%d i1=%d i2=%d <%s> <%s>\n", l, i1, i2, str, str1);*/ | |
112 } | |
113 | |
114 | |
115 /* ----- nwords: count words in string ----- */ | |
116 int nwords (str) | |
117 char *str; | |
118 { | |
119 int w,k; | |
120 char *c; | |
121 c=str; | |
122 w=0; | |
123 for(k=0;k<=50;k++) { | |
124 while (*c==' ') c++; | |
125 if (*c=='\0') break; | |
126 w++; | |
127 while ((*c!=' ') && (*c!='\0')) c++; | |
128 if (*c=='\0') break; | |
129 } | |
130 return w; | |
131 } | |
132 | |
133 | |
134 | |
135 /* ----- getword: return n-th word from string ---- */ | |
136 int getword (iw,str,str1) | |
137 int iw; | |
138 char *str,*str1; | |
139 { | |
140 int w,k; | |
141 char *c,*cc; | |
142 if (iw<0) { *str1='\0'; return 0;} | |
143 c=str; | |
144 w=0; | |
145 for(k=0;k<=50;k++) { | |
146 while (*c==' ') c++; | |
147 if (*c=='\0') break; | |
148 if (w==iw) { | |
149 cc=str1; | |
150 while ((*c!=' ')&&(*c!='\0')) { *cc=*c; c++; cc++; } | |
151 *cc='\0'; | |
152 return 1; | |
153 } | |
154 w++; | |
155 while ((*c!=' ') && (*c!='\0')) c++; | |
156 if (*c=='\0') break; | |
157 } | |
158 *str1='\0'; | |
159 return 0; | |
160 } | |
161 | |
162 | |
163 /* ----- abbrev: check for valid abbreviation ----- */ | |
164 int abbrev (str,ab,nchar) | |
165 char str[],ab[]; | |
166 int nchar; | |
167 { | |
168 int i,nc; | |
169 if (strlen(str) > strlen(ab)) return 0; | |
170 nc=strlen(str); | |
171 if (nc<nchar) nc=nchar; | |
172 for (i=0;i<nc;i++) if (str[i] != ab[i]) return 0; | |
173 return 1; | |
174 } | |
175 | |
176 /* ----- isdig: checks char for digit ----- */ | |
177 int isdig (c) | |
178 char c; | |
179 { | |
180 if (c == '\0') return 0; | |
181 if (strchr("0123456789",c)) return 1; | |
182 return 0; | |
183 } | |
184 | |
185 /* ----- strext: set extension on a file identifier ----- */ | |
186 /* force=1 forces change even if fid already has an extension */ | |
187 /* force=0 does not change the extension if there already is one */ | |
188 void strext (fid1, fid, ext, force) | |
189 char fid[],ext[],fid1[]; | |
190 int force; | |
191 { | |
192 int i,l; | |
193 char *p,*q; | |
194 | |
195 strcpy (fid1, fid); | |
196 l=strlen(fid1); | |
197 p=fid1; | |
198 for (i=0;i<l;i++) | |
199 if (fid1[i]=='/') p=fid1+i; | |
200 | |
201 if (!force) { | |
202 q=strchr(p,'.'); | |
203 if (q && (q!=fid1+strlen(fid1)-1)) return; | |
204 } | |
205 if (!strchr(p,'.')) strcat (fid1,"."); | |
206 q=strchr(p,'.'); | |
207 if (strlen(ext)>0) q++; | |
208 *q = 0; | |
209 strcat(fid1,ext); | |
210 | |
211 } | |
212 | |
213 /* ----- cutext: cut off extension on a file identifier ----- */ | |
214 void cutext (fid) | |
215 char fid[]; | |
216 { | |
217 int i,l; | |
218 | |
219 l=strlen(fid); | |
220 for (i=0;i<l;i++) | |
221 if (fid[i]=='.') fid[i]='\0'; | |
222 } | |
223 | |
224 /* ----- getext: get extension on a file identifier ----- */ | |
225 void getext (fid,ext) | |
226 char fid[],ext[]; | |
227 { | |
228 int i,l,k; | |
229 | |
230 l=strlen(fid); | |
231 k=l-1; | |
232 for (i=0;i<l;i++) | |
233 if (fid[i]=='.') k=i; | |
234 | |
235 for (i=k+1;i<l;i++) | |
236 ext[i-k-1]=fid[i]; | |
237 ext[l-k-1]='\0'; | |
238 | |
239 } | |
240 | |
241 | |
242 /* ----- sscanu ----- */ | |
243 float scan_u(str) | |
244 char str[]; | |
245 { | |
246 char unit[81]; | |
247 float a,b; | |
248 | |
249 strcpy(unit,"pt"); | |
250 sscanf(str,"%f%s", &a, unit); | |
251 | |
252 if (!strcmp(unit,"cm")) b=a*CM; | |
253 else if (!strcmp(unit,"in")) b=a*IN; | |
254 else if (!strcmp(unit,"pt")) b=a*PT; | |
255 else { | |
256 printf ("+++ Unknown unit \"%s\" in: %s\n",unit,str); | |
257 exit (3); | |
258 } | |
259 return b; | |
260 } | |
261 | |
262 | |
263 /* ----- match ------- */ | |
264 int match (str, pat) | |
265 char str[], pat[]; | |
266 { | |
267 char *p,*s; | |
268 p=pat; | |
269 s=str; | |
270 | |
271 if (strlen(pat)==0) return 1; | |
272 | |
273 while (*p != 0) { | |
274 | |
275 if (*p == '*') { /* found wildcard '*' in pattern */ | |
276 p++; | |
277 while (*p == '*') p++; | |
278 if (*p == 0) return 1; /* trailing '*' matches all */ | |
279 for (;;) { /* find match to char after '*' */ | |
280 if (*s == 0) return 0; | |
281 if ((*s == *p) || (*p == '+')) | |
282 if (match(s+1,p+1)) return 1; /* ok if rest matches */ | |
283 s++; | |
284 } | |
285 } | |
286 | |
287 else { /* no wildcard -- char must match */ | |
288 if (*s == 0) return 0; | |
289 if ((*p != *s) && (*p != '+')) return 0; | |
290 s++; | |
291 } | |
292 p++; | |
293 } | |
294 | |
295 if (*s != 0) return 0; /* pattern but not string exhausted */ | |
296 return 1; | |
297 } | |
298 | |
299 /* ----- str_isblank: check for blank string ---- */ | |
300 int str_isblank (str) | |
301 char str[]; | |
302 { | |
303 int i; | |
304 for (i=0;i<strlen(str);i++) if (str[i] != ' ') return 0; | |
305 return 1; | |
306 } | |
307 | |
308 /* ----- cap_str: capitalize a string ----- */ | |
309 void cap_str(str) | |
310 char str[]; | |
311 { | |
312 char *c; | |
313 c=str; | |
314 while (*c!='\0') { | |
315 if (*c=='a') *c='A'; | |
316 else if (*c=='b') *c='B'; | |
317 else if (*c=='c') *c='C'; | |
318 else if (*c=='d') *c='D'; | |
319 else if (*c=='e') *c='E'; | |
320 else if (*c=='f') *c='F'; | |
321 else if (*c=='g') *c='G'; | |
322 else if (*c=='h') *c='H'; | |
323 else if (*c=='i') *c='I'; | |
324 else if (*c=='j') *c='J'; | |
325 else if (*c=='k') *c='K'; | |
326 else if (*c=='l') *c='L'; | |
327 else if (*c=='m') *c='M'; | |
328 else if (*c=='n') *c='N'; | |
329 else if (*c=='o') *c='O'; | |
330 else if (*c=='p') *c='P'; | |
331 else if (*c=='q') *c='Q'; | |
332 else if (*c=='r') *c='R'; | |
333 else if (*c=='s') *c='S'; | |
334 else if (*c=='t') *c='T'; | |
335 else if (*c=='u') *c='U'; | |
336 else if (*c=='v') *c='V'; | |
337 else if (*c=='w') *c='W'; | |
338 else if (*c=='x') *c='X'; | |
339 else if (*c=='y') *c='Y'; | |
340 else if (*c=='z') *c='Z'; | |
341 c++; | |
342 } | |
343 } | |
344 | |
345 | |
346 /* ----- cwid ----- */ | |
347 /* These are char widths for Times-Roman */ | |
348 float cwid(c) | |
349 char c; | |
350 { | |
351 float w; | |
352 if (c=='a') w=44.4; | |
353 else if (c=='b') w=50.0; | |
354 else if (c=='c') w=44.4; | |
355 else if (c=='d') w=50.0; | |
356 else if (c=='e') w=44.4; | |
357 else if (c=='f') w=33.3; | |
358 else if (c=='g') w=50.0; | |
359 else if (c=='h') w=50.0; | |
360 else if (c=='i') w=27.8; | |
361 else if (c=='j') w=27.8; | |
362 else if (c=='k') w=50.0; | |
363 else if (c=='l') w=27.8; | |
364 else if (c=='m') w=77.8; | |
365 else if (c=='n') w=50.0; | |
366 else if (c=='o') w=50.0; | |
367 else if (c=='p') w=50.0; | |
368 else if (c=='q') w=50.0; | |
369 else if (c=='r') w=33.3; | |
370 else if (c=='s') w=38.9; | |
371 else if (c=='t') w=27.8; | |
372 else if (c=='u') w=50.0; | |
373 else if (c=='v') w=50.0; | |
374 else if (c=='w') w=72.2; | |
375 else if (c=='x') w=50.0; | |
376 else if (c=='y') w=50.0; | |
377 else if (c=='z') w=44.4; | |
378 | |
379 else if (c=='A') w=72.2; | |
380 else if (c=='B') w=66.7; | |
381 else if (c=='C') w=66.7; | |
382 else if (c=='D') w=72.2; | |
383 else if (c=='E') w=61.1; | |
384 else if (c=='F') w=55.6; | |
385 else if (c=='G') w=72.2; | |
386 else if (c=='H') w=72.2; | |
387 else if (c=='I') w=33.3; | |
388 else if (c=='J') w=38.9; | |
389 else if (c=='K') w=72.2; | |
390 else if (c=='L') w=61.1; | |
391 else if (c=='M') w=88.9; | |
392 else if (c=='N') w=72.2; | |
393 else if (c=='O') w=72.2; | |
394 else if (c=='P') w=55.6; | |
395 else if (c=='Q') w=72.2; | |
396 else if (c=='R') w=66.7; | |
397 else if (c=='S') w=55.6; | |
398 else if (c=='T') w=61.1; | |
399 else if (c=='U') w=72.2; | |
400 else if (c=='V') w=72.2; | |
401 else if (c=='W') w=94.4; | |
402 else if (c=='X') w=72.2; | |
403 else if (c=='Y') w=72.2; | |
404 else if (c=='Z') w=61.1; | |
405 | |
406 else if (c=='0') w=50.0; | |
407 else if (c=='1') w=50.0; | |
408 else if (c=='2') w=50.0; | |
409 else if (c=='3') w=50.0; | |
410 else if (c=='4') w=50.0; | |
411 else if (c=='5') w=50.0; | |
412 else if (c=='6') w=50.0; | |
413 else if (c=='7') w=50.0; | |
414 else if (c=='8') w=50.0; | |
415 else if (c=='9') w=50.0; | |
416 | |
417 else if (c=='~') w=54.1; | |
418 else if (c=='!') w=33.3; | |
419 else if (c=='@') w=92.1; | |
420 else if (c=='#') w=50.0; | |
421 else if (c=='$') w=50.0; | |
422 else if (c=='%') w=83.3; | |
423 else if (c=='^') w=46.9; | |
424 else if (c=='&') w=77.8; | |
425 else if (c=='*') w=50.0; | |
426 else if (c=='(') w=33.3; | |
427 else if (c==')') w=33.3; | |
428 /*| else if (c=='-') w=33.3; |*/ | |
429 else if (c=='-') w=40.0; | |
430 else if (c=='_') w=50.0; | |
431 else if (c=='+') w=56.4; | |
432 else if (c=='=') w=55.0; | |
433 else if (c=='[') w=33.3; | |
434 else if (c==']') w=33.3; | |
435 else if (c=='{') w=48.0; | |
436 else if (c=='}') w=48.0; | |
437 else if (c=='|') w=20.0; | |
438 else if (c==':') w=27.8; | |
439 else if (c==';') w=27.8; | |
440 else if (c=='.') w=27.8; | |
441 else if (c==',') w=27.8; | |
442 else if (c=='\\') w=27.8; | |
443 else if (c=='\'') w=33.3; | |
444 else if (c=='\"') w=40.8; | |
445 else if (c=='<') w=56.4; | |
446 else if (c=='>') w=56.4; | |
447 else if (c=='?') w=44.4; | |
448 else if (c=='/') w=27.8; | |
449 else if (c=='`') w=33.3; | |
450 else if (c==' ') w=25.0; | |
451 else w=50.0; | |
452 return w/100.0; | |
453 } | |
454 | |
455 | |
456 /* ----- get_file_size ------- */ | |
457 /* version using standard function stat */ | |
458 #include <sys/stat.h> | |
459 int get_file_size (fname) | |
460 char fname[]; | |
461 { | |
462 int m,rc; | |
463 struct stat statbuf; | |
464 rc = stat(fname,&statbuf); | |
465 if (rc == -1) { | |
466 printf ("Unsuccessful call to stat for file %s\n", fname); | |
467 return -1; | |
468 } | |
469 m=statbuf.st_size; | |
470 return m; | |
471 } | |
472 | |
473 /* version which counts bytes by hand */ | |
474 int get_file_size1 (fname) | |
475 char fname[]; | |
476 { | |
477 int m,i; | |
478 FILE *fp; | |
479 | |
480 if ((fp = fopen (fname,"r")) == NULL) { | |
481 printf ("Cannot open file to determine size: %s", fname); | |
482 return -1; | |
483 } | |
484 | |
485 m=0; | |
486 i=getc(fp); | |
487 while (i != EOF) { | |
488 m++; | |
489 i=getc(fp); | |
490 } | |
491 fclose (fp); | |
492 return m; | |
493 } | |
494 |