Exemplo n.º 1
0
/*
 *  Do file globbing:
 *	- appends * to (copy of) str if no globbing chars found
 *	- does expansion, checks for no match, etc.
 *	- sets *wordsp to array of matching strings
 *	- returns number of matching strings
 */
static int
x_file_glob(int flags, const char *str, int slen, char ***wordsp)
{
	char *toglob;
	char **words;
	int nwords;
	XPtrV w;
	struct source *s, *sold;

	if (slen < 0)
		return 0;

	toglob = add_glob(str, slen);

	/*
	 * Convert "foo*" (toglob) to an array of strings (words)
	 */
	sold = source;
	s = pushs(SWSTR, ATEMP);
	s->start = s->str = toglob;
	source = s;
	if (yylex(ONEWORD|UNESCAPE) != LWORD) {
		source = sold;
		internal_errorf(0, "fileglob: substitute error");
		return 0;
	}
	source = sold;
	XPinit(w, 32);
	expand(yylval.cp, &w, DOGLOB|DOTILDE|DOMARKDIRS);
	XPput(w, NULL);
	words = (char **) XPclose(w);

	for (nwords = 0; words[nwords]; nwords++)
		;
	if (nwords == 1) {
		struct stat statb;

		/* Check if file exists, also, check for empty
		 * result - happens if we tried to glob something
		 * which evaluated to an empty string (e.g.,
		 * "$FOO" when there is no FOO, etc).
		 */
		 if ((lstat(words[0], &statb) < 0) ||
		    words[0][0] == '\0') {
			x_free_words(nwords, words);
			words = NULL;
			nwords = 0;
		}
	}
	afree(toglob, ATEMP);

	if (nwords) {
		*wordsp = words;
	} else if (words) {
		x_free_words(nwords, words);
		*wordsp = NULL;
	}

	return nwords;
}
Exemplo n.º 2
0
static void		check_match(char *temp, t_gb *gb, int len, char flag)
{
  glob_t		gl;

  if (flag)
    {
      glob(temp, 0, NULL, &gl);
      if (gl.gl_pathc == 1)
	add_glob(gb, gl.gl_pathv[0], len);
    }
  temp[my_strlen(temp)] = '*';
}
Exemplo n.º 3
0
int			get_data(char *path, char *word, t_gb *gb)
{
  char			*temp;
  glob_t		gl;
  int			len;
  int			i;

  i = -1;
  if (!(temp = get_fusion(path, word, &len)))
    return (FAILURE);
  check_match(temp, gb, len, *path);
  glob(temp, GLOB_TILDE_CHECK, NULL, &gl);
  XFREE(temp);
  if (gl.gl_pathc <= 0)
    return (FAILURE);
  while (++i < (int)gl.gl_pathc)
    if (add_glob(gb, gl.gl_pathv[i], len) == FAILURE)
      return (FAILURE);
  globfree(&gl);
  return (SUCCESS);
}
Exemplo n.º 4
0
void parse_globs(w_query* res, const json_ref& query) {
  size_t i;
  int noescape = 0;
  int includedotfiles = 0;

  auto globs = query.get_default("glob");
  if (!globs) {
    return;
  }

  if (!json_is_array(globs)) {
    throw QueryParseError("'glob' must be an array");
  }

  // Globs implicitly enable dedup_results mode
  res->dedup_results = true;

  if (json_unpack(query, "{s?b}", "glob_noescape", &noescape) != 0) {
    throw QueryParseError("glob_noescape must be a boolean");
  }

  if (json_unpack(query, "{s?b}", "glob_includedotfiles", &includedotfiles) !=
      0) {
    throw QueryParseError("glob_includedotfiles must be a boolean");
  }

  res->glob_flags =
      (includedotfiles ? 0 : WM_PERIOD) | (noescape ? WM_NOESCAPE : 0);

  res->glob_tree = watchman::make_unique<watchman_glob_tree>("", 0);
  for (i = 0; i < json_array_size(globs); i++) {
    const auto& ele = globs.at(i);
    const auto& pattern = json_to_w_string(ele);

    if (!add_glob(res->glob_tree.get(), pattern)) {
      throw QueryParseError("failed to compile multi-glob");
    }
  }
}
Exemplo n.º 5
0
static int
x_command_glob(int flags, const char *str, int slen, char ***wordsp)
{
	char *toglob;
	char *pat;
	char *fpath;
	int nwords;
	XPtrV w;
	struct block *l;

	if (slen < 0)
		return 0;

	toglob = add_glob(str, slen);

	/* Convert "foo*" (toglob) to a pattern for future use */
	pat = evalstr(toglob, DOPAT|DOTILDE);
	afree(toglob, ATEMP);

	XPinit(w, 32);

	glob_table(pat, &w, &keywords);
	glob_table(pat, &w, &aliases);
	glob_table(pat, &w, &builtins);
	for (l = e->loc; l; l = l->next)
		glob_table(pat, &w, &l->funs);

	glob_path(flags, pat, &w, path);
	if ((fpath = str_val(global("FPATH"))) != null)
		glob_path(flags, pat, &w, fpath);

	nwords = XPsize(w);

	if (!nwords) {
		*wordsp = NULL;
		XPfree(w);
		return 0;
	}

	/* Sort entries */
	if (flags & XCF_FULLPATH) {
		/* Sort by basename, then path order */
		struct path_order_info *info;
		struct path_order_info *last_info = NULL;
		char **words = (char **) XPptrv(w);
		int path_order = 0;
		int i;

		info = areallocarray(NULL, nwords,
		    sizeof(struct path_order_info), ATEMP);

		for (i = 0; i < nwords; i++) {
			info[i].word = words[i];
			info[i].base = x_basename(words[i], NULL);
			if (!last_info || info[i].base != last_info->base ||
			    strncmp(words[i], last_info->word, info[i].base) != 0) {
				last_info = &info[i];
				path_order++;
			}
			info[i].path_order = path_order;
		}
		qsort(info, nwords, sizeof(struct path_order_info),
			path_order_cmp);
		for (i = 0; i < nwords; i++)
			words[i] = info[i].word;
		afree(info, ATEMP);
	} else {
		/* Sort and remove duplicate entries */
		char **words = (char **) XPptrv(w);
		int i, j;

		qsortp(XPptrv(w), (size_t) nwords, xstrcmp);

		for (i = j = 0; i < nwords - 1; i++) {
			if (strcmp(words[i], words[i + 1]))
				words[j++] = words[i];
			else
				afree(words[i], ATEMP);
		}
		words[j++] = words[i];
		nwords = j;
		w.cur = (void **) &words[j];
	}

	XPput(w, NULL);
	*wordsp = (char **) XPclose(w);

	return nwords;
}