/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <vppinfra/format.h>

/* Call user's function to fill input buffer. */
__clib_export uword
_unformat_fill_input (unformat_input_t * i)
{
  uword l, first_mark;

  if (i->index == UNFORMAT_END_OF_INPUT)
    return i->index;

  first_mark = l = vec_len (i->buffer);
  if (vec_len (i->buffer_marks) > 0)
    first_mark = i->buffer_marks[0];

  /* Re-use buffer when no marks. */
  if (first_mark > 0)
    vec_delete (i->buffer, first_mark, 0);

  i->index = vec_len (i->buffer);
  for (l = 0; l < vec_len (i->buffer_marks); l++)
    i->buffer_marks[l] -= first_mark;

  /* Call user's function to fill the buffer. */
  if (i->fill_buffer)
    i->index = i->fill_buffer (i);

  /* If input pointer is still beyond end of buffer even after
     fill then we've run out of input. */
  if (i->index >= vec_len (i->buffer))
    i->index = UNFORMAT_END_OF_INPUT;

  return i->index;
}

always_inline uword
is_white_space (uword c)
{
  switch (c)
    {
    case ' ':
    case '\t':
    case '\n':
    case '\r':
      return 1;

    default:
      return 0;
    }
}

/* Format function for dumping input stream. */
__clib_export u8 *
format_unformat_error (u8 * s, va_list * va)
{
  unformat_input_t *i = va_arg (*va, unformat_input_t *);
  uword l = vec_len (i->buffer);

  /* Only show so much of the input buffer (it could be really large). */
  uword n_max = 30;

  if (i->index < l)
    {
      uword n = l - i->index;
      u8 *p, *p_end;

      p = i->buffer + i->index;
      p_end = p + (n > n_max ? n_max : n);

      /* Skip white space at end. */
      if (n <= n_max)
	{
	  while (p_end > p && is_white_space (p_end[-1]))
	    p_end--;
	}

      while (p < p_end)
	{
	  switch (*p)
	    {
	    case '\r':
	      vec_add (s, "\\r", 2);
	      break;
	    case '\n':
	      vec_add (s, "\\n", 2);
	      break;
	    case '\t':
	      vec_add (s, "\\t", 2);
	      break;
	    default:
	      vec_add1 (s, *p);
	      break;
	    }
	  p++;
	}

      if (n > n_max)
	vec_add (s, "...", 3);
    }

  return s;
}

/* Print everything: not just error context. */
__clib_export u8 *
format_unformat_input (u8 * s, va_list * va)
{
  unformat_input_t *i = va_arg (*va, unformat_input_t *);
  uword l, n;

  if (i->index == UNFORMAT_END_OF_INPUT)
    s = format (s, "{END_OF_INPUT}");
  else
    {
      l = vec_len (i->buffer);
      n = l - i->index;
      if (n > 0)
	vec_add (s, i->buffer + i->index, n);
    }

  return s;
}

#if CLIB_DEBUG > 0
void
di (unformat_input_t * i)
{
  fformat (stderr, "%U\n", format_unformat_input, i);
}
#endif

/* Parse delimited vector string.  If string starts with { then string
   is delimited by balanced parenthesis.  Other string is delimited by
   white space.  {} were chosen since they are special to the shell. */
static uword
unformat_string (unformat_input_t * input,
		 uword delimiter_character,
		 uword format_character, va_list * va)
{
  u8 **string_return = va_arg (*va, u8 **);
  u8 *s = 0;
  word paren = 0;
  word is_paren_delimited = 0;
  word backslash = 0;
  uword c;

  switch (delimiter_character)
    {
    case '%':
    case ' ':
    case '\t':
      delimiter_character = 0;
      break;
    }

  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      word add_to_vector;

      /* Null return string means to skip over delimited input. */
      add_to_vector = string_return != 0;

      if (backslash)
	backslash = 0;
      else
	switch (c)
	  {
	  case '\\':
	    backslash = 1;
	    add_to_vector = 0;
	    break;

	  case '{':
	    if (paren == 0 && vec_len (s) == 0)
	      {
		is_paren_delimited = 1;
		add_to_vector = 0;
	      }
	    paren++;
	    break;

	  case '}':
	    paren--;
	    if (is_paren_delimited && paren == 0)
	      goto done;
	    break;

	  case ' ':
	  case '\t':
	  case '\n':
	  case '\r':
	    if (!is_paren_delimited)
	      {
		unformat_put_input (input);
		goto done;
	      }
	    break;

	  default:
	    if (!is_paren_delimited && c == delimiter_character)
	      {
		unformat_put_input (input);
		goto done;
	      }
	  }

      if (add_to_vector)
	vec_add1 (s, c);
    }

done:
  if (string_return)
    {
      /* Match the string { END-OF-INPUT as a single brace. */
      if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0 && paren == 1)
	vec_add1 (s, '{');

      /* Don't match null string. */
      if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0)
	return 0;

      /* Null terminate C string. */
      if (format_character == 's')
	vec_add1 (s, 0);

      *string_return = s;
    }
  else
    vec_free (s);		/* just to make sure */

  return 1;
}

__clib_export uword
unformat_hex_string (unformat_input_t * input, va_list * va)
{
  u8 **hexstring_return = va_arg (*va, u8 **);
  u8 *s;
  uword n, d, c;

  n = 0;
  d = 0;
  s = 0;
  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      if (c >= '0' && c <= '9')
	d = 16 * d + c - '0';
      else if (c >= 'a' && c <= 'f')
	d = 16 * d + 10 + c - 'a';
      else if (c >= 'A' && c <= 'F')
	d = 16 * d + 10 + c - 'A';
      else
	{
	  unformat_put_input (input);
	  break;
	}
      n++;

      if (n == 2)
	{
	  vec_add1 (s, d);
	  n = d = 0;
	}
    }

  /* Hex string must have even number of digits. */
  if (n % 2)
    {
      vec_free (s);
      return 0;
    }
  /* Make sure something was processed. */
  else if (s == 0)
    {
      return 0;
    }

  *hexstring_return = s;
  return 1;
}

/* unformat (input "foo%U", unformat_eof) matches terminal foo only */
__clib_export uword
unformat_eof (unformat_input_t * input, va_list * va)
{
  return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
}

/* Parse a token containing given set of characters. */
__clib_export uword
unformat_token (unformat_input_t * input, va_list * va)
{
  u8 *token_chars = va_arg (*va, u8 *);
  u8 **string_return = va_arg (*va, u8 **);
  u8 *s, map[256];
  uword i, c;

  if (!token_chars)
    token_chars = (u8 *) "a-zA-Z0-9_";

  clib_memset (map, 0, sizeof (map));
  for (s = token_chars; *s;)
    {
      /*
       * Parse range.
       * The test order is important: s[1] is valid because s[0] != '\0' but
       * s[2] might not if s[1] == '\0'
       * Also, if s[1] == '-' but s[2] == '\0' the test s[0] < s[2] will
       * (correctly) fail
       */
      if (s[1] == '-' && s[0] < s[2])
	{
	  for (i = s[0]; i <= s[2]; i++)
	    map[i] = 1;
	  s = s + 3;
	}
      else
	{
	  map[s[0]] = 1;
	  s = s + 1;
	}
    }

  s = 0;
  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      if (!map[c])
	{
	  unformat_put_input (input);
	  break;
	}

      vec_add1 (s, c);
    }

  if (vec_len (s) == 0)
    return 0;

  *string_return = s;
  return 1;
}

/* Unformat (parse) function which reads a %s string and converts it
   to and unformat_input_t. */
__clib_export uword
unformat_input (unformat_input_t * i, va_list * args)
{
  unformat_input_t *sub_input = va_arg (*args, unformat_input_t *);
  u8 *s;

  if (unformat (i, "%v", &s))
    {
      unformat_init_vector (sub_input, s);
      return 1;
    }

  return 0;
}

