(cos_skip_space): New function.
[chise/concord.git] / print.c
1 /* Copyright (C) 2013 MORIOKA Tomohiko
2    This file is part of the CONCORD Library.
3
4    The CONCORD Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The CONCORD Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the CONCORD Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include "cos-print.h"
20 #include "cos-i.h"
21
22 int
23 cos_utf8_encode_char (int cid, unsigned char *dest, size_t size)
24 {
25   int i = 0;
26
27   if (cid <= 0x7F)
28     {
29       if (size >= 2)
30         {
31           dest[i++] = cid;
32           dest[i] = '\0';
33           return i;
34         }
35       else
36         return -1;
37     }
38   else if (cid <= 0x7FF)
39     {
40       if (size >= 3)
41         {
42           dest[i++] = (cid >> 6) | 0xC0;
43           dest[i++] = (cid & 0x3F) | 0x80;
44           dest[i] = '\0';
45           return i;
46         }
47       else
48         return -1;
49     }
50   else if (cid <= 0xFFFF)
51     {
52       if (size >= 4)
53         {
54           dest[i++] = (cid >> 12) | 0xE0;
55           dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
56           dest[i++]=  (cid        & 0x3F) | 0x80;
57           dest[i] = '\0';
58           return i;
59         }
60       else
61         return -1;
62     }
63   else if (cid <= 0x1FFFFF)
64     {
65       if (size >= 5)
66         {
67           dest[i++]=  (cid >> 18) | 0xF0;
68           dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
69           dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
70           dest[i++]=  (cid        & 0x3F) | 0x80;
71           dest[i] = '\0';
72           return i;
73         }
74       else
75         return -1;
76     }
77   else if (cid <= 0x3FFFFFF)
78     {
79       if (size >= 6)
80         {
81           dest[i++]=  (cid >> 24) | 0xF8;
82           dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
83           dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
84           dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
85           dest[i++]=  (cid        & 0x3F) | 0x80;
86           dest[i] = '\0';
87           return i;
88         }
89       else
90         return -1;
91     }
92   else
93     {
94       if (size >= 7)
95         {
96           dest[i++]=  (cid >> 30) | 0xFC;
97           dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
98           dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
99           dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
100           dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
101           dest[i++]=  (cid        & 0x3F) | 0x80;
102           dest[i] = '\0';
103           return i;
104         }
105       else
106         return -1;
107     }
108 }
109
110 int
111 cos_utf8_print_char (COS_object character, unsigned char *dest, size_t size)
112 {
113   int cid = cos_char_id (character);
114   int i = 0;
115
116   dest[i++] = '?';
117   if (cid == '\t')
118     {
119       dest[i++] = '\\';
120       dest[i++] = 't';
121       dest[i] = '\0';
122       return i;
123     }
124   else if (cid == '\n')
125     {
126       dest[i++] = '\\';
127       dest[i++] = 'n';
128       dest[i] = '\0';
129       return i;
130     }
131   else if (cid == '\r')
132     {
133       dest[i++] = '\\';
134       dest[i++] = 'r';
135       dest[i] = '\0';
136       return i;
137     }
138   else if (cid == 0x1C)
139     {
140       dest[i++] = '\\';
141       dest[i++] = '^';
142       dest[i++] = '\\';
143       dest[i++] = '\\';
144       dest[i] = '\0';
145       return i;
146     }
147   else if (cid <= 0x1F)
148     {
149       dest[i++] = '\\';
150       dest[i++] = '^';
151       dest[i++] = '@' + cid;
152       dest[i] = '\0';
153       return i;
154     }
155   else if ( (cid == ' ') || (cid == '"') ||
156             (cid == '#') || (cid == '\'') ||
157             (cid == '(') || (cid == ')') ||
158             (cid == ',') || (cid == '.') ||
159             (cid == ';') || (cid == '?') ||
160             (cid == '[') || (cid == '\\') ||
161             (cid == ']') || (cid == '`') )
162     {
163       dest[i++] = '\\';
164       dest[i++] = cid;
165       dest[i] = '\0';
166       return i;
167     }
168   else if (cid <= 0x7E)
169     {
170       dest[i++] = cid;
171       dest[i] = '\0';
172       return i;
173     }
174   else if (cid == 0x7F)
175     {
176       dest[i++] = '\\';
177       dest[i++] = '^';
178       dest[i++] = '?';
179       dest[i] = '\0';
180       return i;
181     }
182   else if (cid <= 0x9F)
183     {
184       dest[i++] = '\\';
185       dest[i++] = '^';
186       dest[i++] = ((cid + '@') >> 6) | 0xC0;
187       dest[i++] = ((cid + '@') & 0x3F) | 0x80;
188       dest[i] = '\0';
189       return i;
190     }
191   else if (cid <= 0x7FF)
192     {
193       dest[i++] = (cid >> 6) | 0xC0;
194       dest[i++] = (cid & 0x3F) | 0x80;
195       dest[i] = '\0';
196       return i;
197     }
198   else if (cid <= 0xFFFF)
199     {
200       dest[i++] = (cid >> 12) | 0xE0;
201       dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
202       dest[i++]=  (cid        & 0x3F) | 0x80;
203       dest[i] = '\0';
204       return i;
205     }
206   else if (cid <= 0x1FFFFF)
207     {
208       dest[i++]=  (cid >> 18) | 0xF0;
209       dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
210       dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
211       dest[i++]=  (cid        & 0x3F) | 0x80;
212       dest[i] = '\0';
213       return i;
214     }
215   else if (cid <= 0x3FFFFFF)
216     {
217       dest[i++]=  (cid >> 24) | 0xF8;
218       dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
219       dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
220       dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
221       dest[i++]=  (cid        & 0x3F) | 0x80;
222       dest[i] = '\0';
223       return i;
224     }
225   else
226     {
227       dest[i++]=  (cid >> 30) | 0xFC;
228       dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
229       dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
230       dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
231       dest[i++]= ((cid >>  6) & 0x3F) | 0x80;
232       dest[i++]=  (cid        & 0x3F) | 0x80;
233       dest[i] = '\0';
234       return i;
235     }
236 }
237
238
239 void
240 cos_print_object (COS_object obj)
241 {
242   if ( obj == NULL )
243     printf ("#<NULL>", obj);
244   else if ( COS_OBJECT_INT_P (obj) )
245     printf ("%d", cos_int_value (obj));
246   else if ( COS_OBJECT_CHAR_P (obj) )
247     {
248       char id_buf[256];
249
250       cos_utf8_print_char (obj, id_buf, 256);
251       printf ("%s", id_buf);
252     }
253   else if ( COS_OBJECT_STRING_P (obj) )
254     {
255       printf ("\"%s\"", cos_string_data (obj));
256     }
257   else if ( COS_OBJECT_SYMBOL_P (obj) )
258     {
259       printf ("%s", cos_string_data (cos_symbol_name (obj)));
260     }
261   else if ( COS_OBJECT_CONS_P (obj) )
262     {
263       COS_object rest = COS_CDR (obj);
264
265       printf ("(");
266       cos_print_object (COS_CAR (obj));
267       while ( COS_OBJECT_CONS_P (rest) )
268         {
269           printf (" ");
270           cos_print_object (COS_CAR (rest));
271           rest = COS_CDR (rest);
272         }
273       if ( rest != cos_Qnil )
274         {
275           printf (" . ");
276           cos_print_object (rest);
277         }
278       printf (")");
279     }
280   else
281     printf ("Object[0x%lX] is a fat object.\n",
282             obj);
283 }