1 /**** << Text Formating & Printing Utilities >> ****
2  *
3  *  euc.c
4  *                                                  Aug 16 1993
5  *                                      mod:        Aug 19 1993
6  ************************************************** tonooka ***********/
7 /*
8  *	Copyright (c) 1994 Yasuhiro Tonooka (tonooka@msi.co.jp)
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, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 #if !defined lint
25 static char *sccsid = "@(#)euc.c 2.2 (Y.Tonooka) 3/28/94";
26 #endif
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include "euc.h"
33 
34 #if defined EUC
35 
36 typedef unsigned char u_char;
37 
38 #define SS2	0x8e
39 #define SS3	0x8f
40 
41 /**********************************************************************
42  *                                                                    *
43  *  Compatibility                                                     *
44  *                                                                    *
45  **********************************************************************/
46 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
47     NAME
48 	pcode
49  ---------------------------------------------------------------------*/
pcode(s)50 int pcode(s)
51     register char **s;
52 {
53     register int c0, c1;
54 
55     if ((c0 = *(u_char *) (*s)++) & 0x80) {
56 	if ((c1 = *(u_char *) (*s)++) & 0x80)
57 	    switch (c0) {
58 	    case SS2:
59 		return c1;
60 	    case SS3:
61 		if (*(u_char *) (*s) & 0x80)
62 		    return c1 << 8 | *(u_char *) (*s)++ & 0x7f;
63 		break;
64 	    default:
65 		return c0 << 8 | c1;
66 	    }
67 	--(*s);
68 	c0 = ' ';
69     }
70     return c0;
71 }
72 
73 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
74     NAME
75 	geteucc
76  ---------------------------------------------------------------------*/
geteucc(fp)77 int geteucc(fp)
78     register FILE *fp;
79 {
80     register int c, cc;
81 
82     if ((c = getc(fp)) == EOF || c < 0x80)
83 	return c;
84     if ((cc = getc(fp)) == EOF)
85 	return EOF;
86     switch (c) {
87     case SS2:
88 	return cc;
89     case SS3:
90 	if ((c = getc(fp)) == EOF)
91 	    return EOF;
92 	return cc << 8 | c & 0x7f;
93     default:
94 	return c << 8 | cc;
95     }
96 }
97 
98 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
99     NAME
100 	puteucc
101  ---------------------------------------------------------------------*/
puteucc(c,fp)102 int puteucc(c, fp)
103     register int c;
104     FILE *fp;
105 {
106     if (c < 0x80)		/* ASCII */
107 	return putc(c, fp);
108     if (c < 0x100) {		/* SS2 */
109 	putc(SS2, fp);
110 	return putc(c, fp);
111     }
112     if (c & 0x80) {		/* SS1 */
113 	putc(c >> 8, fp);
114 	return putc(c & 0xff, fp);
115     }
116     putc(SS3, fp);		/* SS3 */
117     putc(c >> 8, fp);
118     return putc(c & 0xff | 0x80, fp);
119 }
120 
121 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
122     NAME
123 	euccol - gives displaywidth of an EUC character
124  ---------------------------------------------------------------------*/
euccol(c)125 int euccol(c)
126     register int c;
127 {
128     return c < 0x100 ? 1 : 2;
129 }
130 
131 /**********************************************************************
132  *                                                                    *
133  *  Other Routines                                                    *
134  *                                                                    *
135  **********************************************************************/
136 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
137     NAME
138 	fgeteucs
139  ---------------------------------------------------------------------*/
fgeteucs(str,n,fp)140 char_t *fgeteucs(str, n, fp)
141     char_t *str;
142     register int n;
143     register FILE *fp;
144 {
145     register c;
146     register char_t *s;
147 
148     s = str;
149     while (--n > 0 && (c = geteucc(fp)) != EOF) {
150 	*s++ = c;
151 	if (c == '\n')
152 	    break;
153     }
154     if (c == EOF && s == str)
155 	return NULL;
156     *s = '\0';
157     return str;
158 }
159 
160 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
161     NAME
162 	fputeucs
163  ---------------------------------------------------------------------*/
fputeucs(s,fp)164 int fputeucs(s, fp)
165     register char_t *s;
166     register FILE *fp;
167 {
168     register int c, r;
169 
170     while (c = *s++)
171 	r = puteucc(c, fp);
172     return(r);
173 }
174 
175 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
176     NAME
177 	streuclen
178  ---------------------------------------------------------------------*/
streuclen(s)179 int streuclen(s)
180     register char_t *s;
181 {
182     register int i = 0;
183 
184     while (*s++)
185 	i++;
186     return i;
187 }
188 
189 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
190     NAME
191 	euccmp
192  ---------------------------------------------------------------------*/
euccmp(s1,s2)193 int euccmp(s1, s2)
194     register char_t *s1, *s2;
195 {
196     for (; *s1 == *s2; s1++, s2++)
197 	if (*s1 == '\0')
198 	    return 0;
199     return *s1 - *s2;
200 }
201 
202 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
203     NAME
204 	euccasecmp
205  ---------------------------------------------------------------------*/
euccasecmp(s1,s2)206 int euccasecmp(s1, s2)
207     register char_t *s1, *s2;
208 {
209     register int c;
210 
211     for (; (c = (*s1 < 0x80 ? toupper(*s1) : *s1)
212 	    - (*s2 < 0x80 ? toupper(*s2) : *s2)) == 0; s1++, s2++)
213 	if (*s1 == '\0')
214 	    return 0;
215     return c;
216 }
217 
218 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
219     NAME
220 	stow - single-byte-char string to processing code string
221  ---------------------------------------------------------------------*/
stow(s)222 char_t *stow(s)
223     char *s;
224 {
225     register char_t *w;
226     char_t *euc;
227 
228     if ((euc = (char_t *) malloc(sizeof (char_t) * (strlen(s) + 1)))
229 	    == NULL)
230 	return NULL;
231     for (w = euc; *s; )
232 	*w++ = *(u_char *) s < 0x80 ? *s++ : pcode(&s);
233     *w++ = '\0';
234     return (char_t *) realloc(euc, sizeof (char_t) * (w - euc));
235 }
236 
237 /*-==(spec:\\:":":\(:\):\[:\]::::euc)==--------------------------------
238     NAME
239 	eucdup
240  ---------------------------------------------------------------------*/
eucdup(s)241 char_t *eucdup(s)
242     register char_t *s;
243 {
244     register char_t *d;
245     char_t *dup;
246 
247     if (dup = (char_t *) malloc(sizeof (char_t) * (streuclen(s) + 1)))
248 	for (d = dup; ; )
249 	    if (!(*d++ = *s++))
250 		break;
251     return dup;
252 }
253 
254 #endif
255