Annotation of OpenXM_contrib2/fep/fep_util.c, Revision 1.5
1.1 noro 1: /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
2:
1.4 fujimoto 3: #if defined(ANDROID)
4: #include <strings.h>
5: #define index(s,c) strchr(s,c)
6: #define rindex(s,c) strrchr(s,c)
7: #endif
8:
1.1 noro 9: #ifndef lint
10: static char rcsid[]=
11: "$Header: fep_util.c,v 4.1 88/08/28 18:57:41 utashiro Exp $ (SRA)";
12: #endif /* lint */
13:
14: #ifndef MKARGDEBUG
15:
16: #include <stdio.h>
1.5 ! noro 17: #include <stdlib.h>
! 18: #include <unistd.h>
1.3 ohara 19: #include <string.h>
1.1 noro 20: #include <pwd.h>
21: #include <sys/types.h>
1.4 fujimoto 22: #if defined(__CYGWIN__) || defined(sun) || defined(ANDROID)
1.1 noro 23: #include <dirent.h>
24: #else
25: #include <sys/dir.h>
26: #endif
27: #include <ctype.h>
28: #include "fep_defs.h"
1.5 ! noro 29: #include "fep_funcs.h"
1.1 noro 30:
1.5 ! noro 31: void message(char *messageString)
1.1 noro 32: {
33: write (2, messageString, strlen (messageString));
34: }
35:
1.5 ! noro 36: void errorBell()
1.1 noro 37: {
38: write (2, "\007", 1);
39: }
40:
1.5 ! noro 41: void ctlprint(char *string)
1.1 noro 42: {
43: register char *cp;
44:
45: for (cp = string; *cp; cp++) {
46: if (isctlchar (*cp)) {
47: putchar ('^');
48: putchar (unctl (*cp));
49: }
50: else
51: putchar (*cp);
52: }
53: fputs ("\r\n", stdout);
54: fflush (stdout);
55: }
56:
57: /*
58: * Print string using "^" for control characters
59: */
1.5 ! noro 60: void printS (char *string)
1.1 noro 61: {
62: char *cp;
63:
64: for (cp = string; *cp; cp++)
65: putChar (*cp);
66: }
67:
68: /*
69: * Check the line is empty or not
70: */
1.5 ! noro 71: int is_empty_line(char *line)
1.1 noro 72: {
73: register char *cp;
74:
75: for (cp = line; *cp; cp++) {
76: if (!isspace(*cp)) {
77: return(0);
78: }
79: }
80: return(1);
81: }
82:
83: /*
84: * Put character using "^" for control characters
85: */
1.5 ! noro 86: void putChar(char c)
1.1 noro 87: {
88: if (isctlchar(c)) {
89: (void) putchar('^');
90: (void) putchar(unctl(c));
91: }
92: else
93: (void) putchar(c);
94: }
95:
1.5 ! noro 96: char * x_dirname (char *dir)
1.1 noro 97: {
98: static char dirname [256];
1.4 fujimoto 99: #if !defined(ANDROID)
1.1 noro 100: char *index();
1.4 fujimoto 101: #endif
1.1 noro 102:
103: if (*dir != '~')
104: strcpy (dirname, dir);
105: else {
106: struct passwd *pw;
107:
108: if (*(dir+1) == '/' || *(dir+1) == '\0') {
109: pw = getpwuid (getuid ());
110: }
111: else {
112: char user [64], *sp, *dp;
113:
114: for (sp = dir+1, dp = user; *sp && *sp != '/'; sp++, dp++)
115: *dp = *sp;
116: *dp = '\0';
117: pw = getpwnam (user);
118: }
119:
120: if (pw) {
121: strcpy (dirname, pw->pw_dir);
122: if (any ('/', dir))
123: strcat (dirname, index (dir, '/'));
124: }
125: else {
126: strcpy (dirname, dir);
127: }
128: }
129:
130: return (dirname);
131: }
132:
1.5 ! noro 133: DIR * x_opendir (char *dir)
1.1 noro 134: {
135: return (opendir (x_dirname (dir)));
136: }
137:
138: /*
139: * Strring compare for qsort
140: */
1.5 ! noro 141: int scmp (char **a, char **b)
1.1 noro 142: {
143:
144: return (strcmp (*a, *b));
145: }
146:
147: /*
148: * Return 1 if "str" is prefixed by "sub"
149: */
1.5 ! noro 150: int prefix (char *sub, char *str)
1.1 noro 151: {
152:
153: for (;;) {
154: if (*sub == 0)
155: return (1);
156: if (*str == 0)
157: return (0);
158: if (*sub++ != *str++)
159: return (0);
160: }
161: }
162:
163: /*
164: * Return 1 if s includes character c
165: */
1.5 ! noro 166: int any (int c, char *s)
1.1 noro 167: {
168:
169: while (*s)
170: if (*s++ == c)
171: return(1);
172: return(0);
173: }
174:
175: #ifndef max
176: /*
177: * Return maximum number of d1 and d2
178: */
1.5 ! noro 179: int max (int d1, int d2)
1.1 noro 180: {
181: return (d1 > d2 ? d1 : d2);
182: }
183: #endif /* max */
184:
185: #else /* MKARGDEBUG */
186:
187: #include <stdio.h>
188: #include <ctype.h>
189:
190: #define MAXARGS 64
191:
192: main()
193: {
194: char s[128];
195: char *argv[MAXARGS];
196:
197: while (gets (s)) {
198: register int c;
199:
200: showArgs (s);
201: }
202: }
203: #endif /* MKARGDEBUG */
204:
1.5 ! noro 205: void showArgs (char *comline)
1.1 noro 206: {
207: char *argv[MAXARGS];
208: register int c;
209: register char **argp;
210: register int i;
211:
212: c = mkargv (comline, argv, MAXARGS);
213: if (c < 0) {
214: printf ("%s\n", argv[0]);
215: return;
216: }
217: printf ("argc = %d\n", c);
218: for (i = 0, argp = argv; *argp; argp++, i++) {
219: printf ("\"%s\" ", *argp);
220: }
221: printf ("\n");
222: }
223:
1.5 ! noro 224: int mkargv (char *s, char *argv[], int maxarg)
1.1 noro 225: {
226: register char *cp;
227: register int argc = 0;
228: int insquot = 0, indquot = 0, ignorenext = 0;
229: enum {STRING, SPACE} status = SPACE;
230: static char buf[1024], *bp;
231:
232: for (cp = s, bp = buf; *cp; cp++) {
233:
234: if (argc > maxarg)
235: return (argc);
236:
237: /*
238: * Found white space
239: */
240: if (isspace (*cp)) {
241: /*
242: * In outside of quotation
243: */
244: if (!ignorenext && !insquot && !indquot) {
245: /*
246: * If status was in string, go next arg
247: */
248: if (status == STRING) {
249: status = SPACE;
250: *bp++ = '\0';
251: continue;
252: }
253: else
254: continue;
255: }
256: }
257:
258: # define SPECIALCHARS "\"\'\\"
259: if (!ignorenext && index (SPECIALCHARS, *cp)) {
260: switch (*cp) {
261:
262: /*
263: * Literal next character
264: */
265: case '\\':
266: if (indquot || insquot)
267: goto THROUGH;
268: else {
269: ignorenext = 1;
270: continue;
271: }
272:
273: /*
274: * Double quotation
275: */
276: case '\"':
277: if (insquot)
278: goto THROUGH;
279: if (indquot && *(bp-1) == '\\') {
280: bp--;
281: goto THROUGH;
282: }
283: indquot = !indquot;
284: break;
285:
286: /*
287: * Single quotation
288: */
289: case '\'':
290: if (indquot)
291: goto THROUGH;
292: if (insquot && *(bp-1) == '\\') {
293: bp--;
294: goto THROUGH;
295: }
296: insquot = !insquot;
297: break;
298: }
299:
300: /*
301: * Only in " or ' case.
302: */
303: if (status == SPACE) {
304: status = STRING;
305: argc++;
306: argv[argc-1] = bp;
307: *bp = 0;
308: }
309: continue;
310: }
311:
312: THROUGH:
313: /*
314: * Found non-space character
315: */
316: ignorenext = 0;
317: if (status == SPACE) {
318: status = STRING;
319: argc++;
320: argv[argc-1] = bp;
321: }
322: *bp++ = *cp;
323: }
324:
325: if (indquot || insquot) {
326: argv[0] = indquot ? "Unmatched \"." : "Unmatched \'.";
327: return (-1);
328: }
329:
330: *bp = '\0';
331: argv[argc] = (char *)0;
332: return (argc);
333: }
334:
1.5 ! noro 335: void reverse_strcpy (char *to, char *from)
1.1 noro 336: {
337: register int len;
338:
339: for (len = strlen (from); len >= 0; len--)
340: *(to + len) = *(from + len);
341: }
342:
1.5 ! noro 343: char *search_string (char *s, char *lookup)
1.1 noro 344: {
345: int len = strlen (lookup);
346: enum {SQUOTE, DQUOTE, NORMAL} status = NORMAL;
347:
348: while (*s) {
349: switch (*s) {
350: case '\'':
351: if (status == DQUOTE) break;
352: status = (status == SQUOTE) ? NORMAL : SQUOTE;
353: break;
354:
355: case '\"':
356: if (status == SQUOTE) break;
357: status = (status == DQUOTE) ? NORMAL : DQUOTE;
358: break;
359:
360: case '\\':
361: ++s;
362: break;
363: }
364: if (!*s) break;
365: if (status == NORMAL && strncmp (s, lookup, len) == 0)
366: return s;
367: ++s;
368: }
369: return ((char*) 0);
370: }
371:
372: #ifdef KANJI
373: /*
374: * Uuuuuuuum. I hate search kanji in Shift-JIS code from the end of string
375: * This function check if i'th character is first byte of KANJI code
376: * in string starting from s.
377: * It is assumed that first byte of strint s can't be second byte of KANJI
378: * code.
379: */
1.5 ! noro 380: int iskanji_in_string (char *s, int i)
1.1 noro 381: {
382: register char *cp = s, *target = s + i;
383:
384: if (i < 0)
385: return (0);
386:
387: while (cp < target) {
388: if (iskanji (*cp))
389: cp += 2;
390: else
391: cp++;
392: }
393:
394: if (cp != target)
395: return (0);
396: else
397: return (iskanji (*cp));
398: }
399: #endif /* KANJI */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>