17 #include "EST_Pathname.h"
18 #include "EST_cutils.h"
22 LISP strintern(
const char *data)
24 return strcons(strlen(data),data);
27 LISP strcons(
long length,
const char *data)
30 flag = no_interrupt(1);
33 s->storage_as.string.data = must_malloc(length+1);
34 s->storage_as.string.dim = length;
36 memmove(s->storage_as.string.data,data,length+1);
40 LISP cstrcons(
const char *data)
43 flag = no_interrupt(1);
46 s->storage_as.string.data = (
char *)(
void *)data;
47 s->storage_as.string.dim = strlen(data);
51 static int rfs_getc(
unsigned char **p)
58 static void rfs_ungetc(
unsigned char c,
unsigned char **p)
62 LISP read_from_lstring(LISP x)
63 {
return read_from_string(get_c_string(x));}
65 LISP read_from_string(
const char *
string)
71 s.getc_fcn = (int (*)(
char *))rfs_getc;
72 s.ungetc_fcn = (void (*)(int,
char *))rfs_ungetc;
73 s.cb_argument = (
char *) &p;
79 LISP string_append(LISP args)
84 for(l=args;NNULLP(l);l=cdr(l))
85 size += strlen(get_c_string(car(l)));
86 s = strcons(size,NULL);
87 data = s->storage_as.string.data;
89 for(l=args;NNULLP(l);l=cdr(l))
90 strcat(data,get_c_string(car(l)));
93 LISP string_length(LISP
string)
94 {
if NTYPEP(
string,tc_string) err("not a
string",
string);
95 return(flocons((
double)
string->storage_as.
string.dim));}
97 LISP parse_number(LISP x)
100 return(flocons(atof(c)));}
102 LISP string_downcase(LISP symbol)
104 const char *symname = get_c_string(symbol);
105 char *downsym = wstrdup(symname);
109 for (i=0; symname[i] !=
'\0'; i++)
110 if (isupper(symname[i]))
111 downsym[i] = tolower(symname[i]);
113 downsym[i] = symname[i];
115 newsym = strintern(downsym);
121 LISP string_upcase(LISP symbol)
123 const char *symname = get_c_string(symbol);
124 char *upsym = wstrdup(symname);
128 for (i=0; symname[i] !=
'\0'; i++)
129 if (islower(symname[i]))
130 upsym[i] = toupper(symname[i]);
132 upsym[i] = symname[i];
134 newsym = strintern(upsym);
140 LISP path_is_dirname(LISP lpath)
144 return path.is_dirname()?lpath:NIL;
147 LISP path_is_filename(LISP lpath)
151 return path.is_filename()?lpath:NIL;
154 LISP path_as_directory(LISP lpath)
158 return strintern(res);
161 LISP path_as_file(LISP lpath)
166 return strintern(res);
169 LISP path_append(LISP lpaths)
174 lpaths = cdr(lpaths);
177 res = res +get_c_string(car(lpaths));
178 lpaths = cdr(lpaths);
180 return strintern(res);
185 LISP path_basename(LISP lpath)
190 return strintern(res);
193 LISP symbol_basename(LISP path, LISP suffix)
196 const char *pathstr = get_c_string(path);
199 int i, j, k, start, end;
205 suff = get_c_string(suffix);
207 for (i=strlen(pathstr); i >= 0; i--)
208 if (pathstr[i] ==
'/')
211 for (j=strlen(pathstr),k=strlen(suff); k >= 0; k--,j--)
212 if (pathstr[j] != suff[k])
215 end = strlen(pathstr);
219 bname = walloc(
char,end-start+1);
220 memcpy(bname,&pathstr[start],end-start);
221 bname[end-start] =
'\0';
222 newsym = strcons(strlen(bname),bname);
229 static LISP lisp_to_string(LISP l)
234 printf(
"%s\n",(
const char *)s);
238 static LISP symbolconc(LISP args)
243 for(l=args;NNULLP(l);l=cdr(l))
245 if NSYMBOLP(s) err("wrong type of argument(non-symbol) to symbolconc",s);
246 size = size + strlen(PNAME(s));
247 if (size > TKBUFFERN) err("symbolconc buffer overflow",NIL);
248 strcat(tkbuffer,PNAME(s));}
249 return(rintern(tkbuffer));}
251 LISP symbolexplode(LISP name)
254 const char *pname = get_c_string(name);
260 for (i=0; pname[i] !=
'\0'; i++)
263 e = cons(rintern(tt),e);
268 LISP l_matches(LISP atom, LISP regex)
273 if (pname.
matches(make_regex(get_c_string(regex))) == TRUE)
279 LISP l_strequal(LISP atom1, LISP atom2)
282 if (streq(get_c_string(atom1),get_c_string(atom2)))
288 LISP l_substring(LISP
string, LISP l_start, LISP l_length)
292 if (NTYPEP(
string,tc_string))
293 err(
"not a string",
string);
295 const char *data =
string->storage_as.string.data;
296 int dim =
string->storage_as.string.dim;
298 int start = ( get_c_int(l_start) < dim ? get_c_int(l_start) : dim );
299 int length = ( (get_c_int(l_length) + start) < dim ?
304 char *nbuffer = walloc(
char, length+1);
305 memmove(nbuffer,data+start,length);
306 nbuffer[length] =
'\0';
308 LISP ncell = strcons(length, nbuffer);
315 static LISP l_sbefore(LISP atom, LISP before)
325 static LISP l_safter(LISP atom, LISP after)
335 void init_subrs_str(
void)
337 init_lsubr(
"string-append",string_append,
338 "(string-append STR1 STR2 ...)\n\
339 Return a string made from the concatenation of the print names of STR1\n\
341 init_subr_1(
"string-length",string_length,
342 "(string-length SYMBOL)\n\
343 Return the number of characters in the print name of SYMBOL.");
344 init_subr_1(
"print_string",lisp_to_string,
345 "(print_string DATA)\n\
346 Returns a string representing the printing of DATA." );
347 init_subr_1(
"read-from-string",read_from_lstring,
348 "(read-from-string SYMBOL)\n\
349 Return first s-expression in print name of SYMBOL.");
350 init_subr_1(
"downcase",string_downcase,
351 "(downcase SYMBOL)\n\
352 Returns a string with the downcased version of SYMBOL's printname.");
353 init_subr_1(
"upcase",string_upcase,
355 Returns a string with the upcased version of SYMBOL's printname.");
356 init_subr_2(
"string-matches",l_matches,
357 "(string-matches ATOM REGEX)\n\
358 Returns t if ATOM's printname matches the regular expression REGEX,\n\
359 otherwise it returns nil.");
360 init_subr_2(
"string-equal",l_strequal,
361 "(string-equal ATOM1 ATOM2)\n\
362 Returns t if ATOM's printname is equal to ATOM's print name, otherwise\n\
364 init_subr_3(
"substring", l_substring,
365 "(substring STRING START LENGTH)\n\
366 Return a substring of STRING starting at START of length LENGTH.");
367 init_subr_2(
"string-before",l_sbefore,
368 "(string-before ATOM BEFORE)\n\
369 Returns an atom whose printname is the substring of ATOM's printname \n\
370 which appears before BEFORE. This is a wraparound for the EST_String.before \n\
371 function in C++, and hence has the same conditions for boundary cases.");
372 init_subr_2(
"string-after",l_safter,
373 "(string-after ATOM AFTER)\n\
374 Returns an atom whose printname is the substring of ATOM's printname \n\
375 which appears after AFTER. This is a wraparound for the EST_String.after \n\
376 function in C++, and hence has the same conditions for boundary cases.");
378 init_lsubr(
"symbolconc",symbolconc,
379 "(symbolconc SYMBOL1 SYMBOL2 ...)\n\
380 Form new symbol by concatenation of the print forms of each of SYMBOL1\n\
382 init_subr_1(
"symbolexplode",symbolexplode,
383 "(symbolexplode SYMBOL)\n\
384 Returns list of atoms one for each character in the print name of SYMBOL.");
386 init_subr_1(
"parse-number",parse_number,
387 "(parse-number SYMBOL)\n\
388 Returns a number form a symbol or string whose print name is a number.");
390 init_subr_2(
"basename",symbol_basename,
391 "(basename PATH SUFFIX)\n\
392 Return a string with directory removed from basename. If SUFFIX is\n\
393 specified remove that from end of PATH. Basically the same function\n\
394 as the UNIX command of the same name.");
397 init_subr_1(
"path-is-filename", path_is_filename,
398 "(path-is-filename PATHNAME)\n\
399 Is PATH a non-directory name.");
401 init_subr_1(
"path-as-directory", path_as_directory,
402 "(path-as-directory PATHNAME)\n\
403 Return PATH as a directory name.");
405 init_subr_1(
"path-as-file", path_as_file,
406 "(path-as-file PATHNAME)\n\
407 Return PATH as a non-directory name.");
409 init_lsubr(
"path-append", path_append,
410 "(path-append DIRECTORY-PATH ADDITION1 ADDITION2 ...)\n\
411 Return a the path for ADDITION in DIRECTORY.");
413 init_subr_1(
"path-basename", path_basename,
414 "(path-basename PATHNAME)\n\
415 Return name part of PATH.");
418 init_subr_1(
"path-is-dirname", path_is_dirname,
419 "(path-is-dirname PATHNAME)\n\
420 Is PATH a directory name.");