/* Parse a line ending with \n and return it. */
__clib_export uword
unformat_line (unformat_input_t * i, va_list * va)
{
  u8 *line = 0, **result = va_arg (*va, u8 **);
  uword c;

  while ((c = unformat_get_input (i)) != '\n' && c != UNFORMAT_END_OF_INPUT)
    {
      vec_add1 (line, c);
    }

  *result = line;
  return vec_len (line);
}

/* Parse a line ending with \n and return it as an unformat_input_t. */
__clib_export uword
unformat_line_input (unformat_input_t * i, va_list * va)
{
  unformat_input_t *result = va_arg (*va, unformat_input_t *);
  u8 *line;
  if (!unformat_user (i, unformat_line, &line))
    return 0;
  unformat_init_vector (result, line);
  return 1;
}

/* Values for is_signed. */
#define UNFORMAT_INTEGER_SIGNED		1
#define UNFORMAT_INTEGER_UNSIGNED	0

static uword
unformat_integer (unformat_input_t * input,
		  va_list * va, uword base, uword is_signed, uword data_bytes)
{
  uword c, digit;
  uword value = 0;
  uword n_digits = 0;
  uword n_input = 0;
  uword sign = 0;

  /* We only support bases <= 64. */
  if (base < 2 || base > 64)
    goto error;

  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      switch (c)
	{
	case '-':
	  if (n_input == 0)
	    {
	      if (is_signed)
		{
		  sign = 1;
		  goto next_digit;
		}
	      else
		/* Leading sign for unsigned number. */
		goto error;
	    }
	  /* Sign after input (e.g. 100-200). */
	  goto put_input_done;

	case '+':
	  if (n_input > 0)
	    goto put_input_done;
	  sign = 0;
	  goto next_digit;

	case '0' ... '9':
	  digit = c - '0';
	  break;

	case 'a' ... 'z':
	  digit = 10 + (c - 'a');
	  break;

	case 'A' ... 'Z':
	  digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
	  break;

	case '/':
	  digit = 62;
	  break;

	case '?':
	  digit = 63;
	  break;

	default:
	  goto put_input_done;
	}

      if (digit >= base)
	{
	put_input_done:
	  unformat_put_input (input);
	  goto done;
	}

      {
	uword new_value = base * value + digit;

	/* Check for overflow. */
	if (new_value < value)
	  goto error;
	value = new_value;
      }
      n_digits += 1;

    next_digit:
      n_input++;
    }

done:
  if (sign)
    value = -value;

  if (n_digits > 0)
    {
      void *v = va_arg (*va, void *);

      if (data_bytes == ~0)
	data_bytes = sizeof (int);

      switch (data_bytes)
	{
	case 1:
	  *(u8 *) v = value;
	  break;
	case 2:
	  *(u16 *) v = value;
	  break;
	case 4:
	  *(u32 *) v = value;
	  break;
	case 8:
	  *(u64 *) v = value;
	  break;
	default:
	  goto error;
	}

      return 1;
    }

error:
  return 0;
}

/* Return x 10^n */
static f64
times_power_of_ten (f64 x, int n)
{
  if (n >= 0)
    {
      static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
      while (n >= 8)
	{
	  x *= 1e+8;
	  n -= 8;
	}
      return x * t[n];
    }
  else
    {
      static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
      while (n <= -8)
	{
	  x *= 1e-8;
	  n += 8;
	}
      return x * t[-n];
    }

}

