/*
 * 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. */
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. */
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. */
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 balenced 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;
}

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 */
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. */
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_";

  memset (map, 0, sizeof (map));
  for (s = token_chars; *s;)
    {
      /* Parse range. */
      if (s[0] < s[2] && s[1] == '-')
	{
	  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. */
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. */
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. */
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;

  memset (values, 0, sizeof (values));
  memset (n_digits, 0, sizeof (n_digits));
  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;
}

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;
}

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;
}

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;
}

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. */
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, ' ');
    }
}

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);
}

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
unix_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;
}

void
unformat_init_unix_file (unformat_input_t * input, int file_descriptor)
{
  unformat_init (input, unix_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;
}

#endif /* CLIB_UNIX */


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