~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to texk/dvipdfmx/dvipdfmx-20110311/src/dpxutil.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-05-07 10:47:49 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20120507104749-p00ot5sajjbkp1hp
Tags: 2011.20120507-1
* new upstream checkout: uptex 1.10
* drop patches for config file inclusion in (x)dvipdfmx, included upstream
* add man page for etex
* include pmpost patches and build it
* adapt/unfuzzify patches for current sources
* disable mtx building, we have prepmx package in Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  $Header: /home/cvsroot/dvipdfmx/src/dpxutil.c,v 1.14 2011/03/06 03:14:13 chofchof Exp $
2
 
 
3
 
    This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
4
 
 
5
 
    Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
6
 
    the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
7
 
 
8
 
    Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
9
 
 
10
 
    This program is free software; you can redistribute it and/or modify
11
 
    it under the terms of the GNU General Public License as published by
12
 
    the Free Software Foundation; either version 2 of the License, or
13
 
    (at your option) any later version.
14
 
 
15
 
    This program is distributed in the hope that it will be useful,
16
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
    GNU General Public License for more details.
19
 
 
20
 
    You should have received a copy of the GNU General Public License
21
 
    along with this program; if not, write to the Free Software
22
 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23
 
*/
24
 
 
25
 
#include <stdarg.h>
26
 
#include <stdio.h>
27
 
#include <stdlib.h>
28
 
#include <string.h>
29
 
#include <time.h>
30
 
 
31
 
#include "system.h"
32
 
#include "mem.h"
33
 
#include "error.h"
34
 
 
35
 
#include "dpxutil.h"
36
 
 
37
 
int
38
 
xtoi (char c)
39
 
{
40
 
  if (c >= '0' && c <= '9')
41
 
    return (c - '0');
42
 
  else if (c >= 'a' && c <= 'f')
43
 
    return (c - 'W');
44
 
  else if (c >= 'A' && c <= 'F')
45
 
    return (c - '7');
46
 
  else
47
 
    return -1;
48
 
}
49
 
 
50
 
int
51
 
sputx (unsigned char c, char **s, char *end)
52
 
{
53
 
  char hi = (c >> 4), lo = c & 0x0f;
54
 
 
55
 
  if (*s + 2 > end)
56
 
    ERROR("Buffer overflow.");
57
 
  **s = (hi < 10) ? hi + '0' : hi + '7';
58
 
  *(*s+1) = (lo < 10) ? lo + '0' : lo + '7';
59
 
  *s += 2;
60
 
 
61
 
  return 2;
62
 
}
63
 
 
64
 
int
65
 
getxpair (unsigned char **s)
66
 
{
67
 
  int hi, lo;
68
 
  hi = xtoi(**s);
69
 
  if (hi < 0)
70
 
    return hi;
71
 
  (*s)++;
72
 
  lo = xtoi(**s);
73
 
  if (lo < 0)
74
 
    return lo;
75
 
  (*s)++;
76
 
  return ((hi << 4)| lo);
77
 
}
78
 
 
79
 
int
80
 
putxpair (unsigned char c, char **s)
81
 
{
82
 
  char hi = (c >> 4), lo = c & 0x0f;
83
 
 
84
 
  **s = (hi < 10) ? hi + '0' : hi + '7';
85
 
  *(*s+1) = (lo < 10) ? lo + '0' : lo + '7';
86
 
  *s += 2;
87
 
 
88
 
  return 2;
89
 
}
90
 
 
91
 
/* Overflowed value is set to invalid char.  */
92
 
unsigned char
93
 
ostrtouc (unsigned char **inbuf, unsigned char *inbufend, unsigned char *valid)
94
 
{
95
 
  unsigned char *cur = *inbuf;
96
 
  unsigned int   val = 0;
97
 
 
98
 
  while (cur < inbufend && cur < *inbuf + 3 &&
99
 
         (*cur >= '0' && *cur <= '7')) {
100
 
    val = (val << 3) | (*cur - '0');
101
 
    cur++;
102
 
  }
103
 
  if (val > 255 || cur == *inbuf)
104
 
    *valid = 0;
105
 
  else
106
 
    *valid = 1;
107
 
 
108
 
  *inbuf = cur;
109
 
  return (unsigned char) val;
110
 
}
111
 
 
112
 
unsigned char
113
 
esctouc (unsigned char **inbuf, unsigned char *inbufend, unsigned char *valid)
114
 
