137 lines
3.5 KiB
C
137 lines
3.5 KiB
C
/***************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
*
|
|
* This software is licensed as described in the file COPYING, which
|
|
* you should have received as part of this distribution. The terms
|
|
* are also available at https://curl.se/docs/copyright.html.
|
|
*
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
* furnished to do so, under the terms of the COPYING file.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
* SPDX-License-Identifier: curl
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "strparse.h"
|
|
|
|
/* Get a word until the first DELIM or end of string. At least one byte long.
|
|
return non-zero on error */
|
|
int Curl_str_until(const char **linep, struct Curl_str *out,
|
|
const size_t max, char delim)
|
|
{
|
|
const char *s = *linep;
|
|
size_t len = 0;
|
|
DEBUGASSERT(linep && *linep && out && max && delim);
|
|
|
|
out->str = NULL;
|
|
out->len = 0;
|
|
while(*s && (*s != delim)) {
|
|
s++;
|
|
if(++len > max) {
|
|
return STRE_BIG;
|
|
}
|
|
}
|
|
if(!len)
|
|
return STRE_SHORT;
|
|
out->str = *linep;
|
|
out->len = len;
|
|
*linep = s; /* point to the first byte after the word */
|
|
return STRE_OK;
|
|
}
|
|
|
|
/* Get a word until the first space or end of string. At least one byte long.
|
|
return non-zero on error */
|
|
int Curl_str_word(const char **linep, struct Curl_str *out,
|
|
const size_t max)
|
|
{
|
|
return Curl_str_until(linep, out, max, ' ');
|
|
}
|
|
|
|
|
|
/* Get a "quoted" word. No escaping possible.
|
|
return non-zero on error */
|
|
int Curl_str_quotedword(const char **linep, struct Curl_str *out,
|
|
const size_t max)
|
|
{
|
|
const char *s = *linep;
|
|
size_t len = 0;
|
|
DEBUGASSERT(linep && *linep && out && max);
|
|
|
|
out->str = NULL;
|
|
out->len = 0;
|
|
if(*s != '\"')
|
|
return STRE_BEGQUOTE;
|
|
s++;
|
|
while(*s && (*s != '\"')) {
|
|
s++;
|
|
if(++len > max)
|
|
return STRE_BIG;
|
|
}
|
|
if(*s != '\"')
|
|
return STRE_ENDQUOTE;
|
|
out->str = (*linep) + 1;
|
|
out->len = len;
|
|
*linep = s + 1;
|
|
return STRE_OK;
|
|
}
|
|
|
|
/* Advance over a single character.
|
|
return non-zero on error */
|
|
int Curl_str_single(const char **linep, char byte)
|
|
{
|
|
DEBUGASSERT(linep && *linep);
|
|
if(**linep != byte)
|
|
return STRE_BYTE;
|
|
(*linep)++; /* move over it */
|
|
return STRE_OK;
|
|
}
|
|
|
|
/* Advance over a single space.
|
|
return non-zero on error */
|
|
int Curl_str_singlespace(const char **linep)
|
|
{
|
|
return Curl_str_single(linep, ' ');
|
|
}
|
|
|
|
/* Get an unsigned number. Leading zeroes are accepted.
|
|
return non-zero on error */
|
|
int Curl_str_number(const char **linep, size_t *nump, size_t max)
|
|
{
|
|
size_t num = 0;
|
|
DEBUGASSERT(linep && *linep && nump);
|
|
*nump = 0;
|
|
while(ISDIGIT(**linep)) {
|
|
int n = **linep - '0';
|
|
if(num > ((SIZE_T_MAX - n) / 10))
|
|
return STRE_OVERFLOW;
|
|
num = num * 10 + n;
|
|
if(num > max)
|
|
return STRE_BIG; /** too big */
|
|
(*linep)++;
|
|
}
|
|
*nump = num;
|
|
return STRE_OK;
|
|
}
|
|
|
|
/* CR or LF
|
|
return non-zero on error */
|
|
int Curl_str_newline(const char **linep)
|
|
{
|
|
DEBUGASSERT(linep && *linep);
|
|
if(ISNEWLINE(**linep)) {
|
|
(*linep)++;
|
|
return STRE_OK; /* yessir */
|
|
}
|
|
return STRE_NEWLINE;
|
|
}
|