static uword
unformat_float (unformat_input_t * input, va_list * va)
{
  uword c;
  u64 values[3];
  uword n_digits[3], value_index = 0;
  uword signs[2], sign_index = 0;
  uword n_input = 0;

  clib_memset (values, 0, sizeof (values));
  clib_memset (n_digits, 0, sizeof (n_digits));
  clib_memset (signs, 0, sizeof (signs));

  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      switch (c)
	{
	case '-':
	  if (value_index == 2 && n_digits[2] == 0)
	    /* sign of exponent: it's ok. */ ;

	  else if (value_index < 2 && n_digits[0] > 0)
	    {
	      /* 123- */
	      unformat_put_input (input);
	      goto done;
	    }

	  else if (n_input > 0)
	    goto error;

	  signs[sign_index++] = 1;
	  goto next_digit;

	case '+':
	  if (value_index == 2 && n_digits[2] == 0)
	    /* sign of exponent: it's ok. */ ;

	  else if (value_index < 2 && n_digits[0] > 0)
	    {
	      /* 123+ */
	      unformat_put_input (input);
	      goto done;
	    }

	  else if (n_input > 0)
	    goto error;
	  signs[sign_index++] = 0;
	  goto next_digit;

	case 'e':
	case 'E':
	  if (n_input == 0)
	    goto error;
	  value_index = 2;
	  sign_index = 1;
	  break;

	case '.':
	  if (value_index > 0)
	    goto error;
	  value_index = 1;
	  break;

	case '0' ... '9':
	  {
	    u64 tmp;

	    tmp = values[value_index] * 10 + c - '0';

	    /* Check for overflow. */
	    if (tmp < values[value_index])
	      goto error;
	    values[value_index] = tmp;
	    n_digits[value_index] += 1;
	  }
	  break;

	default:
	  unformat_put_input (input);
	  goto done;
	}

    next_digit:
      n_input++;
    }

done:
  {
    f64 f_values[2], *value_return;
    word expon;

    /* Must have either whole or fraction digits. */
    if (n_digits[0] + n_digits[1] <= 0)
      goto error;

    f_values[0] = values[0];
    if (signs[0])
      f_values[0] = -f_values[0];

    f_values[1] = values[1];
    f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);

    f_values[0] += f_values[1];

    expon = values[2];
    if (signs[1])
      expon = -expon;

    f_values[0] = times_power_of_ten (f_values[0], expon);

    value_return = va_arg (*va, f64 *);
    *value_return = f_values[0];
    return 1;
  }

error:
  return 0;
}

static const char *
match_input_with_format (unformat_input_t * input, const char *f)
{
  uword cf, ci;

  ASSERT (*f != 0);

  while (1)
    {
      cf = *f;
      if (cf == 0 || cf == '%' || cf == ' ')
	break;
      f++;

      ci = unformat_get_input (input);

      if (cf != ci)
	return 0;
    }
  return f;
}

static const char *
do_percent (unformat_input_t * input, va_list * va, const char *f)
{
  uword cf, n, data_bytes = ~0;

  cf = *f++;

  switch (cf)
    {
    default:
      break;

    case 'w':
      /* Word types. */
      cf = *f++;
      data_bytes = sizeof (uword);
      break;

    case 'l':
      cf = *f++;
      if (cf == 'l')
	{
	  cf = *f++;
	  data_bytes = sizeof (long long);
	}
      else
	{
	  data_bytes = sizeof (long);
	}
      break;

    case 'L':
      cf = *f++;
      data_bytes = sizeof (long long);
      break;
    }

  n = 0;
  switch (cf)
    {
    case 'D':
      data_bytes = va_arg (*va, int);
    case 'd':
      n = unformat_integer (input, va, 10,
			    UNFORMAT_INTEGER_SIGNED, data_bytes);
      break;

    case 'u':
      n = unformat_integer (input, va, 10,
			    UNFORMAT_INTEGER_UNSIGNED, data_bytes);
      break;

    case 'b':
      n = unformat_integer (input, va, 2,
			    UNFORMAT_INTEGER_UNSIGNED, data_bytes);
      break;

    case 'o':
      n = unformat_integer (input, va, 8,
			    UNFORMAT_INTEGER_UNSIGNED, data_bytes);
      break;

    case 'X':
      data_bytes = va_arg (*va, int);
    case 'x':
      n = unformat_integer (input, va, 16,
			    UNFORMAT_INTEGER_UNSIGNED, data_bytes);
      break;

    case 'f':
      n = unformat_float (input, va);
      break;

    case 's':
    case 'v':
      n = unformat_string (input, f[0], cf, va);
      break;

    case 'U':
      {
	unformat_function_t *f = va_arg (*va, unformat_function_t *);
	n = f (input, va);
      }
      break;

    case '=':
    case '|':
      {
	int *var = va_arg (*va, int *);
	uword val = va_arg (*va, int);

	if (cf == '|')
	  val |= *var;
	*var = val;
	n = 1;
      }
      break;
    }

  return n ? f : 0;
}

