Little Palm fixes
[MonkeyD.git] / src / str.c
blob14d8f64b92127bbf0c7c5d9b730076c91fcf30a9
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
5 * Copyright (C) 2001-2010, Eduardo Silva P. <edsiper@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #define _GNU_SOURCE
23 #include <string.h>
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
29 #include "request.h"
30 #include "utils.h"
31 #include "memory.h"
32 #include "str.h"
34 #include <stdio.h>
36 /* Return a buffer with a new string from string */
37 char *mk_string_copy_substr(const char *string, int pos_init, int pos_end)
39 unsigned int size, bytes;
40 char *buffer = 0;
42 size = (unsigned int) (pos_end - pos_init) + 1;
43 if (size <= 2)
44 size = 4;
46 buffer = malloc(size);
48 if (!buffer) {
49 return NULL;
52 if (pos_init > pos_end) {
53 mk_mem_free(buffer);
54 return NULL;
57 bytes = pos_end - pos_init;
58 memcpy(buffer, string + pos_init, bytes);
59 buffer[bytes] = '\0';
61 return (char *) buffer;
64 int mk_string_char_search(char *string, int c, int n)
66 int i;
68 if (n < 0) {
69 n = strlen(string);
72 for (i = 0; i < n; i++) {
73 if (string[i] == c)
74 return i;
77 return -1;
80 /* Get position of a substring.
81 * Original version taken from google, modified in order
82 * to send the position instead the substring.
84 int _mk_string_search(char *string, char *search, int n)
86 char *np;
87 int res;
89 np = strcasestr(string, search);
90 if (!np) {
91 return -1;
94 res = np - string;
95 if (res > n && n >= 0) {
96 return -1;
98 return (np - string);
101 int mk_string_search(char *string, char *search)
103 return _mk_string_search(string, search, -1);
106 /* lookup char in reverse order */
107 int mk_string_search_r(char *string, char search, int n)
109 int i, j;
111 if (n >= 0) {
112 j = n;
114 else {
115 j = strlen(string);
118 for (i = j; i >= 0; i--) {
119 if (string[i] == search) {
120 return i;
124 return -1;
127 int mk_string_search_n(char *string, char *search, int n)
129 return _mk_string_search(string, search, n);
132 char *mk_string_remove_space(char *buf)
134 size_t bufsize;
135 int new_i = 0, i, len, spaces = 0;
136 char *new_buf = 0;
138 len = strlen(buf);
139 for (i = 0; i < len; i++) {
140 if (buf[i] == ' ') {
141 spaces++;
145 bufsize = len + 1 - spaces;
146 if (bufsize <= 1) {
147 return NULL;
150 new_buf = mk_mem_malloc(bufsize);
152 for (i = 0; i < len; i++) {
153 if (buf[i] != ' ') {
154 new_buf[new_i] = buf[i];
155 new_i++;
159 return new_buf;
162 char *mk_string_casestr(char *heystack, char *needle)
164 if (!heystack || !needle) {
165 return NULL;
168 return strcasestr(heystack, needle);
171 char *mk_string_dup(const char *s)
173 if (!s)
174 return NULL;
176 return strdup(s);
179 int mk_string_array_count(char *arr[])
181 int i = 0;
183 for (i = 0; arr[i]; i++) {
185 return i;
188 struct mk_string_line *mk_string_split_line(char *line)
190 unsigned int i = 0, len, val_len;
191 int end;
192 char *val;
193 struct mk_string_line *sl = 0, *new, *p;
195 if (!line) {
196 return NULL;
199 len = strlen(line);
201 while (i < len) {
202 end = mk_string_char_search(line + i, ' ', len - i);
204 if (end >= 0 && end + i < len) {
205 end += i;
207 if (i == end) {
208 i++;
209 continue;
212 val = mk_string_copy_substr(line, i, end);
213 val_len = end - i;
215 else {
216 val = mk_string_copy_substr(line, i, len);
217 val_len = len - i;
218 end = len;
222 /* Alloc node */
223 new = mk_mem_malloc(sizeof(struct mk_string_line));
224 new->val = val;
225 new->len = val_len;
226 new->next = NULL;
228 /* Link node */
229 if (!sl) {
230 sl = new;
232 else {
233 p = sl;
234 while (p->next) {
235 p = p->next;
238 p->next = new;
240 i = end + 1;
243 return sl;
246 char *mk_string_build(char **buffer, unsigned long *len,
247 const char *format, ...)
249 va_list ap;
250 int length;
251 char *ptr;
252 static size_t _mem_alloc = 64;
253 size_t alloc = 0;
255 /* *buffer *must* be an empty/NULL buffer */
257 *buffer = (char *) mk_mem_malloc(_mem_alloc);
258 if (!*buffer) {
259 return NULL;
261 alloc = _mem_alloc;
263 va_start(ap, format);
264 length = vsnprintf(*buffer, alloc, format, ap);
265 va_end(ap);
267 if (length >= alloc) {
268 ptr = realloc(*buffer, length + 1);
269 if (!ptr) {
270 return NULL;
272 *buffer = ptr;
273 alloc = length + 1;
275 va_start(ap, format);
276 length = vsnprintf(*buffer, alloc, format, ap);
277 va_end(ap);
280 if (length < 0) {
281 return NULL;
284 ptr = *buffer;
285 ptr[length] = '\0';
286 *len = length;
288 return *buffer;
291 int mk_string_trim(char **str)
293 int i;
294 unsigned int len;
295 char *left = 0, *right = 0;
296 char *buf;
298 buf = *str;
299 if (!buf) {
300 return -1;
303 len = strlen(buf);
304 left = buf;
306 /* left spaces */
307 while (left) {
308 if (isspace(*left)) {
309 left++;
311 else {
312 break;
316 right = buf + (len - 1);
317 /* Validate right v/s left */
318 if (right < left) {
319 buf[0] = '\0';
320 return -1;
323 /* Move back */
324 while (right != buf){
325 if (isspace(*right)) {
326 right--;
328 else {
329 break;
333 len = (right - left) + 1;
334 for(i=0; i<len; i++){
335 buf[i] = (char) left[i];
337 buf[i] = '\0';
339 return 0;
342 int mk_string_itop(int n, mk_pointer *p)
345 Code taken from some forum...
347 int i = 0;
348 int length = 0;
349 int temp = 0;
350 char *str;
352 str = p->data;
354 if (!str) {
355 return -1;
358 /* Generate digit characters in reverse order */
359 do {
360 str[i++] = ('0' + (n % 10));
361 n /= 10;
362 } while (n>0);
364 /* Add CRLF and NULL byte */
365 str[i] = '\0';
367 p->len = length = i;
369 for (i=0; i < (length/2); i++) {
370 temp = str[i];
371 str[i] = str[length-i-1];
372 str[length-i-1] = temp;
375 i = length;
376 str[i++] = '\r';
377 str[i++] = '\n';
378 str[i++] = '\0';
380 p->len+=2;
382 return 0;