1 /*@z39.c:String Handler:AsciiToFull(), StringEqual(), etc.@*******************/
2 /* */
3 /* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.39) */
4 /* COPYRIGHT (C) 1991, 2008 Jeffrey H. Kingston */
5 /* */
6 /* Jeffrey H. Kingston (jeff@it.usyd.edu.au) */
7 /* School of Information Technologies */
8 /* The University of Sydney 2006 */
9 /* AUSTRALIA */
10 /* */
11 /* This program is free software; you can redistribute it and/or modify */
12 /* it under the terms of the GNU General Public License as published by */
13 /* the Free Software Foundation; either Version 3, or (at your option) */
14 /* any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
24 /* */
25 /* FILE: z39.c */
26 /* MODULE: String Handler */
27 /* EXTERNS: AsciiToFull(), StringEqual(), */
28 /* StringCat(), StringCopy(), StringLength(), */
29 /* StringFOpen(), StringFPuts(), StringRemove(), */
30 /* StringRename(), StringBeginsWith(), StringContains(), */
31 /* StringInt(), StringFiveInt(), StringQuotedWord() */
32 /* */
33 /*****************************************************************************/
34 #include "externs.h"
35
36
37 /*****************************************************************************/
38 /* */
39 /* AsciiToFull(str) Returns ASCII string as FULL_CHARs. */
40 /* BOOLEAN StringEqual(a, b) TRUE if strings a and b are equal */
41 /* StringCat(a, b) Catenate string b onto end of a */
42 /* StringCopy(a, b) Overwrite string a with string b */
43 /* StringLength(a) Length of string a */
44 /* StringFOpen(str, mode) Equivalent to fopen(str, mode) */
45 /* StringFPuts(str, fp) Equivalent to fputs(str, fp) */
46 /* StringRemove(a) Equivalent to remove(a) */
47 /* StringRename(a, b) Equivalent to rename(a, b) */
48 /* */
49 /* These procedures are defined as macros in file externs. */
50 /* */
51 /*****************************************************************************/
52
53
54 /*****************************************************************************/
55 /* */
56 /* int strcollcmp(char *a, char *b) */
57 /* */
58 /* Written by Valery Ushakov (uwe). */
59 /* */
60 /* Like strcoll, but returns 0 only iff strcmp returns 0. */
61 /* This allow to test for equality using only strcmp. --uwe */
62 /* */
63 /* The new version of strcollcmp analyses a and b into three fields */
64 /* separated by \t, then does the comparison field by field. This is */
65 /* to ensure that the collation order of \t has no effect on the result. */
66 /* */
67 /*****************************************************************************/
68
69 /* *** old version
70 int strcollcmp(char *a, char *b)
71 {
72 int order = strcoll (a, b);
73 if( order == 0 ) / * then disambiguate with strcmp * /
74 order = strcmp (a, b);
75 return order;
76 }
77 *** */
78
strcollcmp(char * a,char * b)79 int strcollcmp(char *a, char *b)
80 { char a1[MAX_BUFF], a2[MAX_BUFF], a3[MAX_BUFF];
81 char b1[MAX_BUFF], b2[MAX_BUFF], b3[MAX_BUFF];
82 int order;
83 a1[0] = a2[0] = a3[0] = '\0';
84 sscanf(a, "%[^\t]\t%[^\t]\t%[^\t]", a1, a2, a3);
85 b1[0] = b2[0] = b3[0] = '\0';
86 sscanf(b, "%[^\t]\t%[^\t]\t%[^\t]", b1, b2, b3);
87 order = strcoll(a1, b1);
88 if( order == 0 )
89 {
90 order = strcoll(a2, b2);
91 if( order == 0 )
92 {
93 order = strcoll(a3, b3);
94 if( order == 0 )
95 order = strcmp(a, b); /* disambiguate with strcmp */
96 }
97 }
98 debug7(DBS, D, "strcollcmp(\"%s<tab>%s<tab>%s\", \"%s<tab>%s<tab>%s\") = %d",
99 a1, a2, a3, b1, b2, b3, order);
100 return order;
101 }
102
103 /*@::StringBeginsWith(), StringContains(), StringInt(), StringFiveInt()@******/
104 /* */
105 /* BOOLEAN StringBeginsWith(str, pattern) */
106 /* BOOLEAN StringBeginsWithWord(str, pattern) */
107 /* BOOLEAN StringEndsWith(str, pattern) */
108 /* */
109 /* Check whether str begins with or ends with pattern; in the case of */
110 /* StringBeginsWithWord there may not be a letter after the pattern. */
111 /* */
112 /*****************************************************************************/
113
StringBeginsWith(FULL_CHAR * str,FULL_CHAR * pattern)114 BOOLEAN StringBeginsWith(FULL_CHAR *str, FULL_CHAR *pattern)
115 { FULL_CHAR *sp, *pp;
116 sp = str; pp = pattern;
117 while( *sp != '\0' && *pp != '\0' )
118 { if( *sp++ != *pp++ ) return FALSE;
119 }
120 return (*pp == '\0');
121 } /* end StringBeginsWith */
122
123 #define is_letter(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
124
StringBeginsWithWord(FULL_CHAR * str,FULL_CHAR * pattern)125 BOOLEAN StringBeginsWithWord(FULL_CHAR *str, FULL_CHAR *pattern)
126 { FULL_CHAR *sp, *pp;
127 sp = str; pp = pattern;
128 while( *sp != '\0' && *pp != '\0' )
129 { if( *sp++ != *pp++ ) return FALSE;
130 }
131 return (*pp == '\0' && !is_letter(*sp));
132 } /* end StringBeginsWithWord */
133
134
StringEndsWith(FULL_CHAR * str,FULL_CHAR * pattern)135 BOOLEAN StringEndsWith(FULL_CHAR *str, FULL_CHAR *pattern)
136 { FULL_CHAR *sp, *pp; int slen, plen;
137 slen = StringLength(str);
138 plen = StringLength(pattern);
139 if( slen < plen ) return FALSE;
140 sp = &str[slen - plen]; pp = pattern;
141 while( *sp != '\0' && *pp != '\0' )
142 { if( *sp++ != *pp++ ) return FALSE;
143 }
144 return (*pp == '\0');
145 } /* end StringBeginsWith */
146
147
148 /*****************************************************************************/
149 /* */
150 /* BOOLEAN StringContains(str, pattern) */
151 /* */
152 /* Check whether str contains pattern. */
153 /* */
154 /*****************************************************************************/
155
StringContains(FULL_CHAR * str,FULL_CHAR * pattern)156 BOOLEAN StringContains(FULL_CHAR *str, FULL_CHAR *pattern)
157 { FULL_CHAR *sp;
158 for( sp = str; *sp != '\0'; sp++ )
159 { if( StringBeginsWith(sp, pattern) ) return TRUE;
160 }
161 return FALSE;
162 } /* end StringContains */
163
164
165 /*****************************************************************************/
166 /* */
167 /* FULL_CHAR *StringInt(i) */
168 /* FULL_CHAR *StringFiveInt(i) */
169 /* */
170 /* Returns a string version of integer i. */
171 /* */
172 /*****************************************************************************/
173
StringInt(int i)174 FULL_CHAR *StringInt(int i)
175 { static FULL_CHAR buff[20];
176 sprintf( (char *) buff, "%d", i);
177 return buff;
178 } /* end StringInt */
179
StringFiveInt(int i)180 FULL_CHAR *StringFiveInt(int i)
181 { static FULL_CHAR buff[20];
182 sprintf( (char *) buff, "%.5d", i);
183 return buff;
184 } /* end StringInt */
185
186
187 /*@::StringQuotedWord()@******************************************************/
188 /* */
189 /* static char *quoted_string[] */
190 /* */
191 /* quoted_string[ch] is a string containing the representation of the */
192 /* 8-bit character ch within a quoted string in a Lout source file. */
193 /* */
194 /*****************************************************************************/
195
196 static char *quoted_string[] = {
197 "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
198 "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
199 "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
200 "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
201 " ", "!", "\\\"", "#", "$", "%", "&", "'",
202 "(", ")", "*", "+", ",", "-", ".", "/",
203 "0", "1", "2", "3", "4", "5", "6", "7",
204 "8", "9", ":", ";", "<", "=", ">", "?",
205
206 "@", "A", "B", "C", "D", "E", "F", "G",
207 "H", "I", "J", "K", "L", "M", "N", "O",
208 "P", "Q", "R", "S", "T", "U", "V", "W",
209 "X", "Y", "Z", "[", "\\\\", "]", "^", "_",
210 "`", "a", "b", "c", "d", "e", "f", "g",
211 "h", "i", "j", "k", "l", "m", "n", "o",
212 "p", "q", "r", "s", "t", "u", "v", "w",
213 "x", "y", "z", "{", "|", "}", "~", "\\177",
214
215 "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
216 "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
217 "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
218 "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
219 "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
220 "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
221 "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
222 "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
223
224 "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
225 "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
226 "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
227 "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
228 "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
229 "\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357",
230 "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
231 "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377",
232 };
233
234
235 /*****************************************************************************/
236 /* */
237 /* FULL_CHAR *StringQuotedWord(x) */
238 /* */
239 /* Returns the string in QWORD x in the form it would need to take if it */
240 /* was a quoted word in a Lout source file. Note that the result is */
241 /* returned in a static variable so it needs to be copied before a */
242 /* subsequent call to StringQuotedWord is made. */
243 /* */
244 /*****************************************************************************/
245
StringQuotedWord(OBJECT x)246 FULL_CHAR *StringQuotedWord(OBJECT x)
247 { FULL_CHAR *p, *q, *r;
248 static FULL_CHAR buff[MAX_BUFF];
249 assert( type(x) == QWORD, "StringQuotedWord: type(x) != QWORD!" );
250 q = buff;
251 *q++ = CH_QUOTE;
252 for( p = string(x); *p != '\0'; p++ )
253 {
254 for( r = (FULL_CHAR *) quoted_string[*p]; *r != '\0'; *q++ = *r++ );
255 }
256 *q++ = CH_QUOTE;
257 *q++ = '\0';
258 return buff;
259 } /* StringQuotedWord */
260