2015-08-05 03:30:40 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2015-08-18 12:22:31 +02:00
|
|
|
#include <strings.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "stringop.h"
|
2015-08-05 03:30:40 +02:00
|
|
|
#include "string.h"
|
|
|
|
#include "list.h"
|
|
|
|
|
|
|
|
/* Note: This returns 8 characters for trimmed_start per tab character. */
|
2015-08-18 12:22:31 +02:00
|
|
|
void strip_whitespace(char *str) {
|
|
|
|
int shift = 0;
|
|
|
|
int bpair = 1;
|
|
|
|
int in_str = 0, in_ch = 0;
|
|
|
|
while (*str) {
|
|
|
|
str[-shift] = str[0];
|
|
|
|
if (*str == '"' && !in_ch) {
|
|
|
|
in_str = !in_str;
|
|
|
|
} else if (*str == '\'' && !in_str) {
|
|
|
|
in_ch = !in_ch;
|
|
|
|
} else if (!in_ch && !in_str) {
|
|
|
|
if (isblank(*str)) {
|
|
|
|
if (bpair) {
|
|
|
|
++shift;
|
|
|
|
}
|
|
|
|
bpair=1;
|
|
|
|
} else {
|
|
|
|
bpair = 0;
|
|
|
|
}
|
2015-08-05 03:30:40 +02:00
|
|
|
}
|
2015-08-18 12:22:31 +02:00
|
|
|
++str;
|
2015-08-05 03:30:40 +02:00
|
|
|
}
|
2015-08-18 12:22:31 +02:00
|
|
|
str[-shift-bpair] = 0;
|
2015-08-05 03:30:40 +02:00
|
|
|
}
|
|
|
|
|
2015-08-18 12:22:31 +02:00
|
|
|
void strip_comments(char *str) {
|
2015-08-05 03:30:40 +02:00
|
|
|
int in_string = 0, in_character = 0;
|
|
|
|
int i = 0;
|
|
|
|
while (str[i] != '\0') {
|
|
|
|
if (str[i] == '"' && !in_character) {
|
|
|
|
in_string = !in_string;
|
|
|
|
} else if (str[i] == '\'' && !in_string) {
|
|
|
|
in_character = !in_character;
|
|
|
|
} else if (!in_character && !in_string) {
|
2015-08-18 11:48:56 +02:00
|
|
|
if (str[i] == '#') {
|
2015-08-05 03:30:40 +02:00
|
|
|
str[i] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list_t *split_string(const char *str, const char *delims) {
|
|
|
|
list_t *res = create_list();
|
|
|
|
int i, j;
|
2015-08-16 22:38:54 +02:00
|
|
|
int len = strlen(str);
|
|
|
|
for (i = 0, j = 0; i < len + 1; ++i) {
|
|
|
|
if (strchr(delims, str[i]) || i == len) {
|
2015-08-05 03:30:40 +02:00
|
|
|
if (i - j == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
char *left = malloc(i - j + 1);
|
|
|
|
memcpy(left, str + j, i - j);
|
|
|
|
left[i - j] = 0;
|
|
|
|
list_add(res, left);
|
|
|
|
j = i + 1;
|
2015-08-16 22:38:54 +02:00
|
|
|
while (j <= len && str[j] && strchr(delims, str[j])) {
|
2015-08-05 03:30:40 +02:00
|
|
|
j++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_flat_list(list_t *list) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < list->length; ++i) {
|
|
|
|
free(list->items[i]);
|
|
|
|
}
|
|
|
|
list_free(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *code_strstr(const char *haystack, const char *needle) {
|
|
|
|
/* TODO */
|
|
|
|
return strstr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *code_strchr(const char *str, char delimiter) {
|
|
|
|
int in_string = 0, in_character = 0;
|
|
|
|
int i = 0;
|
|
|
|
while (str[i] != '\0') {
|
|
|
|
if (str[i] == '"' && !in_character) {
|
|
|
|
in_string = !in_string;
|
|
|
|
} else if (str[i] == '\'' && !in_string) {
|
|
|
|
in_character = !in_character;
|
|
|
|
} else if (!in_character && !in_string) {
|
|
|
|
if (str[i] == delimiter) {
|
|
|
|
return (char *)str + i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int unescape_string(char *string) {
|
|
|
|
/* TODO: More C string escapes */
|
|
|
|
int len = strlen(string);
|
|
|
|
int i;
|
|
|
|
for (i = 0; string[i]; ++i) {
|
|
|
|
if (string[i] == '\\') {
|
|
|
|
--len;
|
2015-08-16 22:38:54 +02:00
|
|
|
int shift = 0;
|
2015-08-05 03:30:40 +02:00
|
|
|
switch (string[++i]) {
|
|
|
|
case '0':
|
|
|
|
string[i - 1] = '\0';
|
2015-08-16 22:38:54 +02:00
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
string[i - 1] = '\a';
|
2015-08-16 22:38:54 +02:00
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
string[i - 1] = '\b';
|
2015-08-16 22:38:54 +02:00
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
2015-08-16 22:38:54 +02:00
|
|
|
case 'f':
|
|
|
|
string[i - 1] = '\f';
|
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
string[i - 1] = '\n';
|
2015-08-16 22:38:54 +02:00
|
|
|
shift = 1;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
string[i - 1] = '\r';
|
|
|
|
shift = 1;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
string[i - 1] = '\t';
|
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
string[i - 1] = '\v';
|
2015-08-16 22:38:54 +02:00
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
2015-08-16 22:38:54 +02:00
|
|
|
case '\\':
|
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
2015-08-16 22:38:54 +02:00
|
|
|
case '\'':
|
|
|
|
string[i - 1] = '\'';
|
|
|
|
shift = 1;
|
|
|
|
break;
|
|
|
|
case '\"':
|
|
|
|
string[i - 1] = '\"';
|
|
|
|
shift = 1;
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
string[i - 1] = '?';
|
|
|
|
shift = 1;
|
2015-08-05 03:30:40 +02:00
|
|
|
break;
|
2015-08-16 22:38:54 +02:00
|
|
|
case 'x':
|
|
|
|
{
|
|
|
|
unsigned char c = 0;
|
|
|
|
shift = 1;
|
|
|
|
if (string[i+1] >= '0' && string[i+1] <= '9') {
|
|
|
|
shift = 2;
|
|
|
|
c = string[i+1] - '0';
|
|
|
|
if (string[i+2] >= '0' && string[i+2] <= '9') {
|
|
|
|
shift = 3;
|
|
|
|
c *= 0x10;
|
|
|
|
c += string[i+2] - '0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
string[i - 1] = c;
|
|
|
|
}
|
2015-08-05 03:30:40 +02:00
|
|
|
}
|
2015-08-16 22:38:54 +02:00
|
|
|
memmove(string + i, string + i + shift, len - i);
|
2015-08-05 03:30:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return len;
|
|
|
|
}
|
2015-08-06 04:40:38 +02:00
|
|
|
|
|
|
|
char *join_args(char **argv, int argc) {
|
|
|
|
int len = 0, i;
|
|
|
|
for (i = 0; i < argc; ++i) {
|
|
|
|
len += strlen(argv[i]) + 1;
|
|
|
|
}
|
|
|
|
char *res = malloc(len);
|
|
|
|
len = 0;
|
|
|
|
for (i = 0; i < argc; ++i) {
|
|
|
|
strcpy(res + len, argv[i]);
|
|
|
|
len += strlen(argv[i]);
|
|
|
|
res[len++] = ' ';
|
|
|
|
}
|
|
|
|
res[len - 1] = '\0';
|
|
|
|
return res;
|
|
|
|
}
|