m4_substr (struct obstack *obs, int argc, token_data **argv)
{
  int start = 0;
  int length, avail;

  if (bad_argc (argv[0], argc, 3, 4))
    {
      /* builtin(`substr') is blank, but substr(`abc') is abc.  */
      if (argc == 2)
	obstack_grow (obs, ARG (1), strlen (ARG (1)));
      return;
    }

  length = avail = strlen (ARG (1));
  if (!numeric_arg (argv[0], ARG (2), &start))
    return;

  if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
    return;

  if (start < 0 || length <= 0 || start >= avail)
    return;

  if (start + length > avail)
    length = avail - start;
  obstack_grow (obs, ARG (1) + start, length);
}
m4_substr (struct obstack *obs, int argc, token_data **argv)
{
  int start = 0;
  int length, avail;

  if (bad_argc (argv[0], argc, 3, 4))
    {
       
      if (argc == 2)
	obstack_grow (obs, ARG (1), strlen (ARG (1)));
      return;
    }

  length = avail = strlen (ARG (1));
  if (!numeric_arg (argv[0], ARG (2), &start))
    return;

  if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
    return;

  if (start < 0 || length <= 0 || start >= avail)
    return;

  if (start + length > avail)
    length = avail - start;
  obstack_grow (obs, ARG (1) + start, length);
}