Back to index

avfs  1.0.1
string_utils.h
Go to the documentation of this file.
00001 /* 
00002    String utility functions
00003    Copyright (C) 1999-2001, Joe Orton <joe@light.plus.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018    MA 02111-1307, USA
00019 
00020 */
00021 
00022 #ifndef STRING_UTILS_H
00023 #define STRING_UTILS_H
00024 
00025 #include "neon_defs.h"
00026 
00027 #include <stdarg.h>
00028 
00029 #include <ctype.h> /* for tolower */
00030 
00031 BEGIN_NEON_DECLS
00032 
00033 #define ASC2HEX(x) (((x) <= '9') ? ((x) - '0') : (tolower((x)) + 10 - 'a'))
00034 #define HEX2ASC(x) ((x) > 9 ? ((x) - 10 + 'a') : ((x) + '0'))
00035 
00036 /* Returns a ne_malloc-allocated UTF-8 encoded copy of 'str'. */
00037 char *ne_utf8_encode(const char *str);
00038 
00039 /* Splits str into component parts using given seperator,
00040  * skipping given whitespace around separators and at the 
00041  * beginning and end of str. Separators are ignored within
00042  * any pair of characters specified as being quotes.
00043  * Returns array of components followed by a NULL pointer. The
00044  * components are taken from dynamically allocated memory, and
00045  * the entire array can be easily freed using split_string_free.
00046  *
00047  * aka: What strtok should have been.
00048  */
00049 char **split_string(const char *str, const char seperator,
00050                   const char *quotes, const char *whitespace);
00051 
00052 /* As above, but returns count of items as well */
00053 char **split_string_c(const char *str, const char seperator,
00054                     const char *quotes, const char *whitespace, int *count);
00055 
00056 /* A bit like split_string, except each component is split into a pair.
00057  * Each pair is returned consecutively in the return array.
00058  *  e.g.:
00059  *     strpairs("aa=bb,cc=dd", ',', '=', NULL, NULL)
00060  *  =>   "aa", "bb", "cc", "dd", NULL, NULL
00061  * Note, that if a component is *missing* it's key/value separator,
00062  * then the 'value' in the array will be a NULL pointer. But, if the
00063  * value is zero-length (i.e., the component separator follows directly
00064  * after the key/value separator, or with only whitespace inbetween),
00065  * then the value in the array will be a zero-length string.
00066  *  e.g.:
00067  *     pair_string("aaaa,bb=cc,dd=,ee=ff", ',', '=', NULL, NULL)
00068  *  =>   "aaaa", NULL, "bb", "cc", "dd", "", "ee", "ff"
00069  * A NULL key indicates the end of the array (the value will also 
00070  * be NULL, for convenience).
00071  */
00072 char **pair_string(const char *str, const char compsep, const char kvsep, 
00073                  const char *quotes, const char *whitespace);
00074 
00075 /* Frees the array returned by split_string */
00076 void split_string_free(char **components);
00077 
00078 /* Frees the array returned by pair_string */
00079 void pair_string_free(char **pairs);
00080 
00081 /* Returns a string which is str with ch stripped from
00082  * beggining and end, if present in either. The string returned
00083  * is dynamically allocated using malloc().
00084  *
00085  * e.g.  shave_string("abbba", 'a')  => "bbb". */
00086 char *shave_string(const char *str, const char ch);
00087 
00088 #define EOL "\r\n"
00089 
00090 #define STRIP_EOL(str)                           \
00091 do {                                             \
00092    char *p;                                      \
00093    if ((p = strrchr(str, '\r')) != NULL) *p = '\0';     \
00094    if ((p = strrchr(str, '\n')) != NULL) *p = '\0';     \
00095 } while (0)
00096 
00097 /* Return concatenation of all given strings. */
00098 char *ne_concat(const char *str, ...);
00099 
00100 /* String buffer handling. (Strings are zero-terminated still).
00101  * A string buffer sbuffer * which grows dynamically with the string. */
00102 
00103 struct sbuffer_s;
00104 typedef struct sbuffer_s *sbuffer;
00105 
00106 /* Returns contents of buffer at current point in time.
00107  * NOTE: if the buffer is modified with _concat, _append etc,
00108  * this value may no longer be correct. */
00109 char *sbuffer_data(sbuffer buf);
00110 
00111 /* Quick and dirty cast of buf into a 'char *'. 
00112  * Relies on sbuffer internal ordering. */
00113 #define SBUFFER_CAST(buf) (*(char **)buf)
00114 
00115 /* Returns size of data in buffer, equiv to strlen(sbuffer_data(buf)) */
00116 int sbuffer_size(sbuffer buf);
00117 
00118 /* Concatenate all given strings onto the end of the buffer.
00119  * The strings must be null-terminated, and MUST be followed by a
00120  * NULL argument marking the end of the list.
00121  * Returns:
00122  *   0 on success
00123  *   non-zero on error
00124  */
00125 int sbuffer_concat(sbuffer buf, ...);
00126 
00127 /* Create a new sbuffer. Returns NULL on error */
00128 sbuffer sbuffer_create(void);
00129 
00130 /* Create a new sbuffer of given minimum size. Returns NULL on error */
00131 sbuffer sbuffer_create_sized(size_t size);
00132 
00133 /* Destroys (deallocates) a buffer */
00134 void sbuffer_destroy(sbuffer buf);
00135 
00136 /* Append a zero-terminated string 'str' to buf.
00137  * Returns 0 on success, non-zero on error. */
00138 int sbuffer_zappend(sbuffer buf, const char *str);
00139 
00140 /* Append 'len' bytes of 'data' to buf.  'data' does not need to be
00141  * zero-terminated. The resultant string will have a zero-terminator,
00142  * either way. Returns 0 on success, non-zero on error.  */
00143 int sbuffer_append(sbuffer buf, const char *data, size_t len);
00144 
00145 /* Empties the contents of buf; makes the buffer zero-length. */
00146 void sbuffer_clear(sbuffer buf);
00147 
00148 /* Grows the sbuffer to a minimum size.
00149  * Returns 0 on success, non-zero on error */
00150 int sbuffer_grow(sbuffer buf, size_t size);
00151 
00152 void sbuffer_altered(sbuffer buf);
00153 
00154 /* MD5 ascii->binary conversion */
00155 void md5_to_ascii(const unsigned char md5_buf[16], char *buffer);
00156 void ascii_to_md5(const char *buffer, unsigned char md5_buf[16]);
00157 
00158 /* Destroys a buffer, WITHOUT freeing the data, and returns the
00159  * data. */
00160 char *sbuffer_finish(sbuffer buf);
00161 
00162 /* Handy macro to free things. */
00163 #define SAFE_FREE(x) \
00164 do { if ((x)!=NULL) free((x)); (x) = NULL; } while (0)
00165 
00166 /* TODO: do these with stpcpy instead... more efficient, but means 
00167  * bloat on non-GNU platforms. */
00168 
00169 /* TODO: could replace with glib equiv's where available, too */
00170 
00171 /* NOTES:
00172  *  - These abort() on malloc() returning NULL
00173  *  - You will need to #include <string.h> / <strings.h> YOURSELF to
00174  *    prototype strlen and strcat.
00175  */
00176 
00177 #define CONCAT2(out, str1, str2)                 \
00178 do {                                             \
00179     out = malloc(strlen(str1) + strlen(str2) + 1);      \
00180     if (out != NULL) {                                  \
00181        strcpy(out, str1);                        \
00182        strcat(out, str2);                        \
00183     } else {                                     \
00184        abort();                                  \
00185     }                                            \
00186 } while (0)
00187 
00188 #define CONCAT3(out, str1, str2, str3)                         \
00189 do {                                                           \
00190     out = malloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);     \
00191     if (out != NULL) {                                                \
00192        strcpy(out, str1);                                      \
00193        strcat(out, str2);                                      \
00194        strcat(out, str3);                                      \
00195     } else {                                                   \
00196        abort();                                                \
00197     }                                                          \
00198 } while (0)
00199 
00200 #define CONCAT4(out, str1, str2, str3, str4)            \
00201 do {                                             \
00202     out = malloc(strlen(str1) + strlen(str2)            \
00203                 + strlen(str3) + strlen(str4) + 1);     \
00204     if (out != NULL) {                                  \
00205        strcpy(out, str1);                        \
00206        strcat(out, str2);                        \
00207        strcat(out, str3);                        \
00208        strcat(out, str4);                        \
00209     } else {                                     \
00210        abort();                                  \
00211     }                                            \
00212 } while (0)
00213 
00214 END_NEON_DECLS
00215 
00216 #endif /* STRING_UTILS_H */
00217 
00218