__clib_export uword
unformat_skip_white_space (unformat_input_t * input)
{
  uword n = 0;
  uword c;

  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
    {
      if (!is_white_space (c))
	{
	  unformat_put_input (input);
	  break;
	}
      n++;
    }
  return n;
}

__clib_export uword
va_unformat (unformat_input_t * input, const char *fmt, va_list * va)
{
  const char *f;
  uword input_matches_format;
  uword default_skip_input_white_space;
  uword n_input_white_space_skipped;
  uword last_non_white_space_match_percent;
  uword last_non_white_space_match_format;

  vec_add1_aligned (input->buffer_marks, input->index,
		    sizeof (input->buffer_marks[0]));

  f = fmt;
  default_skip_input_white_space = 1;
  input_matches_format = 0;
  last_non_white_space_match_percent = 0;
  last_non_white_space_match_format = 0;

  while (1)
    {
      char cf;
      uword is_percent, skip_input_white_space;

      cf = *f;
      is_percent = 0;

      /* Always skip input white space at start of format string.
         Otherwise use default skip value which can be changed by %_
         (see below). */
      skip_input_white_space = f == fmt || default_skip_input_white_space;

      /* Spaces in format request skipping input white space. */
      if (is_white_space (cf))
	{
	  skip_input_white_space = 1;

	  /* Multiple format spaces are equivalent to a single white
	     space. */
	  while (is_white_space (*++f))
	    ;
	}
      else if (cf == '%')
	{
	  /* %_ toggles whether or not to skip input white space. */
	  switch (*++f)
	    {
	    case '_':
	      default_skip_input_white_space =
		!default_skip_input_white_space;
	      f++;
	      /* For transition from skip to no-skip in middle of format
	         string, skip input white space.  For example, the following matches:
	         fmt = "%_%d.%d%_->%_%d.%d%_"
	         input "1.2 -> 3.4"
	         Without this the space after -> does not get skipped. */
	      if (!default_skip_input_white_space
		  && !(f == fmt + 2 || *f == 0))
		unformat_skip_white_space (input);
	      continue;

	      /* %% means match % */
	    case '%':
	      break;

	      /* % at end of format string. */
	    case 0:
	      goto parse_fail;

	    default:
	      is_percent = 1;
	      break;
	    }
	}

      n_input_white_space_skipped = 0;
      if (skip_input_white_space)
	n_input_white_space_skipped = unformat_skip_white_space (input);

      /* End of format string. */
      if (cf == 0)
	{
	  /* Force parse error when format string ends and input is
	     not white or at end.  As an example, this is to prevent
	     format "foo" from matching input "food".
	     The last_non_white_space_match_percent is to make
	     "foo %d" match input "foo 10,bletch" with %d matching 10. */
	  if (skip_input_white_space
	      && !last_non_white_space_match_percent
	      && !last_non_white_space_match_format
	      && n_input_white_space_skipped == 0
	      && input->index != UNFORMAT_END_OF_INPUT)
	    goto parse_fail;
	  break;
	}

      last_non_white_space_match_percent = is_percent;
      last_non_white_space_match_format = 0;

      /* Explicit spaces in format must match input white space. */
      if (cf == ' ' && !default_skip_input_white_space)
	{
	  if (n_input_white_space_skipped == 0)
	    goto parse_fail;
	}

      else if (is_percent)
	{
	  if (!(f = do_percent (input, va, f)))
	    goto parse_fail;
	}

      else
	{
	  const char *g = match_input_with_format (input, f);
	  if (!g)
	    goto parse_fail;
	  last_non_white_space_match_format = g > f;
	  f = g;
	}
    }

  input_matches_format = 1;
parse_fail:

  /* Rewind buffer marks. */
  {
    uword l = vec_len (input->buffer_marks);

    /* If we did not match back up buffer to last mark. */
    if (!input_matches_format)
      input->index = input->buffer_marks[l - 1];

    _vec_len (input->buffer_marks) = l - 1;
  }

  return input_matches_format;
}

