Source refactoring; no functional changes.
This commit is contained in:
parent
b174130c91
commit
332fdba0bd
20 changed files with 1806 additions and 1440 deletions
107
str.c
Normal file
107
str.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* TTS - track your time.
|
||||
* Copyright (c) 2012-2014 Felicity Tarnell.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely. This software is provided 'as-is', without any express or implied
|
||||
* warranty.
|
||||
*/
|
||||
|
||||
#include "str.h"
|
||||
|
||||
size_t
|
||||
tokenise(str, res)
|
||||
const WCHAR *str;
|
||||
WCHAR ***res;
|
||||
{
|
||||
int ntoks = 0;
|
||||
const WCHAR *p, *q;
|
||||
|
||||
*res = NULL;
|
||||
p = str;
|
||||
|
||||
for (;;) {
|
||||
ptrdiff_t sz;
|
||||
int qskip = 0;
|
||||
|
||||
/* Skip leading whitespace */
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
|
||||
/* End of string - no more arguments */
|
||||
if (!*p)
|
||||
break;
|
||||
|
||||
q = p;
|
||||
|
||||
if (*q == '"') {
|
||||
/* Quoted string - scan for end of string */
|
||||
int isbsl = 0;
|
||||
p++;
|
||||
|
||||
while (*++q) {
|
||||
/* Handle escaping with backslash; currently works but the \ isn't
|
||||
* removed from the string.
|
||||
*/
|
||||
if (*q == '\\') {
|
||||
isbsl = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isbsl && (*q == '"'))
|
||||
break;
|
||||
|
||||
isbsl = 0;
|
||||
}
|
||||
/* At this point, *q == '"'. If it's NUL instead, then the
|
||||
* string was not terminated with a closing '"' before the end
|
||||
* of the line. We could give an error here, but it seems
|
||||
* more useful to just accept it.
|
||||
*/
|
||||
if (*q == '"')
|
||||
qskip = 1;
|
||||
} else {
|
||||
/* Not quoted - just find the next whitespace */
|
||||
while (!ISSPACE(*q) && *q)
|
||||
q++;
|
||||
}
|
||||
|
||||
/* Copy the argument (which is sz bytes long) into the result array */
|
||||
sz = (q - p);
|
||||
*res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1));
|
||||
(*res)[ntoks] = malloc(sizeof(WCHAR) * (sz + 1));
|
||||
MEMCPY((*res)[ntoks], p, sz);
|
||||
(*res)[ntoks][sz] = 0;
|
||||
ntoks++;
|
||||
|
||||
if (qskip)
|
||||
q += qskip;
|
||||
|
||||
while (ISSPACE(*q))
|
||||
q++;
|
||||
|
||||
/*
|
||||
* q is the start of the next token (with leading whitespace); reset
|
||||
* p to process the next argument.
|
||||
*/
|
||||
if (!*q)
|
||||
break;
|
||||
p = q;
|
||||
}
|
||||
|
||||
*res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1));
|
||||
(*res)[ntoks] = NULL;
|
||||
return ntoks;
|
||||
}
|
||||
|
||||
void
|
||||
tokfree(vec)
|
||||
WCHAR ***vec;
|
||||
{
|
||||
WCHAR **p;
|
||||
for (p = (*vec); *p; p++)
|
||||
free(*p);
|
||||
free(*vec);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue