OSDN Git Service

fd3dab66678c944e29b0cc180f10d30ddf29e421
[putex/putex.git] / src / dvipdfmx-pu / src / pst.c
1 /*  
2
3     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
4
5     Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6     the dvipdfmx project team.
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 <string.h>
26 #include <ctype.h>
27
28 #include "system.h"
29 #include "mem.h"
30 #include "error.h"
31 #include "dpxutil.h"
32 #include "pst_obj.h"
33 #include "pst.h"
34
35
36 #define TYPE_CHECK(o, t) do { \
37                              if ((o) == NULL || pst_type_of((o)) != (t)) \
38                                   ERROR("typecheck: object %p not of type %d.", (o), (t)); \
39                              } while (0)
40
41 static pst_obj *
42 pst_parse_any (unsigned char **inbuf, unsigned char *inbufend)
43 {
44   unsigned char *data;
45   unsigned char *cur = *inbuf;
46   unsigned long  len;
47
48   while (cur < inbufend && !PST_TOKEN_END(cur, inbufend))
49     cur++;
50
51   len = cur - (*inbuf);
52   data = NEW(len+1, unsigned char);
53   memcpy(data, *inbuf, len);
54   data[len] = '\0';
55
56   *inbuf = cur;
57   return pst_new_obj(PST_TYPE_UNKNOWN, data);
58 }
59
60 static void
61 skip_line (unsigned char **inbuf, unsigned char *inbufend)
62 {
63   while (*inbuf < inbufend && **inbuf != '\n' && **inbuf != '\r')
64     (*inbuf)++;
65   if (*inbuf < inbufend && **inbuf == '\r')
66     (*inbuf)++;
67   if (*inbuf < inbufend && **inbuf == '\n')
68     (*inbuf)++;
69 }
70
71 static void
72 skip_comments (unsigned char **inbuf, unsigned char *inbufend)
73 {
74   while (*inbuf < inbufend && **inbuf == '%') {
75     skip_line(inbuf, inbufend);
76     skip_white_spaces(inbuf, inbufend);
77   }
78 }
79
80 #if 0
81 static pst_obj *
82 pst_parse_comment (unsigned char **inbuf, unsigned char *inbufend)
83 {
84   unsigned char *data;
85   unsigned char *cur = *inbuf;
86   unsigned long  len;
87
88   if (*cur != '%')
89     return NULL;
90   
91   while (cur < inbufend && *cur != '\n' && *cur != '\r')
92     cur++;
93   len = cur - (*inbuf);
94   data = NEW(len+1, unsigned char);
95   memcpy(data, *inbuf, len);
96   data[len] = '\0';
97      
98   *inbuf = cur;
99   return pst_new_obj(PST_TYPE_UNKNOWN, data);
100 }
101 #endif
102
103 /* NOTE: the input buffer must be null-terminated, i.e., *inbufend == 0 */
104 pst_obj *
105 pst_get_token (unsigned char **inbuf, unsigned char *inbufend)
106 {
107   pst_obj *obj = NULL;
108   unsigned char c;
109
110   ASSERT(*inbuf <= inbufend && !*inbufend);
111
112   skip_white_spaces(inbuf, inbufend);
113   skip_comments(inbuf, inbufend);
114   if (*inbuf >= inbufend)
115     return NULL;
116   c = **inbuf;
117   switch (c) {
118 #if 0
119   case '%':
120     obj = pst_parse_comment(inbuf, inbufend);
121     break;
122 #endif
123   case '/':
124     obj = pst_parse_name(inbuf, inbufend);
125     break;
126   case '[': case '{': /* This is wrong */
127     obj = pst_new_mark();
128     (*inbuf)++;
129     break;
130   case '<':
131     if (*inbuf + 1 >= inbufend)
132       return NULL;
133     c = *(*inbuf+1);
134     if (c == '<') {
135       obj = pst_new_mark();
136       *inbuf += 2;
137     } else if (isxdigit(c))
138       obj = pst_parse_string(inbuf, inbufend);
139     else if (c == '~') /* ASCII85 */
140       obj = pst_parse_string(inbuf, inbufend);
141     break;
142   case '(':
143     obj = pst_parse_string(inbuf, inbufend);
144     break;
145   case '>':
146     if (*inbuf + 1 >= inbufend || *(*inbuf+1) != '>') {
147       ERROR("Unexpected end of ASCII hex string marker.");
148     } else  {
149       char *mark;
150
151       mark = NEW(3, char);
152       mark[0] = '>'; mark[1] = '>'; mark[2] = '\0';
153       obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
154       (*inbuf) += 2;
155     }
156     break;
157   case ']': case '}': 
158     {
159       char *mark;
160
161       mark = NEW(2, char);
162       mark[0] = c; mark[1] = '\0';
163       obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
164       (*inbuf)++;
165     }
166     break;
167   default:
168     if (c == 't' || c == 'f')
169       obj = pst_parse_boolean(inbuf, inbufend);
170     else if (c == 'n')
171       obj = pst_parse_null(inbuf, inbufend);
172     else if (c == '+' || c == '-' || isdigit(c) || c == '.')
173       obj = pst_parse_number(inbuf, inbufend);
174     break;
175   }
176
177   if (!obj) {
178     obj = pst_parse_any(inbuf, inbufend);
179   }
180
181   return obj;
182 }