Browse Source

Single source for lub/string

Serj Kalichev 8 years ago
parent
commit
71fdd2f4e2

+ 3 - 1
lub/ctype.h

@@ -36,9 +36,11 @@ basis.
 #ifndef _lub_ctype_h
 #ifndef _lub_ctype_h
 #define _lub_ctype_h
 #define _lub_ctype_h
 
 
-#include "lub/types.h"
+#include <ctype.h>
 
 
+#include "lub/types.h"
 #include "lub/c_decl.h"
 #include "lub/c_decl.h"
+
 _BEGIN_C_DECL
 _BEGIN_C_DECL
 /**
 /**
  * This operation identifies whether a character is a decimal digit
  * This operation identifies whether a character is a decimal digit

+ 1 - 9
lub/string/module.am

@@ -1,12 +1,4 @@
 liblub_la_SOURCES += \
 liblub_la_SOURCES += \
-	lub/string/string_cat.c\
-	lub/string/string_catn.c \
-	lub/string/string_dup.c \
-	lub/string/string_free.c \
-	lub/string/string_nocasecmp.c \
-	lub/string/string_nocasestr.c \
-	lub/string/string_suffix.c \
-	lub/string/string_escape.c \
-	lub/string/string_word.c \
+	lub/string/string.c \
 	lub/string/private.h
 	lub/string/private.h
 
 

+ 340 - 0
lub/string/string.c

@@ -0,0 +1,340 @@
+/*
+ * string.c
+ */
+#include "private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "lub/ctype.h"
+
+const char *lub_string_esc_default = "`|$<>&()#;\\\"!";
+const char *lub_string_esc_regex = "^$.*+[](){}";
+const char *lub_string_esc_quoted = "\\\"";
+
+/*--------------------------------------------------------- */
+void lub_string_free(char *ptr)
+{
+	free(ptr);
+}
+
+/*--------------------------------------------------------- */
+char *lub_string_ndecode(const char *string, unsigned int len)
+{
+	const char *s = string;
+	char *res, *p;
+	int esc = 0;
+
+	if (!string)
+		return NULL;
+
+	/* Allocate enough memory for result */
+	p = res = malloc(len + 1);
+
+	while (*s && (s < (string +len))) {
+		if (!esc) {
+			if ('\\' == *s)
+				esc = 1;
+			else
+				*p = *s;
+		} else {
+/*			switch (*s) {
+			case 'r':
+			case 'n':
+				*p = '\n';
+				break;
+			case 't':
+				*p = '\t';
+				break;
+			default:
+				*p = *s;
+				break;
+			}
+*/			*p = *s;
+			esc = 0;
+		}
+		if (!esc)
+			p++;
+		s++;
+	}
+	*p = '\0';
+
+	return res;
+}
+
+/*--------------------------------------------------------- */
+inline char *lub_string_decode(const char *string)
+{
+	return lub_string_ndecode(string, strlen(string));
+}
+
+/*----------------------------------------------------------- */
+/*
+ * This needs to escape any dangerous characters within the command line
+ * to prevent gaining access to the underlying system shell.
+ */
+char *lub_string_encode(const char *string, const char *escape_chars)
+{
+	char *result = NULL;
+	const char *p;
+
+	if (!escape_chars)
+		return lub_string_dup(string);
+	if (string && !(*string)) /* Empty string */
+		return lub_string_dup(string);
+
+	for (p = string; p && *p; p++) {
+		/* find any special characters and prefix them with '\' */
+		size_t len = strcspn(p, escape_chars);
+		lub_string_catn(&result, p, len);
+		p += len;
+		if (*p) {
+			lub_string_catn(&result, "\\", 1);
+			lub_string_catn(&result, p, 1);
+		} else {
+			break;
+		}
+	}
+	return result;
+}
+
+/*--------------------------------------------------------- */
+void lub_string_catn(char **string, const char *text, size_t len)
+{
+	if (text) {
+		char *q;
+		size_t length, initlen, textlen = strlen(text);
+
+		/* make sure the client cannot give us duff details */
+		len = (len < textlen) ? len : textlen;
+
+		/* remember the size of the original string */
+		initlen = *string ? strlen(*string) : 0;
+
+		/* account for '\0' */
+		length = initlen + len + 1;
+
+		/* allocate the memory for the result */
+		q = realloc(*string, length);
+		if (NULL != q) {
+			*string = q;
+			/* move to the end of the initial string */
+			q += initlen;
+
+			while (len--) {
+				*q++ = *text++;
+			}
+			*q = '\0';
+		}
+	}
+}
+
+/*--------------------------------------------------------- */
+void lub_string_cat(char **string, const char *text)
+{
+	size_t len = text ? strlen(text) : 0;
+	lub_string_catn(string, text, len);
+}
+
+/*--------------------------------------------------------- */
+char *lub_string_dup(const char *string)
+{
+	if (!string)
+		return NULL;
+	return strdup(string);
+}
+
+/*--------------------------------------------------------- */
+char *lub_string_dupn(const char *string, unsigned int len)
+{
+	char *res = NULL;
+
+	if (!string)
+		return res;
+	res = malloc(len + 1);
+	strncpy(res, string, len);
+	res[len] = '\0';
+
+	return res;
+}
+
+/*--------------------------------------------------------- */
+int lub_string_nocasecmp(const char *cs, const char *ct)
+{
+	int result = 0;
+	while ((0 == result) && *cs && *ct) {
+		/*lint -e155 Ignoring { }'ed sequence within an expression, 0 assumed 
+		 * MACRO implementation uses braces to prevent multiple increments
+		 * when called.
+		 */
+		int s = lub_ctype_tolower(*cs++);
+		int t = lub_ctype_tolower(*ct++);
+
+		result = s - t;
+	}
+	/*lint -e774 Boolean within 'if' always evealuates to True 
+	 * not the case because of tolower() evaluating to 0 under lint
+	 * (see above)
+	 */
+	if (0 == result) {
+		/* account for different string lengths */
+		result = *cs - *ct;
+	}
+	return result;
+}
+
+/*--------------------------------------------------------- */
+char *lub_string_tolower(const char *str)
+{
+	char *tmp = strdup(str);
+	char *p = tmp;
+
+	while (*p) {
+		*p = tolower(*p);
+		p++;
+	}
+
+	return tmp;
+}
+
+/*--------------------------------------------------------- */
+const char *lub_string_nocasestr(const char *cs, const char *ct)
+{
+	const char *p = NULL;
+	const char *result = NULL;
+
+	while (*cs) {
+		const char *q = cs;
+
+		p = ct;
+		/*lint -e155 Ignoring { }'ed sequence within an expression, 0 assumed 
+		 * MACRO implementation uses braces to prevent multiple increments
+		 * when called.
+		 */
+		/*lint -e506 Constant value Boolean
+		 * not the case because of tolower() evaluating to 0 under lint
+		 * (see above)
+		 */
+		while (*p && *q
+		       && (lub_ctype_tolower(*p) == lub_ctype_tolower(*q))) {
+			p++, q++;
+		}
+		if (0 == *p) {
+			break;
+		}
+		cs++;
+	}
+	if (p && !*p) {
+		/* we've found the first match of ct within cs */
+		result = cs;
+	}
+	return result;
+}
+
+/*--------------------------------------------------------- */
+unsigned int lub_string_equal_part(const char *str1, const char *str2,
+	bool_t utf8)
+{
+	unsigned int cnt = 0;
+
+	if (!str1 || !str2)
+		return cnt;
+	while (*str1 && *str2) {
+		if (*str1 != *str2)
+			break;
+		cnt++;
+		str1++;
+		str2++;
+	}
+	if (!utf8)
+		return cnt;
+
+	/* UTF8 features */
+	if (cnt && (UTF8_11 == (*(str1 - 1) & UTF8_MASK)))
+		cnt--;
+
+	return cnt;
+}
+
+/*--------------------------------------------------------- */
+const char *lub_string_suffix(const char *string)
+{
+	const char *p1, *p2;
+	p1 = p2 = string;
+	while (*p1) {
+		if (lub_ctype_isspace(*p1)) {
+			p2 = p1;
+			p2++;
+		}
+		p1++;
+	}
+	return p2;
+}
+
+/*--------------------------------------------------------- */
+const char *lub_string_nextword(const char *string,
+	size_t *len, size_t *offset, size_t *quoted)
+{
+	const char *word;
+
+	*quoted = 0;
+
+	/* Find the start of a word (not including an opening quote) */
+	while (*string && isspace(*string)) {
+		string++;
+		(*offset)++;
+	}
+	/* Is this the start of a quoted string ? */
+	if (*string == '"') {
+		*quoted = 1;
+		string++;
+	}
+	word = string;
+	*len = 0;
+
+	/* Find the end of the word */
+	while (*string) {
+		if (*string == '\\') {
+			string++;
+			(*len)++;
+			if (*string) {
+				(*len)++;
+				string++;
+			}
+			continue;
+		}
+		/* End of word */
+		if (!*quoted && isspace(*string))
+			break;
+		if (*string == '"') {
+			/* End of a quoted string */
+			*quoted = 2;
+			break;
+		}
+		(*len)++;
+		string++;
+	}
+
+	return word;
+}
+
+/*--------------------------------------------------------- */
+unsigned int lub_string_wordcount(const char *line)
+{
+	const char *word;
+	unsigned int result = 0;
+	size_t len = 0, offset = 0;
+	size_t quoted;
+
+	for (word = lub_string_nextword(line, &len, &offset, &quoted);
+		*word || quoted;
+		word = lub_string_nextword(word + len, &len, &offset, &quoted)) {
+		/* account for the terminating quotation mark */
+		len += quoted ? quoted - 1 : 0;
+		result++;
+	}
+
+	return result;
+}
+
+/*--------------------------------------------------------- */

