/*
* Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: args2argv.c,v 1.11 2007/02/03 18:17:35 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/ctype.h"
#include "sm/io.h"
#include "sm/str.h"
#include "util.h"
/*
** ARGS2ARGV -- split a str into a list of strings, NULL terminated
**
** Parameters:
** str -- str consisting of { argname[=argvalue] } *
** pnelem -- (pointer to) number of elements (output)
** pargv -- (pointer to) array of strings (output)
**
** Returns:
** usual sm_error code
*/
sm_ret_T
args2argv(sm_str_P str, uint *pnelem, char ***pargv)
{
size_t i, len;
int elem, nelem, c;
char **s;
SM_REQUIRE(pargv != NULL);
*pargv = NULL;
if (pnelem != NULL)
*pnelem = 0;
if (NULL == str)
return SM_SUCCESS;
len = sm_str_getlen(str);
for (i = 0, nelem = 0;
i < len && (c = sm_str_rd_elem(str, i)) != '\0';
i++)
{
/* skip over leading spaces */
while (i < len
&& (c = sm_str_rd_elem(str, i)) != '\0'
&& ISSPACE(c))
++i;
if (i >= len)
break;
while (i < len
&& (c = sm_str_rd_elem(str, i)) != '\0'
&& ISPRINT(c) && !ISSPACE(c))
++i;
++nelem;
if (i >= len)
break;
if ((c = sm_str_rd_elem(str, i)) != '\0') {
if (ISSPACE(c))
sm_str_wr_elem(str, i, '\0');
else
return sm_err_perm(EINVAL);
}
}
if (0 == nelem)
return SM_SUCCESS;
s = (char **)sm_zalloc(nelem * (sizeof *s));
if (NULL == s)
return sm_error_temp(SM_EM_PMILTER, ENOMEM);
for (i = 0, elem = 0;
i < len && (c = sm_str_rd_elem(str, i)) != '\0' && elem < nelem;
i++)
{
/* skip over leading spaces */
while (i < len
&& (c = sm_str_rd_elem(str, i)) != '\0'
&& ISSPACE(c))
++i;
if (i >= len)
break;
s[elem++] = (char *)sm_str_getdata(str) + i;
while (i < len
&& (c = sm_str_rd_elem(str, i)) != '\0'
&& ISPRINT(c) && !ISSPACE(c))
++i;
if (i >= len)
break;
if ((c = sm_str_rd_elem(str, i)) != '\0') {
if (ISSPACE(c))
sm_str_wr_elem(str, i, '\0');
else
return sm_err_perm(EINVAL);
}
}
/* overwrite last entry (already done above, just paranoia) */
s[elem] = NULL;
*pargv = s;
if (pnelem != NULL)
*pnelem = nelem;
return SM_SUCCESS;
}
syntax highlighted by Code2HTML, v. 0.9.1