__clib_export uword
unformat (unformat_input_t * input, const char *fmt, ...)
{
  va_list va;
  uword result;
  va_start (va, fmt);
  result = va_unformat (input, fmt, &va);
  va_end (va);
  return result;
}

__clib_export uword
unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
{
  va_list va;
  uword result, l;

  /* Save place in input buffer in case parse fails. */
  l = vec_len (input->buffer_marks);
  vec_add1_aligned (input->buffer_marks, input->index,
		    sizeof (input->buffer_marks[0]));

  va_start (va, func);
  result = func (input, &va);
  va_end (va);

  if (!result && input->index != UNFORMAT_END_OF_INPUT)
    input->index = input->buffer_marks[l];

  _vec_len (input->buffer_marks) = l;

  return result;
}

/* Setup for unformat of Unix style command line. */
__clib_export void
unformat_init_command_line (unformat_input_t * input, char *argv[])
{
  uword i;

  unformat_init (input, 0, 0);

  /* Concatenate argument strings with space in between. */
  for (i = 1; argv[i]; i++)
    {
      vec_add (input->buffer, argv[i], strlen (argv[i]));
      if (argv[i + 1])
	vec_add1 (input->buffer, ' ');
    }
}

__clib_export void
unformat_init_string (unformat_input_t * input, char *string, int string_len)
{
  unformat_init (input, 0, 0);
  if (string_len > 0)
    vec_add (input->buffer, string, string_len);
}

__clib_export void
unformat_init_vector (unformat_input_t * input, u8 * vector_string)
{
  unformat_init (input, 0, 0);
  input->buffer = vector_string;
}

#ifdef CLIB_UNIX

static uword
clib_file_fill_buffer (unformat_input_t * input)
{
  int fd = pointer_to_uword (input->fill_buffer_arg);
  uword l, n;

  l = vec_len (input->buffer);
  vec_resize (input->buffer, 4096);
  n = read (fd, input->buffer + l, 4096);
  if (n > 0)
    _vec_len (input->buffer) = l + n;

  if (n <= 0)
    return UNFORMAT_END_OF_INPUT;
  else
    return input->index;
}

__clib_export void
unformat_init_clib_file (unformat_input_t * input, int file_descriptor)
{
  unformat_init (input, clib_file_fill_buffer,
		 uword_to_pointer (file_descriptor, void *));
}

/* Take input from Unix environment variable. */
uword
unformat_init_unix_env (unformat_input_t * input, char *var)
{
  char *val = getenv (var);
  if (val)
    unformat_init_string (input, val, strlen (val));
  return val != 0;
}

__clib_export uword
unformat_data_size (unformat_input_t * input, va_list * args)
{
  u64 _a;
  u64 *a = va_arg (*args, u64 *);
  if (unformat (input, "%lluGb", &_a))
    *a = _a << 30;
  else if (unformat (input, "%lluG", &_a))
    *a = _a << 30;
  else if (unformat (input, "%lluMb", &_a))
    *a = _a << 20;
  else if (unformat (input, "%lluM", &_a))
    *a = _a << 20;
  else if (unformat (input, "%lluKb", &_a))
    *a = _a << 10;
  else if (unformat (input, "%lluK", &_a))
    *a = _a << 10;
  else if (unformat (input, "%llu", a))
    ;
  else
    return 0;
  return 1;
}

#endif /* CLIB_UNIX */


/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