+ 0 - 14
lub/string/string_cat.c

@@ -1,14 +0,0 @@
-/*
- * string_cat.c
- */
-#include "private.h"
-
-#include <string.h>
-/*--------------------------------------------------------- */
-void lub_string_cat(char **string, const char *text)
-{
-	size_t len = text ? strlen(text) : 0;
-	lub_string_catn(string, text, len);
-}
-
-/*--------------------------------------------------------- */

+ 0 - 39
lub/string/string_catn.c

@@ -1,39 +0,0 @@
-/*
- * string_cat.c
- */
-#include "private.h"
-
-#include <string.h>
-#include <stdlib.h>
-/*--------------------------------------------------------- */
-void lub_string_catn(char **string, const char *text, size_t len)
-{
-	if (text) {
-		char *q;
-		size_t length, initlen, textlen = strlen(text);
-
-		/* make sure the client cannot give us duff details */
-		len = (len < textlen) ? len : textlen;
-
-		/* remember the size of the original string */
-		initlen = *string ? strlen(*string) : 0;
-
-		/* account for '\0' */
-		length = initlen + len + 1;
-
-		/* allocate the memory for the result */
-		q = realloc(*string, length);
-		if (NULL != q) {
-			*string = q;
-			/* move to the end of the initial string */
-			q += initlen;
-
-			while (len--) {
-				*q++ = *text++;
-			}
-			*q = '\0';
-		}
-	}
-}
-
-/*--------------------------------------------------------- */

