Files
wmaker/WINGs/string.c
T

241 lines
4.6 KiB
C
Raw Normal View History

2011-03-24 16:07:20 +01:00
/*
* Until FreeBSD gets their act together;
* http://www.mail-archive.com/freebsd-hackers@freebsd.org/msg69469.html
*/
#if defined( FREEBSD )
# undef _XOPEN_SOURCE
#endif
2000-07-15 22:08:25 +00:00
#include "wconfig.h"
2000-07-15 22:08:25 +00:00
#include <string.h>
#include <stdlib.h>
#include <assert.h>
2000-07-15 22:08:25 +00:00
#include <ctype.h>
#ifdef HAVE_BSD_STRING_H
#include <bsd/string.h>
#endif
2000-07-15 22:08:25 +00:00
#include "WUtil.h"
#define PRC_ALPHA 0
#define PRC_BLANK 1
#define PRC_ESCAPE 2
#define PRC_DQUOTE 3
#define PRC_EOS 4
#define PRC_SQUOTE 5
typedef struct {
2009-08-20 00:59:40 +02:00
short nstate;
short output;
2000-07-15 22:08:25 +00:00
} DFA;
static DFA mtable[9][6] = {
/* Ctype: ALPHA BLANK ESCAPE DQUOTE EOS SQUOTE
/* State 0: Start */ {{3, 1}, {0, 0}, {4, 0}, {1, 0}, {8, 0}, {6, 0}},
/* State 1: In dquote */ {{1, 1}, {1, 1}, {2, 0}, {3, 0}, {5, 0}, {1, 1}},
/* State 2: Escape in dquote */ {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {5, 0}, {1, 1}},
/* State 3: In token */ {{3, 1}, {5, 0}, {4, 0}, {1, 0}, {5, 0}, {6, 0}},
/* State 4: Escaping */ {{3, 1}, {3, 1}, {3, 1}, {3, 1}, {5, 0}, {3, 1}},
/* State 5: End of string */ {{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */
/* State 6: In squote */ {{6, 1}, {6, 1}, {7, 0}, {6, 1}, {5, 0}, {3, 0}},
/* State 7: Escape in squote */ {{6, 1}, {6, 1}, {6, 1}, {6, 1}, {5, 0}, {6, 1}},
/* State 8: End of string */ {{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */
2000-07-15 22:08:25 +00:00
};
2009-08-20 00:59:40 +02:00
char *wtokennext(char *word, char **next)
2000-07-15 22:08:25 +00:00
{
2009-08-20 00:59:40 +02:00
char *ptr;
char *ret, *t;
int state, ctype;
t = ret = wmalloc(strlen(word) + 1);
ptr = word;
state = 0;
while (1) {
if (*ptr == 0)
ctype = PRC_EOS;
else if (*ptr == '\\')
ctype = PRC_ESCAPE;
else if (*ptr == '"')
ctype = PRC_DQUOTE;
else if (*ptr == '\'')
ctype = PRC_SQUOTE;
else if (*ptr == ' ' || *ptr == '\t')
ctype = PRC_BLANK;
else
ctype = PRC_ALPHA;
if (mtable[state][ctype].output) {
*t = *ptr;
t++;
*t = 0;
}
state = mtable[state][ctype].nstate;
ptr++;
if (mtable[state][0].output < 0) {
break;
}
}
2013-05-04 15:43:26 +02:00
if (*ret == 0) {
wfree(ret);
ret = NULL;
}
2009-08-20 00:59:40 +02:00
if (ctype == PRC_EOS)
*next = NULL;
else
*next = ptr;
2013-05-04 15:43:26 +02:00
return ret;
2000-07-15 22:08:25 +00:00
}
/* separate a string in tokens, taking " and ' into account */
2009-08-20 00:59:40 +02:00
void wtokensplit(char *command, char ***argv, int *argc)
2000-07-15 22:08:25 +00:00
{
2009-08-20 00:59:40 +02:00
char *token, *line;
int count;
count = 0;
line = command;
do {
token = wtokennext(line, &line);
if (token) {
if (count == 0)
*argv = wmalloc(sizeof(**argv));
2009-08-20 00:59:40 +02:00
else
*argv = wrealloc(*argv, (count + 1) * sizeof(**argv));
2009-08-20 00:59:40 +02:00
(*argv)[count++] = token;
}
} while (token != NULL && line != NULL);
*argc = count;
2000-07-15 22:08:25 +00:00
}
2009-08-20 00:59:40 +02:00
char *wtokenjoin(char **list, int count)
2000-07-15 22:08:25 +00:00
{
2009-08-20 00:59:40 +02:00
int i, j;
char *flat_string, *wspace;
j = 0;
for (i = 0; i < count; i++) {
if (list[i] != NULL && list[i][0] != 0) {
j += strlen(list[i]);
if (strpbrk(list[i], " \t"))
j += 2;
}
}
flat_string = wmalloc(j + count + 1);
for (i = 0; i < count; i++) {
if (list[i] != NULL && list[i][0] != 0) {
2010-09-28 22:25:44 +02:00
if (i > 0 &&
strlcat(flat_string, " ", j + count + 1) >= j + count + 1)
2010-09-28 22:25:44 +02:00
goto error;
2009-08-20 00:59:40 +02:00
wspace = strpbrk(list[i], " \t");
2010-09-28 22:25:44 +02:00
if (wspace &&
strlcat(flat_string, "\"", j + count + 1) >= j + count + 1)
2010-09-28 22:25:44 +02:00
goto error;
if (strlcat(flat_string, list[i], j + count + 1) >= j + count + 1)
2010-09-28 22:25:44 +02:00
goto error;
if (wspace &&
strlcat(flat_string, "\"", j + count + 1) >= j + count + 1)
2010-09-28 22:25:44 +02:00
goto error;
2009-08-20 00:59:40 +02:00
}
}
return flat_string;
2010-09-28 22:25:44 +02:00
error:
wfree(flat_string);
return NULL;
2000-07-15 22:08:25 +00:00
}
2009-08-20 00:59:40 +02:00
void wtokenfree(char **tokens, int count)
2000-07-15 22:08:25 +00:00
{
2007-02-18 03:47:47 +01:00
while (count--)
2009-08-20 00:59:40 +02:00
wfree(tokens[count]);
wfree(tokens);
2000-07-15 22:08:25 +00:00
}
2010-03-17 14:49:33 +01:00
char *wtrimspace(const char *s)
2000-07-15 22:08:25 +00:00
{
2013-05-04 15:43:27 +02:00
const char *t;
2010-03-17 14:49:33 +01:00
if (s == NULL)
return NULL;
2000-10-25 22:41:03 +00:00
2009-08-20 00:59:40 +02:00
while (isspace(*s) && *s)
s++;
2013-05-04 15:43:27 +02:00
t = s + strlen(s) - 1;
2009-08-20 00:59:40 +02:00
while (t > s && isspace(*t))
t--;
2000-10-25 22:41:03 +00:00
2010-03-17 14:49:33 +01:00
return wstrndup(s, t - s + 1);
2000-07-15 22:08:25 +00:00
}
2010-03-16 16:27:43 +01:00
char *wstrdup(const char *str)
{
2009-08-20 00:59:40 +02:00
assert(str != NULL);
2009-08-20 00:59:40 +02:00
return strcpy(wmalloc(strlen(str) + 1), str);
}
2010-03-17 14:49:33 +01:00
char *wstrndup(const char *str, size_t len)
2002-12-02 00:01:05 +00:00
{
2009-08-20 00:59:40 +02:00
char *copy;
2002-12-02 00:01:05 +00:00
2009-08-20 00:59:40 +02:00
assert(str != NULL);
2002-12-02 00:01:05 +00:00
2009-08-20 00:59:40 +02:00
len = WMIN(len, strlen(str));
copy = strncpy(wmalloc(len + 1), str, len);
copy[len] = 0;
2002-12-02 00:01:05 +00:00
2009-08-20 00:59:40 +02:00
return copy;
2002-12-02 00:01:05 +00:00
}
char *wstrconcat(const char *str1, const char *str2)
{
2009-08-20 00:59:40 +02:00
char *str;
2021-09-04 19:05:26 +02:00
size_t slen, slen1;
if (!str1 && str2)
2009-08-20 00:59:40 +02:00
return wstrdup(str2);
else if (str1 && !str2)
2009-08-20 00:59:40 +02:00
return wstrdup(str1);
else if (!str1 && !str2)
return NULL;
2021-09-04 19:05:26 +02:00
slen1 = strlen(str1);
slen = slen1 + strlen(str2) + 1;
2010-09-28 22:25:44 +02:00
str = wmalloc(slen);
2021-09-04 19:05:26 +02:00
strcpy(str, str1);
strcpy(str + slen1, str2);
2009-08-20 00:59:40 +02:00
return str;
}
char *wstrappend(char *dst, const char *src)
{
2010-09-28 22:25:44 +02:00
size_t slen;
if (!src || *src == 0)
2009-08-20 00:59:40 +02:00
return dst;
else if (!dst)
return wstrdup(src);
2010-09-28 22:25:44 +02:00
slen = strlen(dst) + strlen(src) + 1;
dst = wrealloc(dst, slen);
strcat(dst, src);
2009-08-20 00:59:40 +02:00
return dst;
}