xref: /minix3/minix/commands/cawf/string.c (revision 4d3708913c2076bda91438dab93c91e44ba5a7cf)
1433d6423SLionel Sambuc /*
2433d6423SLionel Sambuc  *	string.c - string support functions for cawf(1)
3433d6423SLionel Sambuc  */
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc /*
6433d6423SLionel Sambuc  *	Copyright (c) 1991 Purdue University Research Foundation,
7433d6423SLionel Sambuc  *	West Lafayette, Indiana 47907.  All rights reserved.
8433d6423SLionel Sambuc  *
9433d6423SLionel Sambuc  *	Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
10433d6423SLionel Sambuc  *	University Computing Center.  Not derived from licensed software;
11433d6423SLionel Sambuc  *	derived from awf(1) by Henry Spencer of the University of Toronto.
12433d6423SLionel Sambuc  *
13433d6423SLionel Sambuc  *	Permission is granted to anyone to use this software for any
14433d6423SLionel Sambuc  *	purpose on any computer system, and to alter it and redistribute
15433d6423SLionel Sambuc  *	it freely, subject to the following restrictions:
16433d6423SLionel Sambuc  *
17433d6423SLionel Sambuc  *	1. The author is not responsible for any consequences of use of
18433d6423SLionel Sambuc  *	   this software, even if they arise from flaws in it.
19433d6423SLionel Sambuc  *
20433d6423SLionel Sambuc  *	2. The origin of this software must not be misrepresented, either
21433d6423SLionel Sambuc  *	   by explicit claim or by omission.  Credits must appear in the
22433d6423SLionel Sambuc  *	   documentation.
23433d6423SLionel Sambuc  *
24433d6423SLionel Sambuc  *	3. Altered versions must be plainly marked as such, and must not
25433d6423SLionel Sambuc  *	   be misrepresented as being the original software.  Credits must
26433d6423SLionel Sambuc  *	   appear in the documentation.
27433d6423SLionel Sambuc  *
28433d6423SLionel Sambuc  *	4. This notice may not be removed or altered.
29433d6423SLionel Sambuc  */
30433d6423SLionel Sambuc 
31433d6423SLionel Sambuc #include "cawf.h"
32433d6423SLionel Sambuc #include <ctype.h>
33433d6423SLionel Sambuc 
34d9494baaSJacob Adams static void Setroman(void);
35433d6423SLionel Sambuc 
36433d6423SLionel Sambuc 
37433d6423SLionel Sambuc /*
38433d6423SLionel Sambuc  * Asmname(s, c) - assemble name
39433d6423SLionel Sambuc  */
40433d6423SLionel Sambuc 
Asmname(unsigned char * s,unsigned char * c)41d9494baaSJacob Adams int Asmname(unsigned char *s, unsigned char *c) {
42d9494baaSJacob Adams /* pointer to name s
43d9494baaSJacob Adams  * code destination (c[3])
44d9494baaSJacob Adams  */
45433d6423SLionel Sambuc 	c[1] = c[2] = '\0';
46*4d370891SDavid van Moolenbroek 	while (*s == ' ')
47433d6423SLionel Sambuc 		s++;
48433d6423SLionel Sambuc 	if ((c[0] = *s) == '\0')
49433d6423SLionel Sambuc 		return(0);
50433d6423SLionel Sambuc 	return(((c[1] = s[1]) == '\0') ? 1 : 2);
51433d6423SLionel Sambuc }
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc /*
55433d6423SLionel Sambuc  * Delstr(sx) - delete string
56433d6423SLionel Sambuc  */
57433d6423SLionel Sambuc 
Delstr(int sx)58d9494baaSJacob Adams void Delstr(int sx) {
59d9494baaSJacob Adams /* string index sx */
60433d6423SLionel Sambuc 	char buf[MAXLINE];		/* message buffer */
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc 	if (sx >= Nstr) {
63433d6423SLionel Sambuc 		(void) sprintf(buf, " bad Delstr(%d) index", sx);
64433d6423SLionel Sambuc 		Error(FATAL, LINE, buf, NULL);
65433d6423SLionel Sambuc 	}
66433d6423SLionel Sambuc 	Free(&Str[sx].str);
67433d6423SLionel Sambuc 	while (sx < (Nstr - 1)) {
68433d6423SLionel Sambuc 		Str[sx] = Str[sx + 1];
69433d6423SLionel Sambuc 		sx++;
70433d6423SLionel Sambuc 	}
71433d6423SLionel Sambuc 	Nstr--;
72433d6423SLionel Sambuc }
73433d6423SLionel Sambuc 
74433d6423SLionel Sambuc 
75433d6423SLionel Sambuc /*
76433d6423SLionel Sambuc  * Endword() - end a word
77433d6423SLionel Sambuc  */
78433d6423SLionel Sambuc 
Endword(void)79d9494baaSJacob Adams void Endword(void) {
80433d6423SLionel Sambuc 	if (Fontstat != 'R')
81433d6423SLionel Sambuc 		Setroman();
82433d6423SLionel Sambuc 	Word[Wordx] = '\0';
83433d6423SLionel Sambuc }
84433d6423SLionel Sambuc 
85433d6423SLionel Sambuc 
86433d6423SLionel Sambuc /*
87433d6423SLionel Sambuc  * Findchar(nm, l, s, e) - find special character definition and
88433d6423SLionel Sambuc  *			   optionally enter it
89433d6423SLionel Sambuc  */
90433d6423SLionel Sambuc 
Findchar(unsigned char * nm,int l,unsigned char * s,int e)91d9494baaSJacob Adams int Findchar(unsigned char *nm, int l, unsigned char *s, int e) {
92d9494baaSJacob Adams /* character name nm
93d9494baaSJacob Adams  * effective length l
94d9494baaSJacob Adams  * value string s
95d9494baaSJacob Adams  * e = 0 = find, don't enter
96d9494baaSJacob Adams  * e = 1 = don't find, enter
97d9494baaSJacob Adams  */
98433d6423SLionel Sambuc 	int cmp, hi, low, mid;
99433d6423SLionel Sambuc 	unsigned char c[3];
100433d6423SLionel Sambuc 
101433d6423SLionel Sambuc 	c[0] = nm[0];
102433d6423SLionel Sambuc 	c[1] = (nm[1] == ' ' || nm[1] == '\t') ? '\0' : nm[1];
103433d6423SLionel Sambuc 	c[2] = '\0';
104433d6423SLionel Sambuc 	low = mid = 0;
105433d6423SLionel Sambuc 	hi = Nsch - 1;
106433d6423SLionel Sambuc 	while (low <= hi) {
107433d6423SLionel Sambuc 		mid = (low + hi) / 2;
108433d6423SLionel Sambuc 		if ((cmp = strncmp((char *)c, (char *)Schar[mid].nm, 2)) < 0)
109433d6423SLionel Sambuc 			hi = mid - 1;
110433d6423SLionel Sambuc 		else if (cmp > 0)
111433d6423SLionel Sambuc 			low = mid + 1;
112433d6423SLionel Sambuc 		else {
113433d6423SLionel Sambuc 			if ( ! e)
114433d6423SLionel Sambuc 				return(mid);
115433d6423SLionel Sambuc 			Free(&Schar[mid].str);
116433d6423SLionel Sambuc 			goto new_char;
117433d6423SLionel Sambuc 		}
118433d6423SLionel Sambuc 	}
119433d6423SLionel Sambuc 	if ( ! e)
120433d6423SLionel Sambuc 		return(-1);
121433d6423SLionel Sambuc 	if (Nsch >= MAXSCH)
122433d6423SLionel Sambuc 		Error(FATAL, LINE, " at character table limit", NULL);
123433d6423SLionel Sambuc 	if (Nsch) {
124433d6423SLionel Sambuc 		if (cmp > 0)
125433d6423SLionel Sambuc 			mid++;
126433d6423SLionel Sambuc 		for (hi = Nsch - 1; hi >= mid; hi--)
127433d6423SLionel Sambuc 			Schar[hi+1] = Schar[hi];
128433d6423SLionel Sambuc 	}
129433d6423SLionel Sambuc 	Nsch++;
130433d6423SLionel Sambuc 	Schar[mid].nm[0] = c[0];
131433d6423SLionel Sambuc 	Schar[mid].nm[1] = c[1];
132433d6423SLionel Sambuc 
133433d6423SLionel Sambuc new_char:
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc 	Schar[mid].str = Newstr(s);
136433d6423SLionel Sambuc 	Schar[mid].len = l;
137433d6423SLionel Sambuc 	return(mid);
138433d6423SLionel Sambuc }
139433d6423SLionel Sambuc 
140433d6423SLionel Sambuc 
141433d6423SLionel Sambuc /*
142433d6423SLionel Sambuc  * Findhy(s, l, e) - find and optionally enter hyphen
143433d6423SLionel Sambuc  */
144433d6423SLionel Sambuc 
Findhy(unsigned char * s,int l,int e)145d9494baaSJacob Adams int Findhy(unsigned char *s, int l, int e) {
146d9494baaSJacob Adams /* value string s
147d9494baaSJacob Adams  * equivalent length l
148d9494baaSJacob Adams  * e = 0 = find, don't enter
149d9494baaSJacob Adams  * e = 1 = enter, don't find
150d9494baaSJacob Adams  */
151433d6423SLionel Sambuc 	int i;
152433d6423SLionel Sambuc 
153433d6423SLionel Sambuc 	for (i = 0; i < Nhy; i++) {
154433d6423SLionel Sambuc 		if (Font[0] == Hychar[i].font)
155433d6423SLionel Sambuc 			break;
156433d6423SLionel Sambuc 	}
157433d6423SLionel Sambuc 	if (i >= Nhy) {
158433d6423SLionel Sambuc 		if ( ! e)
159433d6423SLionel Sambuc 			return(-1);
160433d6423SLionel Sambuc 		if (Nhy >= MAXHYCH)
161433d6423SLionel Sambuc 			Error(FATAL, LINE, " at hyphen limit for font ",
162433d6423SLionel Sambuc 				(char *)Font);
163433d6423SLionel Sambuc 		Hychar[i].font = Font[0];
164433d6423SLionel Sambuc 		Nhy++;
165433d6423SLionel Sambuc 	} else {
166433d6423SLionel Sambuc 		if ( ! e)
167433d6423SLionel Sambuc 			return(i);
168433d6423SLionel Sambuc 		Error(WARN, LINE, " duplicate hyphen for font ", (char *)Font);
169433d6423SLionel Sambuc 		Free(&Hychar[i].str);
170433d6423SLionel Sambuc 	}
171433d6423SLionel Sambuc 	Hychar[i].str = Newstr(s);
172433d6423SLionel Sambuc 	Hychar[i].len = l;
173433d6423SLionel Sambuc 	return(i);
174433d6423SLionel Sambuc }
175433d6423SLionel Sambuc 
176433d6423SLionel Sambuc 
177433d6423SLionel Sambuc /*
178433d6423SLionel Sambuc  * Findstr(nm, s, e) - find and  optionally enter string in Str[]
179433d6423SLionel Sambuc  */
180433d6423SLionel Sambuc 
Findstr(unsigned char * nm,unsigned char * s,int e)181d9494baaSJacob Adams unsigned char *Findstr(unsigned char *nm, unsigned char *s, int e) {
182d9494baaSJacob Adams /* 2 character string name nm
183d9494baaSJacob Adams  * string value s
184d9494baaSJacob Adams  * e = 0 = find, don't enter
185d9494baaSJacob Adams  * e = 1 = enter, don't find
186d9494baaSJacob Adams  */
187433d6423SLionel Sambuc 	unsigned char c[3];		/* character buffer */
188433d6423SLionel Sambuc 	int cmp, hi, low, mid;		/* binary search controls */
189433d6423SLionel Sambuc 	int i;				/* temporary indexes */
190433d6423SLionel Sambuc 	unsigned char *s1, *s2;		/* temporary string pointers */
191433d6423SLionel Sambuc 
192433d6423SLionel Sambuc 	c[0] = nm[0];
193433d6423SLionel Sambuc 	c[1] = (nm[1] == ' ' || nm[1] == '\t') ? '\0' : nm[1];
194433d6423SLionel Sambuc 	c[2] = '\0';
195433d6423SLionel Sambuc 	low = mid = 0;
196433d6423SLionel Sambuc 	hi = Nstr - 1;
197433d6423SLionel Sambuc 	Sx = -1;
198433d6423SLionel Sambuc 	while (low <= hi) {
199433d6423SLionel Sambuc 		mid = (low + hi) / 2;
200433d6423SLionel Sambuc 		if ((cmp = strncmp((char *)c, (char *)Str[mid].nm, 2)) < 0)
201433d6423SLionel Sambuc 			hi = mid - 1;
202433d6423SLionel Sambuc 		else if (cmp > 0)
203433d6423SLionel Sambuc 			low = mid + 1;
204433d6423SLionel Sambuc 		else {
205433d6423SLionel Sambuc 			Sx = mid;
206433d6423SLionel Sambuc 			if ( ! e)
207433d6423SLionel Sambuc 				return(Str[mid].str);
208433d6423SLionel Sambuc 			Free(&Str[mid].str);
209433d6423SLionel Sambuc 			goto new_string;
210433d6423SLionel Sambuc 		}
211433d6423SLionel Sambuc 	}
212433d6423SLionel Sambuc 	if ( ! e)
213433d6423SLionel Sambuc 		return((unsigned char *)"");
214433d6423SLionel Sambuc 	if (Nstr >= MAXSTR)
215433d6423SLionel Sambuc 		Error(FATAL, LINE, " out of space for string ", (char *)c);
216433d6423SLionel Sambuc 	if (Nstr) {
217433d6423SLionel Sambuc 		if (cmp > 0)
218433d6423SLionel Sambuc 			mid++;
219433d6423SLionel Sambuc 		for (hi = Nstr - 1; hi >= mid; hi--)
220433d6423SLionel Sambuc 			Str[hi+1] = Str[hi];
221433d6423SLionel Sambuc 	}
222433d6423SLionel Sambuc 	Nstr++;
223433d6423SLionel Sambuc 	Sx = mid;
224433d6423SLionel Sambuc 	Str[mid].nm[0] = c[0];
225433d6423SLionel Sambuc 	Str[mid].nm[1] = c[1];
226433d6423SLionel Sambuc 
227433d6423SLionel Sambuc new_string:
228433d6423SLionel Sambuc 
229433d6423SLionel Sambuc 	if (s == NULL)
230433d6423SLionel Sambuc 		return (Str[mid].str = Newstr((unsigned char *)""));
231433d6423SLionel Sambuc 	i = (*s == '"') ? 1 : 0;
232433d6423SLionel Sambuc 	s1 = Str[mid].str = Newstr(s + i);
233433d6423SLionel Sambuc 	if (i) {
234433d6423SLionel Sambuc 		s2 = s1 + strlen((char *)s1);
235433d6423SLionel Sambuc 		if (s2 > s1 && *(s2-1) == '"')
236433d6423SLionel Sambuc 			*(s2-1) = '\0';
237433d6423SLionel Sambuc 	}
238433d6423SLionel Sambuc 	return(s1);
239433d6423SLionel Sambuc }
240433d6423SLionel Sambuc 
241433d6423SLionel Sambuc 
242433d6423SLionel Sambuc /*
243433d6423SLionel Sambuc  * Setroman() - set Roman font
244433d6423SLionel Sambuc  */
245433d6423SLionel Sambuc 
Setroman(void)246d9494baaSJacob Adams static void Setroman(void) {
247433d6423SLionel Sambuc 	int i;
248433d6423SLionel Sambuc 
249433d6423SLionel Sambuc 	if ((Wordx + Fstr.rl) >= MAXLINE)
250433d6423SLionel Sambuc 		Error(WARN, LINE, " word too long", NULL);
251433d6423SLionel Sambuc 	else {
252433d6423SLionel Sambuc 		if (Fstr.r) {
253433d6423SLionel Sambuc 			for (i = 0; i < Fstr.rl; i++) {
254433d6423SLionel Sambuc 				Word[Wordx++] = Fstr.r[i];
255433d6423SLionel Sambuc 			}
256433d6423SLionel Sambuc 	    	}
257433d6423SLionel Sambuc 		Fontstat = 'R';
258433d6423SLionel Sambuc 	}
259433d6423SLionel Sambuc }
260433d6423SLionel Sambuc 
261433d6423SLionel Sambuc 
262433d6423SLionel Sambuc /*
263433d6423SLionel Sambuc  * Str2word(s, len) - copy len characters from string to Word[]
264433d6423SLionel Sambuc  */
265433d6423SLionel Sambuc 
Str2word(unsigned char * s,int len)266d9494baaSJacob Adams int Str2word(unsigned char *s, int len) {
267433d6423SLionel Sambuc 	int i;
268433d6423SLionel Sambuc 
269433d6423SLionel Sambuc 	for (; len > 0; len--, s++) {
270433d6423SLionel Sambuc 		switch (Font[0]) {
271433d6423SLionel Sambuc 		case 'B':
272433d6423SLionel Sambuc 		case 'C':
273433d6423SLionel Sambuc 			if (Fontctl == 0) {
274433d6423SLionel Sambuc 				if ((Wordx + 5) >= MAXLINE) {
275433d6423SLionel Sambuc word_too_long:
276433d6423SLionel Sambuc 					Error(WARN, LINE, " word too long",
277433d6423SLionel Sambuc 						NULL);
278433d6423SLionel Sambuc 					return(1);
279433d6423SLionel Sambuc 				}
280433d6423SLionel Sambuc 				Word[Wordx++] = Trtbl[(int)*s];
281433d6423SLionel Sambuc 				Word[Wordx++] = '\b';
282433d6423SLionel Sambuc 				Word[Wordx++] = Trtbl[(int)*s];
283433d6423SLionel Sambuc 				Word[Wordx++] = '\b';
284433d6423SLionel Sambuc 				Word[Wordx++] = Trtbl[(int)*s];
285433d6423SLionel Sambuc 				break;
286433d6423SLionel Sambuc 			}
287433d6423SLionel Sambuc 			if (Fontstat != Font[0]) {
288433d6423SLionel Sambuc 				if (Fontstat != 'R')
289433d6423SLionel Sambuc 					Setroman();
290433d6423SLionel Sambuc 				if ((Wordx + Fstr.bl) >= MAXLINE)
291433d6423SLionel Sambuc 					goto word_too_long;
292433d6423SLionel Sambuc 				if (Fstr.b) {
293433d6423SLionel Sambuc 					for (i = 0; i < Fstr.bl; i++) {
294433d6423SLionel Sambuc 						Word[Wordx++] = Fstr.b[i];
295433d6423SLionel Sambuc 					}
296433d6423SLionel Sambuc 				}
297433d6423SLionel Sambuc 				Fontstat = Font[0];
298433d6423SLionel Sambuc 			}
299433d6423SLionel Sambuc 			if ((Wordx + 1) >= MAXLINE)
300433d6423SLionel Sambuc 				goto word_too_long;
301433d6423SLionel Sambuc 			Word[Wordx++] = Trtbl[(int)*s];
302433d6423SLionel Sambuc 			break;
303433d6423SLionel Sambuc 		case 'I':
304433d6423SLionel Sambuc 			if (isalnum(*s)) {
305433d6423SLionel Sambuc 				if (Fontctl == 0) {
306433d6423SLionel Sambuc 					if ((Wordx + 3) >= MAXLINE)
307433d6423SLionel Sambuc 						goto word_too_long;
308433d6423SLionel Sambuc 					Word[Wordx++] = '_';
309433d6423SLionel Sambuc 					Word[Wordx++] = '\b';
310433d6423SLionel Sambuc 					Word[Wordx++] = Trtbl[(int)*s];
311433d6423SLionel Sambuc 					break;
312433d6423SLionel Sambuc 				}
313433d6423SLionel Sambuc 				if (Fontstat != 'I') {
314433d6423SLionel Sambuc 					if (Fontstat != 'R')
315433d6423SLionel Sambuc 						Setroman();
316433d6423SLionel Sambuc 					if ((Wordx + Fstr.itl) >= MAXLINE)
317433d6423SLionel Sambuc 						goto word_too_long;
318433d6423SLionel Sambuc 					if (Fstr.it) {
319433d6423SLionel Sambuc 					    for (i = 0; i < Fstr.itl; i++) {
320433d6423SLionel Sambuc 						Word[Wordx++] = Fstr.it[i];
321433d6423SLionel Sambuc 					    }
322433d6423SLionel Sambuc 					}
323433d6423SLionel Sambuc 					Fontstat = 'I';
324433d6423SLionel Sambuc 				}
325433d6423SLionel Sambuc 				if ((Wordx + 1) >= MAXLINE)
326433d6423SLionel Sambuc 					goto word_too_long;
327433d6423SLionel Sambuc 				Word[Wordx++] = Trtbl[(int)*s];
328433d6423SLionel Sambuc 				break;
329433d6423SLionel Sambuc 			}
330433d6423SLionel Sambuc 			/* else fall through */
331433d6423SLionel Sambuc 		default:
332433d6423SLionel Sambuc 			if (Fontstat != 'R')
333433d6423SLionel Sambuc 				Setroman();
334433d6423SLionel Sambuc 			if ((Wordx + 1) >= MAXLINE)
335433d6423SLionel Sambuc 				goto word_too_long;
336433d6423SLionel Sambuc 			Word[Wordx++] = Trtbl[(int)*s];
337433d6423SLionel Sambuc 		}
338433d6423SLionel Sambuc 	}
339433d6423SLionel Sambuc 	return(0);
340433d6423SLionel Sambuc }
341