{
115
 
  unsigned char unescaped, escaped;
116
 
 
117
 
  escaped = **inbuf;
118
 
  *valid    = 1;
119
 
  switch (escaped) {
120
 
    /* Backslash, unbalanced paranthes */
121
 
  case '\\': case ')': case '(':
122
 
    unescaped = escaped;
123
 
    (*inbuf)++;
124
 
    break;
125
 
    /* Other escaped char */ 
126
 
  case 'n': unescaped = '\n'; (*inbuf)++; break;
127
 
  case 'r': unescaped = '\r'; (*inbuf)++; break;
128
 
  case 't': unescaped = '\t'; (*inbuf)++; break;
129
 
  case 'b': unescaped = '\b'; (*inbuf)++; break;
130
 
  case 'f': unescaped = '\f'; (*inbuf)++; break;
131
 
    /*
132
 
     * An end-of-line marker preceeded by backslash is not part of a
133
 
     * literal string
134
 
     */
135
 
  case '\r':
136
 
    unescaped = 0;
137
 
    *valid    = 0;
138
 
    *inbuf   += (*inbuf < inbufend - 1 && *(*inbuf+1) == '\n') ? 2 : 1;
139
 
    break;
140
 
  case '\n':
141
 
    unescaped = 0;
142
 
    *valid    = 0;
143
 
    (*inbuf)++;
144
 
    break;
145
 
    /* Possibly octal notion */ 
146
 
  default:
147
 
    unescaped = ostrtouc(inbuf, inbufend, valid);
148
 
  }
149
 
 
150
 
  return unescaped;
151
 
}
152
 
 
153
 
void
154
 
skip_white_spaces (unsigned char **s, unsigned char *endptr)
155
 
{
156
 
  while (*s < endptr)
157
 
    if (!is_space(**s))
158
 
      break;
159
 
    else
160
 
      (*s)++;
161
 
}
162
 
 
163
 
void
164
 
ht_init_table (struct ht_table *ht, void (*hval_free_fn) (void *))
165
 
{
166
 
  int  i;
167
 
 
168
 
  ASSERT(ht);
169
 
 
170
 
  for (i = 0; i < HASH_TABLE_SIZE; i++) {
171
 
    ht->table[i] = NULL;
172
 
  }
173
 
  ht->count = 0;
174
 
  ht->hval_free_fn = hval_free_fn;
175
 
}
176
 
 
177
 
void
178
 
ht_clear_table (struct ht_table *ht)
179
 
{
180
 
  int   i;
181
 
 
182
 
  ASSERT(ht);
183
 
 
184
 
  for (i = 0; i < HASH_TABLE_SIZE; i++) {
185
 
    struct ht_entry *hent, *next;
186
 
 
187
 
    hent = ht->table[i];
188
 
    while (hent) {
189
 
      if (hent->value && ht->hval_free_fn) {
190
 
        ht->hval_free_fn(hent->value);
191
 
      }
192
 
      hent->value  = NULL;
193
 
      if (hent->key) {
194
 
        RELEASE(hent->key);
195
 
      }
196
 
      hent->key = NULL;
197
 
      next = hent->next;
198
 
      RELEASE(hent);
199
 
      hent = next;
200
 
    }
201
 
    ht->table[i] = NULL;
202
 
  }
203
 
  ht->count = 0;
204
 
  ht->hval_free_fn = NULL;
205
 
}
206
 
 
207
 
long ht_table_size (struct ht_table *ht)
208
 
{
209
 
  ASSERT(ht);
210
 
 
211
 
  return ht->count;
212
 
}
213
 
 
214
 
static unsigned int
215
 
get_hash (const void *key, int keylen)
216
 
{
217
 
  unsigned int hkey = 0;
218
 
  int      i;
219
 
 
220
 
  for (i = 0; i < keylen; i++) {
221
 
    hkey = (hkey << 5) + hkey + ((const char *)key)[i];
222
 
  }
223
 
 
224
 
  return (hkey % HASH_TABLE_SIZE);
225
 
}
226
 
 
227
 
void *
228
 
ht_lookup_table (struct ht_table *ht, const void *key, int keylen)
229
 
{
230
 
  struct ht_entry *hent;
231
 
  unsigned int     hkey;
232
 
 
233
 
  ASSERT(ht && key);
234
 
 
235
 
  hkey = get_hash(key, keylen);
236
 
  hent = ht->table[hkey];
237
 
  while (hent) {
238
 
    if (hent->keylen == keylen &&
239
 
        !memcmp(hent->key, key, keylen)) {
240
 
      return hent->value;
241
 
    }
242
 
    hent = hent->next;
243
 
  }
244
 
 
245
 
  return NULL;
246
 
}
247
 
 
248
 
int
249
 
ht_remove_table (struct ht_table *ht,
250
 
                 const void *key, int keylen)
251
 
/* returns 1 if the element was found and removed and 0 otherwise */
252
 
{
253
 
  struct ht_entry *hent, *prev;
254
 
  unsigned int     hkey;
255
 
 
256
 
  ASSERT(ht && key);
257
 
 
258
 
  hkey = get_hash(key, keylen);
259
 
  hent = ht->table[hkey];
260
 
  prev = NULL;
261
 
  while (hent) {
262
 
    if (hent->keylen == keylen &&
263
 
        !memcmp(hent->key, key, keylen)) {
264
 
      break;
265
 
    }
266
 
    prev = hent;
267
 
    hent = hent->next;
268
 
  }
269
 
  if (hent) {
270
 
    if (hent->key)
271
 
      RELEASE(hent->key);
272
 
    hent->key    = NULL;
273
 
    hent->keylen = 0;
274
 
    if (hent->value && ht->hval_free_fn) {
275
 
      ht->hval_free_fn(hent->value);
276
 
    }
277
 
    hent->value  = NULL;
278
 
    if (prev) {
279
 
      prev->next = hent->next;
280
 
    } else {
281
 
      ht->table[hkey] = hent->next;
282
 
    }
283
 
    RELEASE(hent);
284
 
    ht->count--;
285
 
    return 1;
286
 
  } else
287
 
    return 0;
288
 
}
289
 
 
290
 
void
291
 
ht_modify_table (struct ht_table *ht,
292
 
                 const void *key, int keylen, void *value, int mode)
293
 
{
294
 
  struct ht_entry *hent, *prev;
295
 
  unsigned int     hkey;
296
 
 
297
 
  ASSERT(ht && key);
298
 
 
299
 
  hkey = get_hash(key, keylen);
300
 
  hent = ht->table[hkey];
301
 
  prev = NULL;
302
 
  while (hent) {
303
 
    if (hent->keylen == keylen &&
304
 
        !memcmp(hent->key, key, keylen)) {
305
 
      break;
306
 
    }
307
 
    prev = hent;
308
 
    hent = hent->next;
309
 
  }
310
 
  if (hent) {
311
 
    switch (mode) {
312
 
    case HT_NEW:
313
 
      ASSERT(0); /* duplicates not allowed in this mode */
314
 
      break;
315
 
    case HT_REPLACE: {
316
 
      if (hent->value && ht->hval_free_fn)
317
 
        ht->hval_free_fn(hent->value);
318
 
      hent->value  = value;
319
 
      break;
320
 
    }
321
 
    case HT_KEEP:
322
 
      ht->hval_free_fn(value);
323
 
      break;
324
 
    }
325
 
  } else {
326
 
    hent = NEW(1, struct ht_entry);
327
 
    hent->key = NEW(keylen, char);
328
 
    memcpy(hent->key, key, keylen);
329
 
    hent->keylen = keylen;
330
 
    hent->value  = value;
331
 
    hent->next   = NULL;
332
 
    if (prev) {
333
 
      prev->next      = hent;
334
 
    } else {
335
 
      ht->table[hkey] = hent;
336
 
    }
337
 
    ht->count++;
338
 
  }
339
 
}
340
 
 
341
 
int
342
 
ht_set_iter (struct ht_table *ht, struct ht_iter *iter)
343
 
{
344
 
  int    i;
345
 
 
346
 
  ASSERT(ht && ht->table && iter);
347
 
 
348
 
  for (i = 0; i < HASH_TABLE_SIZE; i++) {
349
 
    if (ht->table[i]) {
350
 
      iter->index = i;
351
 
      iter->curr  = ht->table[i];
352
 
      iter->hash  = ht;
353
 
      return 0;
354
 
    }
355
 
  }
356
 
 
357
 
  return -1;
358
 
}
359
 
 
360
 
void
361
 
ht_clear_iter (struct ht_iter *iter)
362
 
{
363
 
  if (iter) {
364
 
    iter->index = HASH_TABLE_SIZE;
365
 
    iter->curr  = NULL;
366
 
    iter->hash  = NULL;
367
 
  }
368
 
}
369
 
 
370
 
char *
371
 
ht_iter_getkey (struct ht_iter *iter, int *keylen)
372
 
{
373
 
  struct ht_entry *hent;
374
 
 
375
 
  hent = (struct ht_entry *) iter->curr;
376
 
  if (iter && hent) {
377
 
    *keylen = hent->keylen;
378
 
    return hent->key;
379
 
  } else {
380
 
    *keylen = 0;
381
 
    return NULL;
382
 
  }
383
 
}
384
 
 
385
 