+ 0 - 32
lub/string/string_dup.c

@@ -1,32 +0,0 @@
-/*
- * string_dup.c
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include "private.h"
-
-/*--------------------------------------------------------- */
-char *lub_string_dup(const char *string)
-{
-	if (!string)
-		return NULL;
-	return strdup(string);
-}
-
-/*--------------------------------------------------------- */
-char *lub_string_dupn(const char *string, unsigned int len)
-{
-	char *res = NULL;
-
-	if (!string)
-		return res;
-	res = malloc(len + 1);
-	strncpy(res, string, len);
-	res[len] = '\0';
-
-	return res;
-}
-
-
-/*--------------------------------------------------------- */

+ 0 - 93
lub/string/string_escape.c

@@ -1,93 +0,0 @@
-/*
- * string_escape.c
- */
-#include "private.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-const char *lub_string_esc_default = "`|$<>&()#;\\\"!";
-const char *lub_string_esc_regex = "^$.*+[](){}";
-const char *lub_string_esc_quoted = "\\\"";
-
-/*--------------------------------------------------------- */
-char *lub_string_ndecode(const char *string, unsigned int len)
-{
-	const char *s = string;
-	char *res, *p;
-	int esc = 0;
-
-	if (!string)
-		return NULL;
-
-	/* Allocate enough memory for result */
-	p = res = malloc(len + 1);
-
-	while (*s && (s < (string +len))) {
-		if (!esc) {
-			if ('\\' == *s)
-				esc = 1;
-			else
-				*p = *s;
-		} else {
-/*			switch (*s) {
-			case 'r':
-			case 'n':
-				*p = '\n';
-				break;
-			case 't':
-				*p = '\t';
-				break;
-			default:
-				*p = *s;
-				break;
-			}
-*/			*p = *s;
-			esc = 0;
-		}
-		if (!esc)
-			p++;
-		s++;
-	}
-	*p = '\0';
-
-	return res;
-}
-
-/*--------------------------------------------------------- */
-inline char *lub_string_decode(const char *string)
-{
-	return lub_string_ndecode(string, strlen(string));
-}
-
-/*----------------------------------------------------------- */
-/*
- * This needs to escape any dangerous characters within the command line
- * to prevent gaining access to the underlying system shell.
- */
-char *lub_string_encode(const char *string, const char *escape_chars)
-{
-	char *result = NULL;
-	const char *p;
-
-	if (!escape_chars)
-		return lub_string_dup(string);
-	if (string && !(*string)) /* Empty string */
-		return lub_string_dup(string);
-
-	for (p = string; p && *p; p++) {
-		/* find any special characters and prefix them with '\' */
-		size_t len = strcspn(p, escape_chars);
-		lub_string_catn(&result, p, len);
-		p += len;
-		if (*p) {
-			lub_string_catn(&result, "\\", 1);
-			lub_string_catn(&result, p, 1);
-		} else {
-			break;
-		}
-	}
-	return result;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 14
lub/string/string_free.c

@@ -1,14 +0,0 @@
-/*
- * string_free.c
- */
-#include "private.h"
-
-#include <stdlib.h>
-
-/*--------------------------------------------------------- */
-void lub_string_free(char *ptr)
-{
-	free(ptr);
-}
-
-/*--------------------------------------------------------- */

+ 0 - 51
lub/string/string_nocasecmp.c

@@ -1,51 +0,0 @@
-/*
- * string_nocasecmp.c
- */
-#include <string.h>
-#include <ctype.h>
-
-#include "private.h"
-#include "lub/ctype.h"
-
-
-/*--------------------------------------------------------- */
-int lub_string_nocasecmp(const char *cs, const char *ct)
-{
-	int result = 0;
-	while ((0 == result) && *cs && *ct) {
-		/*lint -e155 Ignoring { }'ed sequence within an expression, 0 assumed 
-		 * MACRO implementation uses braces to prevent multiple increments
-		 * when called.
-		 */
-		int s = lub_ctype_tolower(*cs++);
-		int t = lub_ctype_tolower(*ct++);
-
-		result = s - t;
-	}
-	/*lint -e774 Boolean within 'if' always evealuates to True 
-	 * not the case because of tolower() evaluating to 0 under lint
-	 * (see above)
-	 */
-	if (0 == result) {
-		/* account for different string lengths */
-		result = *cs - *ct;
-	}
-	return result;
-}
-
-/*--------------------------------------------------------- */
-char *lub_string_tolower(const char *str)
-{
-	char *tmp = strdup(str);
-	char *p = tmp;
-
-	while (*p) {
-		*p = tolower(*p);
-		p++;
-	}
-
-	return tmp;
-}
-
-
-/*--------------------------------------------------------- */

+ 0 - 69
lub/string/string_nocasestr.c

@@ -1,69 +0,0 @@
-/*
- * string_nocasestr.c
- *
- * Find a string within another string in a case insensitive manner
- */
-#include "private.h"
-
-#include "lub/ctype.h"
-
-/*--------------------------------------------------------- */
-const char *lub_string_nocasestr(const char *cs, const char *ct)
-{
-	const char *p = NULL;
-	const char *result = NULL;
-
-	while (*cs) {
-		const char *q = cs;
-
-		p = ct;
-		/*lint -e155 Ignoring { }'ed sequence within an expression, 0 assumed 
-		 * MACRO implementation uses braces to prevent multiple increments
-		 * when called.
-		 */
-		/*lint -e506 Constant value Boolean
-		 * not the case because of tolower() evaluating to 0 under lint
-		 * (see above)
-		 */
-		while (*p && *q
-		       && (lub_ctype_tolower(*p) == lub_ctype_tolower(*q))) {
-			p++, q++;
-		}
-		if (0 == *p) {
-			break;
-		}
-		cs++;
-	}
-	if (p && !*p) {
-		/* we've found the first match of ct within cs */
-		result = cs;
-	}
-	return result;
-}
-
-/*--------------------------------------------------------- */
-unsigned int lub_string_equal_part(const char *str1, const char *str2,
-	bool_t utf8)
-{
-	unsigned int cnt = 0;
-
-	if (!str1 || !str2)
-		return cnt;
-	while (*str1 && *str2) {
-		if (*str1 != *str2)
-			break;
-		cnt++;
-		str1++;
-		str2++;
-	}
-	if (!utf8)
-		return cnt;
-
-	/* UTF8 features */
-	if (cnt && (UTF8_11 == (*(str1 - 1) & UTF8_MASK)))
-		cnt--;
-
-	return cnt;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 22
lub/string/string_suffix.c

@@ -1,22 +0,0 @@
-/*
- * string_suffix.c
- */
-#include "private.h"
-
-#include "lub/ctype.h"
-/*--------------------------------------------------------- */
-const char *lub_string_suffix(const char *string)
-{
-	const char *p1, *p2;
-	p1 = p2 = string;
-	while (*p1) {
-		if (lub_ctype_isspace(*p1)) {
-			p2 = p1;
-			p2++;
-		}
-		p1++;
-	}
-	return p2;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 76
lub/string/string_word.c

@@ -1,76 +0,0 @@
-/*
- * /lub/string/string_word.c
- */
-#include <stddef.h>
-#include <ctype.h>
-
-#include "private.h"
-#include "lub/types.h"
-
-/*--------------------------------------------------------- */
-const char *lub_string_nextword(const char *string,
-	size_t *len, size_t *offset, size_t *quoted)
-{
-	const char *word;
-
-	*quoted = 0;
-
-	/* Find the start of a word (not including an opening quote) */
-	while (*string && isspace(*string)) {
-		string++;
-		(*offset)++;
-	}
-	/* Is this the start of a quoted string ? */
-	if (*string == '"') {
-		*quoted = 1;
-		string++;
-	}
-	word = string;
-	*len = 0;
-
-	/* Find the end of the word */
-	while (*string) {
-		if (*string == '\\') {
-			string++;
-			(*len)++;
-			if (*string) {
-				(*len)++;
-				string++;
-			}
-			continue;
-		}
-		/* End of word */
-		if (!*quoted && isspace(*string))
-			break;
-		if (*string == '"') {
-			/* End of a quoted string */
-			*quoted = 2;
-			break;
-		}
-		(*len)++;
-		string++;
-	}
-
-	return word;
-}
-
-/*--------------------------------------------------------- */
-unsigned int lub_string_wordcount(const char *line)
-{
-	const char *word;
-	unsigned int result = 0;
-	size_t len = 0, offset = 0;
-	size_t quoted;
-
-	for (word = lub_string_nextword(line, &len, &offset, &quoted);
-		*word || quoted;
-		word = lub_string_nextword(word + len, &len, &offset, &quoted)) {
-		/* account for the terminating quotation mark */
-		len += quoted ? quoted - 1 : 0;
-		result++;
-	}
-
-	return result;
-}
-
-/*--------------------------------------------------------- */