228 lines
5.0 KiB
C
228 lines
5.0 KiB
C
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|
**********/
|
|
|
|
/*
|
|
* Expand global characters.
|
|
*/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/cpdefs.h"
|
|
#include "glob.h"
|
|
|
|
#ifdef HAVE_SYS_DIR_H
|
|
#include <sys/types.h>
|
|
#include <sys/dir.h>
|
|
#else
|
|
|
|
#ifdef HAVE_DIRENT_H
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#ifndef direct
|
|
#define direct dirent
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_PWD_H
|
|
#include <pwd.h>
|
|
#endif
|
|
|
|
|
|
char cp_comma = ',';
|
|
char cp_ocurl = '{';
|
|
char cp_ccurl = '}';
|
|
char cp_til = '~';
|
|
|
|
static wordlist *bracexpand(char *string);
|
|
static wordlist *brac1(char *string);
|
|
static wordlist *brac2(char *string);
|
|
|
|
|
|
/* For each word, go through two steps: expand the {}'s, and then do ?*[]
|
|
* globbing in them. Sort after the second phase but not the first...
|
|
*/
|
|
|
|
/* MW. Now only tilde is supported, {}*? don't work */
|
|
|
|
wordlist *
|
|
cp_doglob(wordlist *wlist)
|
|
{
|
|
wordlist *wl;
|
|
char *s;
|
|
|
|
/* Expand {a,b,c} */
|
|
|
|
for (wl = wlist; wl; wl = wl->wl_next) {
|
|
wordlist *nwl, *w = bracexpand(wl->wl_word);
|
|
if (!w) {
|
|
wlist->wl_word = NULL; /* XXX */
|
|
return (wlist);
|
|
}
|
|
nwl = wl_splice(wl, w);
|
|
if (wlist == wl)
|
|
wlist = w;
|
|
wl = nwl;
|
|
}
|
|
|
|
/* Do tilde expansion. */
|
|
|
|
for (wl = wlist; wl; wl = wl->wl_next)
|
|
if (*wl->wl_word == cp_til) {
|
|
s = cp_tildexpand(wl->wl_word);
|
|
txfree(wl->wl_word); /* sjb - fix memory leak */
|
|
if (!s)
|
|
*wl->wl_word = '\0'; /* MW. We Con't touch tmalloc addres */
|
|
else
|
|
wl->wl_word = s;
|
|
}
|
|
|
|
return (wlist);
|
|
}
|
|
|
|
|
|
static wordlist *
|
|
bracexpand(char *string)
|
|
{
|
|
wordlist *wl, *w;
|
|
char *s;
|
|
|
|
if (!string)
|
|
return (NULL);
|
|
wl = brac1(string);
|
|
if (!wl)
|
|
return (NULL);
|
|
for (w = wl; w; w = w->wl_next) {
|
|
s = w->wl_word;
|
|
w->wl_word = copy(s);
|
|
tfree(s);
|
|
}
|
|
return (wl);
|
|
}
|
|
|
|
/* Given a string, returns a wordlist of all the {} expansions. This is
|
|
* called recursively by cp_brac2(). All the words here will be of size
|
|
* BSIZE_SP, so it is a good idea to copy() and free() the old words.
|
|
*/
|
|
|
|
static wordlist *
|
|
brac1(char *string)
|
|
{
|
|
wordlist *words, *wl, *w, *nw, *nwl, *newwl;
|
|
char *s;
|
|
int nb;
|
|
|
|
words = wl_cons(TMALLOC(char, BSIZE_SP), NULL);
|
|
words->wl_word[0] = '\0';
|
|
for (s = string; *s; s++) {
|
|
if (*s == cp_ocurl) {
|
|
nwl = brac2(s);
|
|
nb = 0;
|
|
for (;;) {
|
|
if (*s == cp_ocurl)
|
|
nb++;
|
|
if (*s == cp_ccurl)
|
|
nb--;
|
|
if (*s == '\0') {
|
|
fprintf(cp_err, "Error: missing }.\n");
|
|
return (NULL);
|
|
}
|
|
if (nb == 0)
|
|
break;
|
|
s++;
|
|
}
|
|
/* Add nwl to the rest of the strings in words. */
|
|
newwl = NULL;
|
|
for (wl = words; wl; wl = wl->wl_next)
|
|
for (w = nwl; w; w = w->wl_next) {
|
|
nw = wl_cons(TMALLOC(char, BSIZE_SP), NULL);
|
|
(void) strcpy(nw->wl_word, wl->wl_word);
|
|
(void) strcat(nw->wl_word, w->wl_word);
|
|
newwl = wl_append(newwl, nw);
|
|
}
|
|
wl_free(words);
|
|
wl_free(nwl);
|
|
words = newwl;
|
|
} else {
|
|
for (wl = words; wl; wl = wl->wl_next)
|
|
appendc(wl->wl_word, *s);
|
|
}
|
|
}
|
|
return (words);
|
|
}
|
|
|
|
/* Given a string starting with a {, return a wordlist of the expansions
|
|
* for the text until the matching }.
|
|
*/
|
|
|
|
static wordlist *
|
|
brac2(char *string)
|
|
{
|
|
wordlist *wlist = NULL, *nwl;
|
|
char buf[BSIZE_SP], *s;
|
|
int nb;
|
|
bool eflag = FALSE;
|
|
|
|
string++; /* Get past the first open brace... */
|
|
for (;;) {
|
|
(void) strcpy(buf, string);
|
|
nb = 0;
|
|
s = buf;
|
|
for (;;) {
|
|
if ((*s == cp_ccurl) && (nb == 0)) {
|
|
eflag = TRUE;
|
|
break;
|
|
}
|
|
if ((*s == cp_comma) && (nb == 0))
|
|
break;
|
|
if (*s == cp_ocurl)
|
|
nb++;
|
|
if (*s == cp_ccurl)
|
|
nb--;
|
|
if (*s == '\0') {
|
|
fprintf(cp_err, "Error: missing }.\n");
|
|
return (NULL);
|
|
}
|
|
s++;
|
|
}
|
|
*s = '\0';
|
|
nwl = brac1(buf);
|
|
wlist = wl_append(wlist, nwl);
|
|
string += s - buf + 1;
|
|
if (eflag)
|
|
return (wlist);
|
|
}
|
|
}
|
|
|
|
/* Expand tildes. */
|
|
|
|
char *
|
|
cp_tildexpand(char *string)
|
|
{
|
|
char *result;
|
|
|
|
result = tildexpand(string);
|
|
|
|
if (!result) {
|
|
if (cp_nonomatch)
|
|
return copy(string);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/* Say whether the pattern p can match the string s. */
|
|
|
|
/* MW. Now simply compare strings */
|
|
|
|
bool
|
|
cp_globmatch(char *p, char *s)
|
|
{
|
|
return (!(strcmp(p, s)));
|
|
}
|