void *
386
 
ht_iter_getval (struct ht_iter *iter)
387
 
{
388
 
  struct ht_entry *hent;
389
 
 
390
 
  hent = (struct ht_entry *) iter->curr;
391
 
  if (iter && hent) {
392
 
    return hent->value;
393
 
  } else {
394
 
    return NULL;
395
 
  }
396
 
}
397
 
 
398
 
int
399
 
ht_iter_next (struct ht_iter *iter)
400
 
{
401
 
  struct ht_entry *hent;
402
 
  struct ht_table *ht;
403
 
 
404
 
  ASSERT(iter);
405
 
 
406
 
  ht   = iter->hash;
407
 
  hent = (struct ht_entry *) iter->curr;
408
 
  hent = hent->next;
409
 
  while (!hent &&
410
 
         ++iter->index < HASH_TABLE_SIZE) {
411
 
    hent = ht->table[iter->index];
412
 
  }
413
 
  iter->curr = hent;
414
 
 
415
 
  return (hent ? 0 : -1);
416
 
}
417
 
 
418
 
 
419
 
static int
420
 
read_c_escchar (char *r, const char **pp, const char *endptr)
421
 
{
422
 
  int   c = 0, l = 1;
423
 
  const char *p = *pp;
424
 
 
425
 
  switch (p[0]) {
426
 
  case 'a' : c = '\a'; p++; break;
427
 
  case 'b' : c = '\b'; p++; break;
428
 
  case 'f' : c = '\f'; p++; break;
429
 
  case 'n' : c = '\n'; p++; break;
430
 
  case 'r' : c = '\r'; p++; break;
431
 
  case 't' : c = '\t'; p++; break;
432
 
  case 'v' : c = '\v'; p++; break;
433
 
  case '\\': case '?': case '\'': case '\"':
434
 
    c = p[0]; p++;
435
 
    break;
436
 
  case '\n': l = 0; p++; break;
437
 
  case '\r':
438
 
    {
439
 
      p++;
440
 
      if (p < endptr && p[0] == '\n')
441
 
        p++;
442
 
      l = 0;
443
 
    }
444
 
    break;
445
 
  case '0': case '1': case '2': case '3':
446
 
  case '4': case '5': case '6': case '7':
447
 
    {
448
 
      int  i;
449
 
      for (c = 0, i = 0;
450
 
           i < 3 && p < endptr &&
451
 
           p[0] >= '0' && p[0] <= '7'; i++, p++)
452
 
        c = (c << 3) + (p[0] - '0');
453
 
    }
454
 
    break;
455
 
  case 'x':
456
 
    {
457
 
      int  i;
458
 
      for (c = 0, i = 0, p++;
459
 
           i < 2 && p < endptr && isxdigit(p[0]);
460
 
           i++, p++)
461
 
        c = (c << 4) +
462
 
            (isdigit(p[0]) ?
463
 
             p[0] - '0' :
464
 
             (islower(p[0]) ? p[0] - 'a' + 10: p[0] - 'A' + 10));
465
 
    }
466
 
    break;
467
 
  default:
468
 
    WARN("Unknown escape char sequence: \\%c", p[0]);
469
 
    l = 0; p++;
470
 
    break;
471
 
  }
472
 
 
473
 
  if (r)
474
 
    *r = (char) c;
475
 
  *pp  = p;
476
 
  return  l;
477
 
}
478
 
 
479
 
#define C_QUOTE  '"'
480
 
#define C_ESCAPE '\\'
481
 
static int
482
 
read_c_litstrc (char *q, int len, const char **pp, const char *endptr)
483
 
