/* atparse.c

   Parse the AT command set... */

/*
 * Copyright (c) 1995 RadioMail Corporation.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of RadioMail Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software was written for RadioMail Corporation by Ted Lemon
 * under a contract with Vixie Enterprises, and is based on an earlier
 * design by Paul Vixie.
 */

#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 RadioMail Corporation.  All rights reserved.\n";
#endif /* not lint */

#include "osdep.h"
#include "cdefs.h"
#include "global.h"
#include <ctype.h>

/* Convert a string of AT commands into a vector of pointers to individual
   commands.  */

char **atparse (string, clumpp)
     char *string;
     int clumpp;
{
  int i = strlen (string);
  char **ptrs, **pp, *s, *n, *bp;
  int sreg;

  /* Allocate space for a pointer for every character in the string,
     plus buffer space for every character in the string and a NUL
     following it.   This is the worst possible case. */
  bp = (char *)malloc (i * (2 + sizeof (char **)));
  if (!bp)
    error ("No memory for AT parse buffer");
  /* Pointers follow character buffer... */
  pp = ptrs = (char **)(bp + 2 * i);

  i = 0;
  s = string;
  /* Skip leading AT command, if specified. */
  if (!strncasecmp (s, "at", 2))
    s += 2;
  while (*s)
    {
      /* Skip leading whitespace... */
      if (isascii (*s) && isspace (*s))
	{
	  ++s;
	  continue;
	}
      /* Leading digits aren't permitted... */
      if (isascii (*s) && isdigit (*s))
	error ("Raw numeric value encountered in AT command string: %s", s);

      n = s;
      if (*n == 'S' || *n == 's')
	sreg = 1;
      else
	sreg = 0;
      /* Include leading punctuation... */
      while (*n && isascii (*n) && !isalpha (*n))
	++n;
      if (clumpp)
	while (*n && isascii (*n) && !isdigit (*n))
	  ++n;
      else
	{
	  if (!*n || !isascii (*n) || !isalpha (*n))
	    error ("Expecting alphabetic char in %s", s);
	  else
	    ++n;
	}
      /* Now skip over digits... */
      while (*n && isascii (*n) && isdigit (*n))
	++n;
      /* If it's an s-register assignment, skip over the =\d+... */
      if (sreg && *n == '=')
	{
	  ++n;
	  while (*n && isascii (*n) && isdigit (*n))
	    ++n;
	}

      /* Copy and NUL-terminate the command. */
      memcpy (bp, s, n - s);
      bp [n - s] = 0;
      /* Store it in the pointer array... */
      *pp++ = bp;
      /* Go to the next available buffer position... */
      bp += (n - s) + 1;
      /* Do the next command... */
      s = n;
    }
  *pp = (char *)0;
  return ptrs;
}
