Bug Summary

File:ucs2any.c
Location:line 749, column 7
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*-
2 * Copyright (c) 2003 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Ben Collver <collver1@attbi.com>.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * This utility allows you to generate from an ISO10646-1 encoded
31 * BDF font other BDF fonts in any possible encoding. This way, you can
32 * derive from a single ISO10646-1 master font a whole set of 8-bit
33 * fonts in all ISO 8859 and various other encodings. (Hopefully
34 * a future XFree86 release will have a similar facility built into
35 * the server, which can reencode ISO10646-1 on the fly, because
36 * storing the same fonts in many different encodings is clearly
37 * a waste of storage capacity).
38*/
39
40#include <ctype.h>
41#include <errno(*__errno_location ()).h>
42#include <fcntl.h>
43#if !defined(NEED_BASENAME) && !defined(Lynx)
44#include <libgen.h>
45#endif
46#include <limits.h>
47#include <stdarg.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <unistd.h>
52
53/* global variable for argv[0] */
54static const char *my_name = NULL((void*)0);
55
56#ifdef NEED_BASENAME
57static char *
58basename__xpg_basename(char *pathname)
59{
60 char *ptr;
61
62 ptr = strrchr(pathname, '/');
63 return ((ptr == NULL((void*)0)) ? pathname : &ptr[1]);
64}
65#endif
66
67/* "CLASS" "z" string and memory manipulation */
68
69static void *
70zmalloc(size_t size)
71{
72 void *r;
73 r = malloc(size);
74 if (r == NULL((void*)0)) {
75 perror(my_name);
76 exit(errno(*__errno_location ()));
77 }
78 memset(r, 0, size);
79 return r;
80}
81
82static void *
83zrealloc(void *ptr, size_t size)
84{
85 void *temp;
86 temp = realloc(ptr, size);
87 if (temp == NULL((void*)0)) {
88 perror(my_name);
89 exit(errno(*__errno_location ()));
90 }
91 return temp;
92}
93
94static char *
95zstrdup(const char *str)
96{
97 char *retval;
98
99 if (str == NULL((void*)0)) {
100 fprintf(stderrstderr, "%s: zstrdup(NULL)\n", my_name);
101 exit(1);
102 }
103 retval = strdup(str);
104 if (retval == NULL((void*)0)) {
105 perror(my_name);
106 exit(errno(*__errno_location ()));
107 }
108 return retval;
109}
110
111static void
112zstrcpy(char **dest, const char *source)
113{
114 if (*dest != NULL((void*)0))
115 free(*dest);
116 *dest = zstrdup(source);
117}
118
119static void
120zquotedcpy(char **dest, const char *source)
121{
122 const char *start, *end;
123
124 if (*dest != NULL((void*)0))
125 free(*dest);
126 *dest = NULL((void*)0);
127 start = source;
128 if (*start == '"') {
129 start = source+1;
130 end = strrchr(start, '"');
131 if (!end) return;
132 *dest = zmalloc(end-start+1);
133 strncpy(*dest, start, end-start);
134 (*dest)[end-start] = '\0';
135 } else {
136 *dest = zstrdup(source);
137 }
138}
139
140static void
141zstrcat(char **dest, const char *source)
142{
143 int dest_size = 1;
144 int source_size;
145
146 if (*dest != NULL((void*)0))
147 dest_size = strlen(*dest) + 1;
148 source_size = strlen(source);
149 *dest = zrealloc(*dest, dest_size + source_size);
150 strcpy(*dest + dest_size - 1, source);
151}
152
153static void
154zstrtoupper(char *s)
155{
156 char *t;
157
158 for (t = s; *t != '\000'; t++)
159 *t = toupper(*t);
160}
161
162#define zs_true(x)(x != ((void*)0) && strcmp(x, "0") != 0) (x != NULL((void*)0) && strcmp(x, "0") != 0)
163#define zi_true(x)(x == 1) (x == 1)
164
165/* "CLASS" "dynamic array" */
166
167typedef struct {
168 char *name;
169 int size;
170 int count;
171 void **values;
172 void *nv;
173} da_t;
174
175static da_t *
176da_new(const char *name)
177{
178 da_t *da;
179
180 da = zmalloc(sizeof(da_t));
181 da->size = 0;
182 da->count = 0;
183 da->values = NULL((void*)0);
184 da->nv = NULL((void*)0);
185 da->name = NULL((void*)0);
186 zstrcpy(&(da->name), name);
187 return da;
188}
189
190static void *
191da_fetch(da_t *da, int key)
192{
193 void *r = NULL((void*)0);
194
195 if (key >= 0 && key < da->size && da->values[key] != NULL((void*)0))
196 r = da->values[key];
197 else
198 if (key == -1 && da->nv != NULL((void*)0))
199 r = da->nv;
200
201 return r;
202}
203
204static int
205da_fetch_int(da_t *da, int key)
206{
207 int *t;
208 int r = -1;
209 t = da_fetch(da, key);
210 if (t != NULL((void*)0))
211 r = *t;
212 return r;
213}
214
215#define da_fetch_str(a,k)(char *)da_fetch(a,k) \
216 (char *)da_fetch(a,k)
217
218static void
219da_add(da_t *da, int key, void *value)
220{
221 int i = da->size;
222 if (key >= 0) {
223 if (key >= da->size) {
224 da->size = key + 1;
225 da->values = zrealloc(da->values,
226 da->size * sizeof(void *));
227 for (; i < da->size; i++)
228 da->values[i] = NULL((void*)0);
229 }
230 if (da->values[key] != NULL((void*)0)) {
231 free(da->values[key]);
232 } else {
233 if (value == NULL((void*)0)) {
234 if (da->count > 0)
235 da->count--;
236 } else {
237 da->count++;
238 }
239 }
240 da->values[key] = value;
241 } else if (key == -1) {
242 if (da->nv != NULL((void*)0))
243 free(da->nv);
244 da->nv = value;
245 }
246}
247
248static void
249da_add_str(da_t *da, int key, const char *value)
250{
251 da_add(da, key, value?zstrdup(value):NULL((void*)0));
252}
253
254static void
255da_add_int(da_t *da, int key, int value)
256{
257 int *v;
258
259 v = zmalloc(sizeof(int));
260 *v = value;
261 da_add(da, key, v);
262}
263
264#define da_count(da)(da->count) (da->count)
265#define da_size(da)(da->size) (da->size)
266
267static void
268da_clear(da_t *da)
269{
270 int i;
271
272 for (i = da->size; i; i--)
273 free(da->values[i]);
274 if (da->values != NULL((void*)0))
275 free(da->values);
276 da->size = 0;
277 da->count = 0;
278 da->values = NULL((void*)0);
279}
280
281/* "CLASS" file input */
282
283#define TYPICAL_LINE_SIZE(80) (80)
284
285/* read a line and strip trailing whitespace */
286static int
287read_line(FILE *fp, char **buffer)
288{
289 int buffer_size = TYPICAL_LINE_SIZE(80);
290 int eof = 0;
291 int position = 0;
292 int c;
293
294 *buffer = zmalloc(TYPICAL_LINE_SIZE(80));
295 (*buffer)[0] = '\0';
296
297 if ((c = getc(fp)_IO_getc (fp)) == EOF(-1))
298 eof = 1;
299
300 while (c != '\n' && !eof) {
301 if (position + 1 >= buffer_size) {
302 buffer_size = buffer_size * 2 + 1;
303 *buffer = zrealloc(*buffer, buffer_size);
304 }
305 (*buffer)[position++] = c;
306 (*buffer)[position] = '\0';
307 c = getc(fp)_IO_getc (fp);
308 if (c == EOF(-1))
309 eof = 1;
310 }
311
312 if (eof) {
313 free(*buffer);
314 *buffer = NULL((void*)0);
315 return 0;
316 }
317
318 while (position > 1) {
319 position--;
320 if (!isspace((*buffer)[position])((*__ctype_b_loc ())[(int) (((*buffer)[position]))] & (unsigned
short int) _ISspace)
)
321 break;
322 (*buffer)[position] = '\0';
323 }
324
325 return 1;
326}
327
328/* BEGIN */
329
330/*
331DEC VT100 graphics characters in the range 1-31 (as expected by
332some old xterm versions and a few other applications)
333*/
334#define decmap_size31 31
335static int decmap[decmap_size31] = {
336 0x25C6, /* BLACK DIAMOND */
337 0x2592, /* MEDIUM SHADE */
338 0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */
339 0x240C, /* SYMBOL FOR FORM FEED */
340 0x240D, /* SYMBOL FOR CARRIAGE RETURN */
341 0x240A, /* SYMBOL FOR LINE FEED */
342 0x00B0, /* DEGREE SIGN */
343 0x00B1, /* PLUS-MINUS SIGN */
344 0x2424, /* SYMBOL FOR NEWLINE */
345 0x240B, /* SYMBOL FOR VERTICAL TABULATION */
346 0x2518, /* BOX DRAWINGS LIGHT UP AND LEFT */
347 0x2510, /* BOX DRAWINGS LIGHT DOWN AND LEFT */
348 0x250C, /* BOX DRAWINGS LIGHT DOWN AND RIGHT */
349 0x2514, /* BOX DRAWINGS LIGHT UP AND RIGHT */
350 0x253C, /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
351 0x23BA, /* HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
352 0x23BB, /* HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
353 0x2500, /* BOX DRAWINGS LIGHT HORIZONTAL */
354 0x23BC, /* HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
355 0x23BD, /* HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
356 0x251C, /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
357 0x2524, /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */
358 0x2534, /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */
359 0x252C, /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
360 0x2502, /* BOX DRAWINGS LIGHT VERTICAL */
361 0x2264, /* LESS-THAN OR EQUAL TO */
362 0x2265, /* GREATER-THAN OR EQUAL TO */
363 0x03C0, /* GREEK SMALL LETTER PI */
364 0x2260, /* NOT EQUAL TO */
365 0x00A3, /* POUND SIGN */
366 0x00B7 /* MIDDLE DOT */
367};
368
369static int
370is_control(int ucs)
371{
372 return ((ucs >= 0x00 && ucs <= 0x1f) ||
373 (ucs >= 0x7f && ucs <= 0x9f));
374}
375
376static int
377is_blockgraphics(int ucs)
378{
379 return ucs >= 0x2500 && ucs <= 0x25FF;
380}
381
382/* calculate the bounding box that covers both provided bounding boxes */
383typedef struct {
384 int cwidth;
385 int cheight;
386 int cxoff;
387 int cyoff;
388} bbx_t;
389
390static bbx_t *
391combine_bbx(int awidth, int aheight, int axoff, int ayoff,
392 int cwidth, int cheight, int cxoff, int cyoff, bbx_t *r)
393{
394 r->cwidth = cwidth;
395 r->cheight = cheight;
396 r->cxoff = cxoff;
397 r->cyoff = cyoff;
398
399 if (axoff < r->cxoff) {
400 r->cwidth += r->cxoff - axoff;
401 r->cxoff = axoff;
402 }
403 if (ayoff < r->cyoff) {
404 r->cheight += r->cyoff - ayoff;
405 r->cyoff = ayoff;
406 }
407 if (awidth + axoff > r->cwidth + r->cxoff) {
408 r->cwidth = awidth + axoff - r->cxoff;
409 }
410 if (aheight + ayoff > r->cheight + r->cyoff) {
411 r->cheight = aheight + ayoff - r->cyoff;
412 }
413
414 return r;
415}
416
417static void
418usage(void) {
419 printf("%s", "\n"
420"Usage: ucs2any [+d|-d] <source-name> { <mapping-file> <registry-encoding> }\n"
421"\n"
422"where\n"
423"\n"
424" +d put DEC VT100 graphics characters in the C0 range\n"
425" (default for upright charcell fonts)\n"
426"\n"
427" -d do not put DEC VT100 graphics characters in the\n"
428" C0 range (default for all other font types)\n"
429"\n"
430" <source-name> is the name of an ISO10646-1 encoded BDF file\n"
431"\n"
432" <mapping-file> is the name of a character set table like those on\n"
433" <ftp://ftp.unicode.org/Public/MAPPINGS/>\n"
434"\n"
435" <registry-encoding> are the CHARSET_REGISTRY and CHARSET_ENCODING\n"
436" field values for the font name (XLFD) of the\n"
437" target font, separated by a hyphen\n"
438"\n"
439"Example:\n"
440"\n"
441" ucs2any 6x13.bdf 8859-1.TXT iso8859-1 8859-2.TXT iso8859-2\n"
442"\n"
443"will generate the files 6x13-iso8859-1.bdf and 6x13-iso8859-2.bdf\n"
444"\n");
445}
446
447static int
448chars_compare(const void *aa, const void *bb)
449{
450 int a = *(const int *)aa;
451 int b = *(const int *)bb;
452
453 return a - b;
454}
455
456/*
457 * Return != 0 if "string" starts with "pattern" followed by whitespace.
458 * If it does, return a pointer to the first non space char.
459 */
460static const char *
461startswith(const char *string, const char *pattern)
462{
463 int l = strlen(pattern);
464
465 if (strlen(string) <= l) return NULL((void*)0);
466 if (strncmp(string, pattern, l) != 0) return NULL((void*)0);
467 string += l;
468 if (!isspace(*string)((*__ctype_b_loc ())[(int) ((*string))] & (unsigned short
int) _ISspace)
) return NULL((void*)0);
469 while (isspace(*string)((*__ctype_b_loc ())[(int) ((*string))] & (unsigned short
int) _ISspace)
)
470 string++;
471 return string;
472}
473
474int
475main(int argc, char *argv[])
476{
477 int ai = 1;
478 int dec_chars = -1;
479 char *fsource = NULL((void*)0);
480 FILE *fsource_fp;
481 int properties;
482 int default_char;
483 char *l = NULL((void*)0);
484 char *t = NULL((void*)0);
485 const char *nextc = NULL((void*)0);
486 char *startfont = NULL((void*)0);
487 char *slant = NULL((void*)0);
488 char *spacing = NULL((void*)0);
489 char *sc = NULL((void*)0);
490 int code = -1;
491 da_t *startchar;
492 da_t *my_char;
493 char *fmap = NULL((void*)0);
494 char *registry = NULL((void*)0);
495 char *encoding = NULL((void*)0);
496 char *fontname = NULL((void*)0);
497 FILE *fmap_fp;
498 da_t *map;
499 da_t *headers;
500 int nextheader = -1;
501 int default_char_index = -1;
502 int startproperties_index = -1;
503 int fontname_index = -1;
504 int charset_registry_index = -1;
505 int slant_index = -1;
506 int spacing_index = -1;
507 int charset_encoding_index = -1;
508 int fontboundingbox_index = -1;
509 int target;
510 int ucs;
511 int i;
512 int j;
513 int *chars = NULL((void*)0);
514 bbx_t bbx;
515 char *fout = NULL((void*)0);
516 FILE *fout_fp;
517 int k;
518 char *registry_encoding = NULL((void*)0);
519
520 my_name = argv[0];
521 bbx.cheight = bbx.cxoff = bbx.cyoff = -1;
522
523 startchar = da_new("startchar");
524 my_char = da_new("my_char");
525 map = da_new("map");
526 headers = da_new("headers");
527
528 if (argc < 2) {
1
Assuming 'argc' is >= 2
2
Taking false branch
529 usage();
530 exit(0);
531 }
532
533 /* check options */
534 if (strcmp(argv[ai], "+d") == 0) {
3
Taking false branch
535 ai++;
536 dec_chars = 1;
537 } else if (strcmp(argv[ai], "-d") == 0) {
4
Taking false branch
538 ai++;
539 dec_chars = 0;
540 }
541 if (ai >= argc) {
5
Taking false branch
542 usage();
543 exit(0);
544 }
545
546 /* open and read source file */
547 fsource = argv[ai];
548 fsource_fp = fopen(fsource, "r");
549 if (fsource_fp == NULL((void*)0)) {
6
Assuming 'fsource_fp' is not equal to null
7
Taking false branch
550 fprintf(stderrstderr, "%s: Can't read file '%s': %s!\n", my_name,
551 fsource, strerror(errno(*__errno_location ())));
552 exit(1);
553 }
554
555 /* read header */
556 properties = 0;
557 default_char = 0;
558 while (read_line(fsource_fp, &l)) {
8
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
34
Loop condition is true. Entering loop body
37
Loop condition is false. Execution continues on line 649
559 if (startswith(l, "CHARS"))
9
Taking false branch
22
Taking false branch
35
Taking false branch
560 break;
561 if (startswith(l, "STARTFONT")) {
10
Taking false branch
23
Taking false branch
36
Taking true branch
562 zstrcpy(&startfont, l);
563 } else if (startswith(l, "_XMBDFED_INFO") ||
11
Taking false branch
24
Taking false branch
564 startswith(l, "XFREE86_GLYPH_RANGES"))
565 {
566 properties--;
567 } else if ((nextc = startswith(l, "DEFAULT_CHAR")) != NULL((void*)0))
12
Taking false branch
25
Taking false branch
568 {
569 default_char = atoi(nextc);
570 default_char_index = ++nextheader;
571 da_add_str(headers, default_char_index, NULL((void*)0));
572 } else {
573 if ((nextc = startswith(l, "STARTPROPERTIES")) != NULL((void*)0))
13
Taking false branch
26
Taking false branch
574 {
575 properties = atoi(nextc);
576 startproperties_index = ++nextheader;
577 da_add_str(headers, startproperties_index, NULL((void*)0));
578 } else if ((nextc = startswith(l, "FONT")) != NULL((void*)0))
14
Taking false branch
27
Taking false branch
579 {
580 char * term;
581 /* slightly simplistic check ... */
582 zquotedcpy(&fontname, nextc);
583 if ((term = strstr(fontname, "-ISO10646-1")) == NULL((void*)0)) {
584 fprintf(stderrstderr,
585 "%s: FONT name in '%s' is '%s' and not '*-ISO10646-1'!\n",
586 my_name, fsource, fontname);
587 exit(1);
588 }
589 *term = '\0';
590 fontname_index = ++nextheader;
591 da_add_str(headers, fontname_index, NULL((void*)0));
592 } else if ((nextc = startswith(l, "CHARSET_REGISTRY")) != NULL((void*)0))
15
Taking false branch
28
Taking false branch
593 {
594 if (strcmp(nextc, "\"ISO10646\"") != 0) {
595 fprintf(stderrstderr,
596 "%s: CHARSET_REGISTRY in '%s' is '%s' and not 'ISO10646'!\n",
597 my_name, fsource, nextc);
598 exit(1);
599 }
600 charset_registry_index = ++nextheader;
601 da_add_str(headers, charset_registry_index, NULL((void*)0));
602 } else if ((nextc = startswith(l, "CHARSET_ENCODING")) != NULL((void*)0))
16
Taking false branch
29
Taking false branch
603 {
604 if (strcmp(nextc, "\"1\"") != 0) {
605 fprintf(stderrstderr,
606 "%s: CHARSET_ENCODING in '%s' is '%s' and not '1'!\n",
607 my_name, fsource, nextc);
608 exit(1);
609 }
610 charset_encoding_index = ++nextheader;
611 da_add_str(headers, charset_encoding_index, NULL((void*)0));
612 } else if (startswith(l, "FONTBOUNDINGBOX")) {
17
Taking false branch
30
Taking false branch
613 fontboundingbox_index = ++nextheader;
614 da_add_str(headers, fontboundingbox_index, NULL((void*)0));
615 } else if ((nextc = startswith(l, "SLANT")) != NULL((void*)0))
18
Taking false branch
31
Taking false branch
616 {
617 zquotedcpy(&slant, nextc);
618 slant_index = ++nextheader;
619 da_add_str(headers, slant_index, NULL((void*)0));
620 } else if ((nextc = startswith(l, "SPACING")) != NULL((void*)0))
19
Taking false branch
32
Taking false branch
621 {
622 zquotedcpy(&spacing, nextc);
623 zstrtoupper(spacing);
624 spacing_index = ++nextheader;
625 da_add_str(headers, spacing_index, NULL((void*)0));
626 } else if ((nextc = startswith(l, "COMMENT")) != NULL((void*)0)) {
20
Taking false branch
33
Taking false branch
627 if (strncmp(nextc, "$Id: ", 5)==0) {
628 char *header = NULL((void*)0);
629 char *id = NULL((void*)0), *end = NULL((void*)0);
630 id = zstrdup(nextc + 5);
631 end = strrchr(id, '$');
632 if (end) *end = '\0';
633 zstrcpy(&header, "COMMENT Derived from ");
634 zstrcat(&header, id);
635 zstrcat(&header, "\n");
636 free(id);
637 da_add_str(headers, ++nextheader, header);
638 free(header);
639 } else {
640 da_add_str(headers, ++nextheader, l);
641 }
642 } else {
643 da_add_str(headers, ++nextheader, l);
644 }
645 }
646 free(l);
647 }
648
649 if (startfont == NULL((void*)0)) {
38
Assuming 'startfont' is not equal to null
39
Taking false branch
650 fprintf(stderrstderr, "%s: No STARTFONT line found in '%s'!\n",
651 my_name, fsource);
652 exit(1);
653 }
654
655 /* read characters */
656 while (read_line(fsource_fp, &l)) {
40
Loop condition is false. Execution continues on line 681
657 if (startswith(l, "STARTCHAR")) {
658 zstrcpy(&sc, l);
659 zstrcat(&sc, "\n");
660 code = -1;
661 } else if ((nextc = startswith(l, "ENCODING")) != NULL((void*)0)) {
662 code = atoi(nextc);
663 da_add_str(startchar, code, sc);
664 da_add_str(my_char, code, "");
665 } else if (strcmp(l, "ENDFONT")==0) {
666 code = -1;
667 zstrcpy(&sc, "STARTCHAR ???\n");
668 } else {
669 zstrcpy(&t, da_fetch_str(my_char, code)(char *)da_fetch(my_char,code));
670 zstrcat(&t, l);
671 zstrcat(&t, "\n");
672 da_add_str(my_char, code, t);
673 if (strcmp(l, "ENDCHAR")==0) {
674 code = -1;
675 zstrcpy(&sc, "STARTCHAR ???\n");
676 }
677 }
678 free(l);
679 }
680
681 fclose(fsource_fp);
682
683 ai++;
684 while (ai < argc) {
41
Assuming 'ai' is < 'argc'
42
Loop condition is true. Entering loop body
685 zstrcpy(&fmap, argv[ai]);
686 i = ai + 1;
687 if (i < argc) {
43
Assuming 'i' is < 'argc'
44
Taking true branch
688 char *temp = NULL((void*)0);
689 char * hyphen = strchr(argv[i], '-');
690 if (!hyphen || strchr(hyphen+1, '-') != NULL((void*)0)) {
45
Assuming 'hyphen' is non-null
46
Taking false branch
691 fprintf(stderrstderr,
692 "%s: Argument registry-encoding '%s' not in expected format!\n",
693 my_name, i < argc ? fmap : "");
694 exit(1);
695 }
696 temp = zstrdup(argv[i]);
697 hyphen = strchr(temp, '-');
698 if (hyphen) *hyphen = 0;
47
Assuming 'hyphen' is null
48
Taking false branch
699 zstrcpy(&registry, temp);
700 zstrcpy(&encoding, hyphen+1);
701 free(temp);
702 } else {
703 fprintf(stderrstderr, "map file argument \"%s\" needs a "
704 "coresponding registry-encoding argument\n", fmap);
705 exit(0);
706 }
707
708 ai++;
709 ai++;
710
711 /* open and read source file */
712 fmap_fp = fopen(fmap, "r");
713 if (fmap_fp == NULL((void*)0)) {
49
Assuming 'fmap_fp' is not equal to null
50
Taking false branch
714 fprintf(stderrstderr,
715 "%s: Can't read mapping file '%s': %s!\n",
716 my_name, fmap, strerror(errno(*__errno_location ())));
717 exit(1);
718 }
719
720 da_clear(map);
721
722 for (;read_line(fmap_fp, &l); free(l)) {
51
Loop condition is true. Entering loop body
56
Loop condition is true. Entering loop body
61
Loop condition is true. Entering loop body
723 char *p, *endp;
724
725 for (p = l; isspace(p[0])((*__ctype_b_loc ())[(int) ((p[0]))] & (unsigned short int
) _ISspace)
; p++)
52
Loop condition is false. Execution continues on line 727
57
Loop condition is false. Execution continues on line 727
62
Loop condition is false. Execution continues on line 727
726 ;
727 if (p[0] == '\0' || p[0] == '#')
53
Taking false branch
58
Taking false branch
63
Taking false branch
728 continue;
729 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
54
Taking false branch
59
Taking false branch
64
Taking true branch
730 target = strtol(p+2, &endp, 16);
731 if (*endp == '\0') goto bad;
65
Taking false branch
732 p = endp;
733 } else
734 goto bad;
55
Control jumps to line 760
60
Control jumps to line 760
735 for (; isspace(p[0])((*__ctype_b_loc ())[(int) ((p[0]))] & (unsigned short int
) _ISspace)
; p++)
66
Loop condition is false. Execution continues on line 737
736 ;
737 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
67
Taking true branch
738 ucs = strtol(p+2, &endp, 16);
739 if (*endp == '\0') goto bad;
68
Taking false branch
740 } else
741 goto bad;
742
743 if (!is_control(ucs)) {
69
Taking true branch
744 if (zs_true(da_fetch_str(startchar, ucs))((char *)da_fetch(startchar,ucs) != ((void*)0) && strcmp
((char *)da_fetch(startchar,ucs), "0") != 0)
)
70
Taking false branch
745 {
746 da_add_int(map, target, ucs);
747 } else {
748 if (!((is_blockgraphics(ucs) &&
749 strcmp(slant, "R") != 0) ||
71
Null pointer passed as an argument to a 'nonnull' parameter
750 (ucs >= 0x200e &&
751 ucs <= 0x200f))) {
752 fprintf(stderrstderr,
753 "No glyph for character U+%04X (0x%02x) available.\n",
754 ucs, target);
755 }
756 }
757 }
758 continue;
759 bad:
760 fprintf(stderrstderr, "Unrecognized line in '%s':\n%s\n", fmap, l);
761 }
762 fclose(fmap_fp);
763
764 /* add default character */
765 if (!zi_true(da_fetch_int(map, 0))(da_fetch_int(map, 0) == 1)) {
766 if (zs_true(da_fetch_str(startchar, default_char))((char *)da_fetch(startchar,default_char) != ((void*)0) &&
strcmp((char *)da_fetch(startchar,default_char), "0") != 0)
) {
767 da_add_int(map, 0, default_char);
768 da_add_str(startchar, default_char,
769 "STARTCHAR defaultchar\n");
770 } else {
771 fprintf(stderrstderr, "%s",
772 "No default character defined.\n");
773 }
774 }
775
776 if (dec_chars == 1 ||
777 (dec_chars == -1 && strcmp(slant, "R") == 0 &&
778 strcmp(spacing, "C") == 0))
779 {
780 /* add DEC VT100 graphics characters in the range 1-31
781 (as expected by some old xterm versions) */
782 for (i = 0; i < decmap_size31; i++) {
783 if (zs_true(da_fetch_str(startchar, decmap[i]))((char *)da_fetch(startchar,decmap[i]) != ((void*)0) &&
strcmp((char *)da_fetch(startchar,decmap[i]), "0") != 0)
)
784 {
785 da_add_int(map, i + 1, decmap[i]);
786 }
787 }
788 }
789
790 /* list of characters that will be written out */
791 j = da_count(map)(map->count);
792 if (j < 0) {
793 fprintf(stderrstderr,
794 "No characters found for %s-%s.\n",
795 registry, encoding);
796 continue;
797 }
798 if (chars != NULL((void*)0))
799 free(chars);
800 chars = zmalloc(j * sizeof(int));
801 memset(chars, 0, j * sizeof(int));
802 for (k = 0, i = 0; k < da_count(map)(map->count) && i < da_size(map)(map->size); i++) {
803 if (da_fetch(map, i) != NULL((void*)0))
804 chars[k++] = i;
805 }
806 qsort(chars, j, sizeof(int), chars_compare);
807
808 /* find overall font bounding box */
809 bbx.cwidth = -1;
810 for (i = 0; i < j; i++) {
811 ucs = da_fetch_int(map, chars[i]);
812 zstrcpy(&t, da_fetch_str(my_char, ucs)(char *)da_fetch(my_char,ucs));
813 if ((nextc = startswith(t, "BBX")) != NULL((void*)0)
814 || (nextc = strstr(t, "\nBBX")) != NULL((void*)0))
815 {
816 char *endp;
817 long w, h, x, y;
818
819 if (*nextc == '\n') {
820 nextc += 4;
821 while (isspace(*nextc)((*__ctype_b_loc ())[(int) ((*nextc))] & (unsigned short int
) _ISspace)
)
822 nextc++;
823 }
824 for (;isspace(*nextc)((*__ctype_b_loc ())[(int) ((*nextc))] & (unsigned short int
) _ISspace)
;)
825 nextc++;
826 w = strtol(nextc, &endp, 10);
827 nextc = endp;
828 if (*nextc == '\0') goto bbxbad;
829 for (;isspace(*nextc)((*__ctype_b_loc ())[(int) ((*nextc))] & (unsigned short int
) _ISspace)
;)
830 nextc++;
831 h = strtol(nextc, &endp, 10);
832 nextc = endp;
833 if (*nextc == '\0') goto bbxbad;
834 for (;isspace(*nextc)((*__ctype_b_loc ())[(int) ((*nextc))] & (unsigned short int
) _ISspace)
;)
835 nextc++;
836 x = strtol(nextc, &endp, 10);
837 nextc = endp;
838 if (*nextc == '\0') goto bbxbad;
839 for (;isspace(*nextc)((*__ctype_b_loc ())[(int) ((*nextc))] & (unsigned short int
) _ISspace)
;)
840 nextc++;
841 y = strtol(nextc, &endp, 10);
842 if (bbx.cwidth == -1) {
843 bbx.cwidth = w;
844 bbx.cheight = h;
845 bbx.cxoff = x;
846 bbx.cyoff = y;
847 } else {
848 combine_bbx(bbx.cwidth, bbx.cheight,
849 bbx.cxoff, bbx.cyoff,
850 w, h, x, y, &bbx);
851 }
852 continue;
853 bbxbad:
854 fprintf(stderrstderr, "Unparsable BBX found for U+%04x!\n", ucs);
855 } else {
856 fprintf(stderrstderr,
857 "Warning: No BBX found for U+%04X!\n",
858 ucs);
859 }
860 }
861
862 if (!registry) registry = zstrdup("");
863 if (!encoding) encoding = zstrdup("");
864
865 /* generate output file name */
866 zstrcpy(&registry_encoding, "-");
867 zstrcat(&registry_encoding, registry);
868 zstrcat(&registry_encoding, "-");
869 zstrcat(&registry_encoding, encoding);
870
871 {
872 char * p = strstr(fsource, ".bdf");
873 if (p) {
874 zstrcpy(&fout, fsource);
875 p = strstr(fout, ".bdf");
876 *p = 0;
877 zstrcat(&fout, registry_encoding);
878 zstrcat(&fout, ".bdf");
879 } else {
880 zstrcpy(&fout, fsource);
881 zstrcat(&fout, registry_encoding);
882 }
883 }
884
885 /* remove path prefix */
886 zstrcpy(&t, basename__xpg_basename(fout));
887 zstrcpy(&fout, t);
888
889 /* write new BDF file */
890 fprintf(stderrstderr, "Writing %d characters into file '%s'.\n",
891 j, fout);
892 fout_fp = fopen(fout, "w");
893 if (fout_fp == NULL((void*)0)) {
894 fprintf(stderrstderr, "%s: Can't write file '%s': %s!\n",
895 my_name, fout, strerror(errno(*__errno_location ())));
896 exit(1);
897 }
898
899 fprintf(fout_fp, "%s\n", startfont);
900 fprintf(fout_fp, "%s",
901 "COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT!\n");
902 fprintf(fout_fp,
903 "COMMENT Generated with 'ucs2any %s %s %s-%s'\n",
904 fsource, fmap, registry, encoding);
905 fprintf(fout_fp, "%s",
906 "COMMENT from an ISO10646-1 encoded source BDF font.\n");
907 fprintf(fout_fp, "%s",
908 "COMMENT ucs2any by Ben Collver <collver1@attbi.com>, 2003, based on\n");
909 fprintf(fout_fp, "%s",
910 "COMMENT ucs2any.pl by Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/>, 2000.\n");
911
912 for (i = 0; i <= nextheader; i++) {
913 if (i == default_char_index)
914 fprintf(fout_fp, "DEFAULT_CHAR %d\n", default_char);
915 else if (i == startproperties_index)
916 fprintf(fout_fp, "STARTPROPERTIES %d\n", properties);
917 else if (i == fontname_index) {
918 fprintf(fout_fp, "FONT %s%s\n", fontname, registry_encoding);
919 }
920 else if (i == charset_registry_index)
921 fprintf(fout_fp, "CHARSET_REGISTRY \"%s\"\n", registry);
922 else if (i == slant_index)
923 fprintf(fout_fp, "SLANT \"%s\"\n", slant);
924 else if (i == charset_encoding_index)
925 fprintf(fout_fp, "CHARSET_ENCODING \"%s\"\n", encoding);
926 else if (i == fontboundingbox_index)
927 fprintf(fout_fp, "FONTBOUNDINGBOX %d %d %d %d\n", bbx.cwidth, bbx.cheight, bbx.cxoff, bbx.cyoff);
928 else if (i == spacing_index)
929 fprintf(fout_fp, "SPACING \"%s\"\n", spacing);
930 else
931 fprintf(fout_fp, "%s\n", da_fetch_str(headers, i)(char *)da_fetch(headers,i));
932 }
933
934 fprintf(fout_fp, "CHARS %d\n", j);
935
936 /* Write characters */
937 for (i = 0; i < j; i++) {
938 ucs = da_fetch_int(map, chars[i]);
939 fprintf(fout_fp, "%s", da_fetch_str(startchar,(char *)da_fetch(startchar,ucs)
940 ucs)(char *)da_fetch(startchar,ucs));
941 fprintf(fout_fp, "ENCODING %d\n", chars[i]);
942 fprintf(fout_fp, "%s", da_fetch_str(my_char,(char *)da_fetch(my_char,ucs)
943 ucs)(char *)da_fetch(my_char,ucs));
944 }
945 fprintf(fout_fp, "%s", "ENDFONT\n");
946 fclose(fout_fp);
947 }
948
949 exit(0);
950}