{
484
 
  const char *p;
485
 
  int    l = 0;
486
 
#define Q_TERM          0
487
 
#define Q_CONT         -1
488
 
#define Q_ERROR_UNTERM -1
489
 
#define Q_ERROR_INVAL  -2
490
 
#define Q_ERROR_BUFF   -3
491
 
  int    s = Q_CONT;
492
 
 
493
 
  for (l = 0, p = *pp;
494
 
       s == Q_CONT && p < endptr; ) {
495
 
    switch (p[0]) {
496
 
    case C_QUOTE:
497
 
      s = Q_TERM; p++;
498
 
      break;
499
 
    case C_ESCAPE:
500
 
      if (q && l == len)
501
 
        s = Q_ERROR_BUFF;
502
 
      else {
503
 
        p++;
504
 
        l += read_c_escchar(q ? &q[l] : NULL, &p, endptr);
505
 
      }
506
 
      break;
507
 
    case '\n': case '\r':
508
 
      s = Q_ERROR_INVAL;
509
 
      break;
510
 
    default:
511
 
      if (q && l == len)
512
 
        s = Q_ERROR_BUFF;
513
 
      else {
514
 
        if (!q)
515
 
          l++;
516
 
        else
517
 
          q[l++] = p[0];
518
 
        p++;
519
 
      }
520
 
      break;
521
 
    }
522
 
  }
523
 
  if (s == Q_TERM) {
524
 
    if (q && l == len)
525
 
      s = Q_ERROR_BUFF;
526
 
    else if (q)
527
 
      q[l++] = '\0';
528
 
  }
529
 
 
530
 
  *pp = p;
531
 
  return ((s == Q_TERM) ? l : s);
532
 
}
533
 
 
534
 
char *
535
 
parse_c_string (const char **pp, const char *endptr)
536
 
{
537
 
  char  *q = NULL;
538
 
  const char *p = *pp;
539
 
  int    l = 0;
540
 
 
541
 
  if (p >= endptr || p[0] != C_QUOTE)
542
 
    return NULL;
543
 
 
544
 
  p++;
545
 
  l = read_c_litstrc(NULL, 0, &p, endptr);
546
 
  if (l >= 0) {
547
 
    q = NEW(l + 1, char);
548
 
    p = *pp + 1;
549
 
    l = read_c_litstrc(q, l + 1, &p, endptr);
550
 
  }
551
 
 
552
 
  *pp = p;
553
 
  return  q;
554
 
}
555
 
 
556
 
#define ISCNONDIGITS(c) ( \
557
 
  (c) == '_' || \
558
 
  ((c) >= 'a' && (c) <= 'z') || \
559
 
  ((c) >= 'A' && (c) <= 'Z') \
560
 
)
561
 
#define ISCIDENTCHAR(c) ( \
562
 
  ISCNONDIGITS((c)) || \
563
 
  ((c) >= '0' && (c) <= '9') \
564
 
)
565
 
 
566
 
char *
567
 
parse_c_ident (const char **pp, const char *endptr)
568
 
{
569
 
  char  *q = NULL;
570
 
  const char *p = *pp;
571
 
  int    n;
572
 
 
573
 
  if (p >= endptr || !ISCNONDIGITS(*p))
574
 
    return NULL;
575
 
 
576
 
  for (n = 0; p < endptr && ISCIDENTCHAR(*p); p++, n++);
577
 
  q = NEW(n + 1, char);
578
 
  memcpy(q, *pp, n); q[n] = '\0';
579
 
 
580
 
  *pp = p;
581
 
  return  q;
582
 
}
583
 
 
584
 
char *
585
 
parse_float_decimal (const char **pp, const char *endptr)
586
 
{
587
 
  char  *q = NULL;
588
 
  const char *p = *pp;
589
 
  int    s = 0, n = 0;
590
 
 
591
 
  if (p >= endptr)
592
 
    return NULL;
593
 
 
594
 
  if (p[0] == '+' || p[0] == '-')
595
 
    p++;
596
 
 
597
 
  /* 1. .01 001 001E-001 */
598
 
  for (s = 0, n = 0; p < endptr && s >= 0; ) {
599
 
    switch (p[0]) {
600
 
    case '+': case '-':
601
 
      if (s != 2)
602
 
        s = -1;
603
 
      else {
604
 
        s = 3; p++;
605
 
      }
606
 
      break;
607
 
    case '.':
608
 
      if (s > 0)
609
 
        s = -1;
610
 
      else {
611
 
        s =  1; p++;
612
 
      }
613
 
      break;
614
 
    case '0': case '1': case '2': case '3': case '4':
615
 
    case '5': case '6': case '7': case '8': case '9':
616
 
      n++; p++;
617
 
      break;
618
 
    case 'E': case 'e':
619
 
      if (n == 0 || s == 2)
620
 
        s = -1;
621
 
      else {
622
 
        s = 2; p++;
623
 
      }
624
 
      break;
625
 
    default:
626
 
      s = -1;
627
 
      break;
628
 
    }
629
 
  }
630
 
 
631
 
  if (n != 0) {
632
 
    n = (int) (p - *pp);
633
 
    q = NEW(n + 1, char);
634
 
    memcpy(q, *pp, n); q[n] = '\0';
635
 
  }
636
 
 
637
 
  *pp = p;
638
 
  return  q;
639
 
}