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