Beispiel #1
0
static string
kpse_brace_expand_element P1C(const_string, elt)
{
  unsigned i;
  str_list_type expansions = brace_expand (&elt);
  string ret = (string)xmalloc (1);
  *ret = 0;

  for (i = 0; i != STR_LIST_LENGTH(expansions); i++) {
    /* Do $ and ~ expansion on each element.  */
    string x = kpse_expand (STR_LIST_ELT(expansions,i));
    string save_ret = ret;
    if (!STREQ (x, STR_LIST_ELT(expansions,i))) {
      /* If we did any expansions, do brace expansion again.  Since
         recursive variable definitions are not allowed, this recursion
         must terminate.  (In practice, it's unlikely there will ever be
         more than one level of recursion.)  */
      string save_x = x;
      x = kpse_brace_expand_element (x);
      free (save_x);
    }
    ret = concat3 (ret, x, ENV_SEP_STRING);
    free (save_ret);
    free (x);
  }
  for (i = 0; i != STR_LIST_LENGTH(expansions); ++i) {
      free(STR_LIST_ELT(expansions,i));
  }
  str_list_free(&expansions);
  ret[strlen (ret) - 1] = 0; /* waste the trailing null */
  return ret;
}
Beispiel #2
0
static str_list_type brace_expand P1C(const_string *, text)
{
    str_list_type result, partial, recurse;
    const_string p;
    result = str_list_init();
    partial = str_list_init();
    for (p = *text; *p && *p != '}'; ++p) {
        /* FIXME: Should be IS_ENV_SEP(*p) */
        if (*p == ENV_SEP || *p == ',') {
            expand_append(&partial, *text, p);
            str_list_concat(&result, partial);
            str_list_free(&partial);
            *text = p+1;
            partial = str_list_init();
        } else if (*p == '{') {
            expand_append(&partial, *text, p);
            ++p;
            recurse = brace_expand(&p);
            str_list_concat_elements(&partial, recurse);
            str_list_free(&recurse);
            /* Check for missing closing brace. */
            if (*p != '}') {
                WARNING1 ("%s: Unmatched {", *text);
            }
            *text = p+1;
        } else if (*p == '$') {
            /* Skip ${VAR} */
            if (*(p+1) == '{')
                for (p+=2; *p!='}';++p);
        }
    }
    expand_append(&partial, *text, p);
    str_list_concat(&result, partial);
    str_list_free(&partial);
    *text = p;
    return result;
}
Beispiel #3
0
static SgObject brace_expand(SgString *str, int flags)
{
  const int escape = !(flags & SG_NOESCAPE);
  int lbrace = 0, rbrace = 0, nest = 0, i;
  int haslb = FALSE, hasrb = FALSE;

  /* find { and }*/
  for (i = 0; i < SG_STRING_SIZE(str); i++) {
    if (SG_STRING_VALUE_AT(str, i) == '{' && nest++ == 0) {
      lbrace = i;
      haslb = TRUE;
    }
    if (SG_STRING_VALUE_AT(str, i) == '}' && --nest == 0) {
      rbrace = i;
      hasrb = TRUE;
      break;
    }
    if (SG_STRING_VALUE_AT(str, i) == '\\' && escape) {
      if (++i == SG_STRING_SIZE(str)) break;
    }
  }
  /* make "foo/{a,b}" to ("foo/a" "foo/b") */
  if (haslb && hasrb) {
    SgObject h = SG_NIL, t = SG_NIL;
    SgPort *out;
    SgStringPort tp;
    int i;
    /* copy value until the first '{' */
    out = Sg_InitStringOutputPort(&tp, 255);
    for (i = 0; i < lbrace; i++) {
      Sg_PutcUnsafe(out, SG_STRING_VALUE_AT(str, i));
    }
    /* skip '{' */
    i++;
    while (i < rbrace) {
      /* now we need to copy one by one */
      int nest = 0, j;
      SgObject tmp;
      for (;SG_STRING_VALUE_AT(str, i) != ',' || nest != 0; i++) {
	if (i >= rbrace) break;

  	if (SG_STRING_VALUE_AT(str, i) == '{') nest++;
  	if (SG_STRING_VALUE_AT(str, i) == '}') nest--;
  	if (SG_STRING_VALUE_AT(str, i) == '\\' && escape) {
  	  if (++i == rbrace) break;
  	}
  	Sg_PutcUnsafe(out, SG_STRING_VALUE_AT(str, i));
      }
      /* skip ',' */
      i++;
      /* copy after the '}' */
      for (j = rbrace+1; j < SG_STRING_SIZE(str); j++) {
  	Sg_PutcUnsafe(out, SG_STRING_VALUE_AT(str, j));
      }
      tmp = Sg_GetStringFromStringPort(&tp);
      SG_APPEND(h, t, brace_expand(tmp, flags));
      /* back to the starting position */
      Sg_SetPortPosition(out, lbrace, SG_BEGIN);
    }
    SG_CLEAN_STRING_PORT(&tp);
    return h;
  } else {
    return SG_LIST1(str);
  }
}