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