Exemplo n.º 1
0
static void
xheader_set_keyword_equal (char *kw, char *eq)
{
  bool global = true;
  char *p = eq;

  if (eq[-1] == ':')
    {
      p--;
      global = false;
    }

  while (p > kw && isspace ((unsigned char) *p))
    p--;

  *p = 0;

  for (p = eq + 1; *p && isspace ((unsigned char) *p); p++)
    ;

  if (strcmp (kw, "delete") == 0)
    {
      if (xheader_protected_pattern_p (p))
	USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p)));
      xheader_list_append (&keyword_pattern_list, p, NULL);
    }
  else if (strcmp (kw, "exthdr.name") == 0)
    assign_string (&exthdr_name, p);
  else if (strcmp (kw, "globexthdr.name") == 0)
    assign_string (&globexthdr_name, p);
  else if (strcmp (kw, "exthdr.mtime") == 0)
    assign_time_option (&exthdr_mtime_option, &exthdr_mtime, p);
  else if (strcmp (kw, "globexthdr.mtime") == 0)
    assign_time_option (&globexthdr_mtime_option, &globexthdr_mtime, p);
  else
    {
      if (xheader_protected_keyword_p (kw))
	USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw));
      if (global)
	xheader_list_append (&keyword_global_override_list, kw, p);
      else
	xheader_list_append (&keyword_override_list, kw, p);
    }
}
Exemplo n.º 2
0
static const char *
parse_transform_expr (const char *expr)
{
  int delim;
  int i, j, rc;
  char *str, *beg, *cur;
  const char *p;
  int cflags = 0;
  struct transform *tf = new_transform ();

  if (expr[0] != 's')
    {
      if (strncmp (expr, "flags=", 6) == 0)
	{
	  transform_flags = 0;
	  for (expr += 6; *expr; expr++)
	    {
	      if (*expr == ';')
		{
		  expr++;
		  break;
		}
	      if (parse_xform_flags (&transform_flags, *expr))
		USAGE_ERROR ((0, 0, _("Unknown transform flag: %c"),
			      *expr));
	    }
	  return expr;
	}
      USAGE_ERROR ((0, 0, _("Invalid transform expression")));
    }

  delim = expr[1];

  /* Scan regular expression */
  for (i = 2; expr[i] && expr[i] != delim; i++)
    if (expr[i] == '\\' && expr[i+1])
      i++;

  if (expr[i] != delim)
    USAGE_ERROR ((0, 0, _("Invalid transform expression")));

  /* Scan replacement expression */
  for (j = i + 1; expr[j] && expr[j] != delim; j++)
    if (expr[j] == '\\' && expr[j+1])
      j++;

  if (expr[j] != delim)
    USAGE_ERROR ((0, 0, _("Invalid transform expression")));

  /* Check flags */
  tf->transform_type = transform_first;
  tf->flags = transform_flags;
  for (p = expr + j + 1; *p && *p != ';'; p++)
    switch (*p)
      {
      case 'g':
	tf->transform_type = transform_global;
	break;

      case 'i':
	cflags |= REG_ICASE;
	break;

      case 'x':
	cflags |= REG_EXTENDED;
	break;

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
	tf->match_number = strtoul (p, (char**) &p, 0);
	p--;
	break;

      default:
	if (parse_xform_flags (&tf->flags, *p))
	  USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
			*p));
      }

  if (*p == ';')
    p++;

  /* Extract and compile regex */
  str = xmalloc (i - 1);
  memcpy (str, expr + 2, i - 2);
  str[i - 2] = 0;

  rc = regcomp (&tf->regex, str, cflags);

  if (rc)
    {
      char errbuf[512];
      regerror (rc, &tf->regex, errbuf, sizeof (errbuf));
      USAGE_ERROR ((0, 0, _("Invalid transform expression: %s"), errbuf));
    }

  if (str[0] == '^' || str[strlen (str) - 1] == '$')
    tf->transform_type = transform_first;

  free (str);

  /* Extract and compile replacement expr */
  i++;
  str = xmalloc (j - i + 1);
  memcpy (str, expr + i, j - i);
  str[j - i] = 0;

  for (cur = beg = str; *cur;)
    {
      if (*cur == '\\')
	{
	  size_t n;

	  add_literal_segment (tf, beg, cur);
	  switch (*++cur)
	    {
	    case '0': case '1': case '2': case '3': case '4':
	    case '5': case '6': case '7': case '8': case '9':
	      n = strtoul (cur, &cur, 10);
	      if (n > tf->regex.re_nsub)
		USAGE_ERROR ((0, 0, _("Invalid transform replacement: back reference out of range")));
	      add_backref_segment (tf, n);
	      break;

	    case '\\':
	      add_char_segment (tf, '\\');
	      cur++;
	      break;

	    case 'a':
	      add_char_segment (tf, '\a');
	      cur++;
	      break;

	    case 'b':
	      add_char_segment (tf, '\b');
	      cur++;
	      break;

	    case 'f':
	      add_char_segment (tf, '\f');
	      cur++;
	      break;

	    case 'n':
	      add_char_segment (tf, '\n');
	      cur++;
	      break;

	    case 'r':
	      add_char_segment (tf, '\r');
	      cur++;
	      break;

	    case 't':
	      add_char_segment (tf, '\t');
	      cur++;
	      break;

	    case 'v':
	      add_char_segment (tf, '\v');
	      cur++;
	      break;

	    case '&':
	      add_char_segment (tf, '&');
	      cur++;
	      break;

	    case 'L':
	      /* Turn the replacement to lowercase until a '\U' or '\E'
		 is found, */
	      add_case_ctl_segment (tf, ctl_locase);
	      cur++;
	      break;

	    case 'l':
	      /* Turn the next character to lowercase, */
	      add_case_ctl_segment (tf, ctl_locase_next);
	      cur++;
	      break;

	    case 'U':
	      /* Turn the replacement to uppercase until a '\L' or '\E'
		 is found, */
	      add_case_ctl_segment (tf, ctl_upcase);
	      cur++;
	      break;

	    case 'u':
	      /* Turn the next character to uppercase, */
	      add_case_ctl_segment (tf, ctl_upcase_next);
	      cur++;
	      break;

	    case 'E':
	      /* Stop case conversion started by '\L' or '\U'. */
	      add_case_ctl_segment (tf, ctl_stop);
	      cur++;
	      break;

	    default:
	      /* Try to be nice */
	      {
		char buf[2];
		buf[0] = '\\';
		buf[1] = *cur;
		add_literal_segment (tf, buf, buf + 2);
	      }
	      cur++;
	      break;
	    }
	  beg = cur;
	}
      else if (*cur == '&')
	{
	  add_literal_segment (tf, beg, cur);
	  add_backref_segment (tf, 0);
	  beg = ++cur;
	}
      else
	cur++;
    }
  add_literal_segment (tf, beg, cur);

  return p;
}
Exemplo n.º 3
0
void
collect_and_sort_names (void)
{
  struct name *name;
  struct name *next_name, *prev_name;
  int num_names;
  struct stat statbuf;
  Hash_table *nametab;
  
  name_gather ();

  if (!namelist)
    addname (".", 0, false, NULL);

  if (listed_incremental_option)
    {
      switch (chdir_count ())
	{
	case 0:
	  break;

	case 1:
	  if (namelist->change_dir == 0)
	    USAGE_ERROR ((0, 0,
			  _("Using -C option inside file list is not "
			    "allowed with --listed-incremental")));
	  break;

	default:
	  USAGE_ERROR ((0, 0,
			_("Only one -C option is allowed with "
			  "--listed-incremental")));
	}

      read_directory_file ();
    }
  
  num_names = 0;
  for (name = namelist; name; name = name->next, num_names++)
    {
      if (name->found_count || name->directory)
	continue;
      if (name->matching_flags & EXCLUDE_WILDCARDS)
	/* NOTE: EXCLUDE_ANCHORED is not relevant here */
	/* FIXME: just skip regexps for now */
	continue;
      chdir_do (name->change_dir);

      if (name->name[0] == 0)
	continue;

      if (deref_stat (dereference_option, name->name, &statbuf) != 0)
	{
	  stat_diag (name->name);
	  continue;
	}
      if (S_ISDIR (statbuf.st_mode))
	{
	  name->found_count++;
	  add_hierarchy_to_namelist (name, statbuf.st_dev, true);
	}
    }

  namelist = merge_sort (namelist, num_names, compare_names);

  num_names = 0;
  nametab = hash_initialize (0, 0,
			     name_hash,
			     name_compare, NULL);
  for (name = namelist; name; name = next_name)
    {
      next_name = name->next;
      name->caname = normalize_filename (name->name);
      if (prev_name)
	{
	  struct name *p = hash_lookup (nametab, name);
	  if (p)
	    {
	      /* Keep the one listed in the command line */
	      if (!name->parent)
		{
		  if (p->child)
		    rebase_child_list (p->child, name);
		  /* FIXME: remove_directory (p->caname); ? */
		  remname (p);
		  free_name (p);
		  num_names--;
		}
	      else
		{
		  if (name->child)
		    rebase_child_list (name->child, p);
		  /* FIXME: remove_directory (name->caname); ? */
		  remname (name);
		  free_name (name);
		  continue;
		}
	    }
	}
      name->found_count = 0;
      if (!hash_insert (nametab, name))
	xalloc_die ();
      prev_name = name;
      num_names++;
    }
  nametail = prev_name;
  hash_free (nametab);

  namelist = merge_sort (namelist, num_names, compare_names_found);

  if (listed_incremental_option)
    {
      for (name = namelist; name && name->name[0] == 0; name++)
	;
      if (name)
	append_incremental_renames (name->directory);
    }
}
Exemplo n.º 4
0
static void
xheader_set_single_keyword (char *kw)
{
  USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
}