| /****************************************************************************** |
| *(C) Copyright 2008 Marvell International Ltd. |
| * All Rights Reserved |
| ******************************************************************************/ |
| /*-------------------------------------------------------------------------------------------------------------------- |
| * ------------------------------------------------------------------------------------------------------------------- |
| * |
| * Filename: mstring.c |
| * |
| * Description: Various helper functions to manipulate strings. |
| * |
| * History: |
| * Nov, 19 2012 - Haili Wang(hlw@marvell.com) Creation of file |
| * |
| * Notes: |
| * |
| ******************************************************************************/ |
| #include "mstring.h" |
| #include <stdio.h> |
| #include <stdarg.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <limits.h> |
| |
| MString* MStringCreate() |
| { |
| MString* s; |
| |
| s = (MString*) calloc(1, sizeof(*s)); |
| return s; |
| } |
| |
| void MStringDestroy(void* s) |
| { |
| free(s); |
| } |
| |
| int MStringAppend(MString* src, char* append, int newline) |
| { |
| int len, size, empty = 0; |
| |
| if(!src || !append) return -1; |
| len = strlen(append) + src->len + (newline != 0); |
| if(src->size <= len) |
| { |
| if(src->size == 0) |
| { |
| size = 1; |
| empty = 1; |
| } |
| else |
| size = src->size; |
| do |
| { |
| size <<= 1; |
| if(size > INT_MAX/2) break; |
| }while(size <= len); |
| src->str = (char*) realloc(src->str, size); |
| if(!src->str) return -1; |
| else src->size = size; |
| } |
| if(empty) |
| src->str[0] = '\0'; |
| strcat(src->str, append); |
| if(newline) |
| { |
| src->str[len - 1] = '\n'; |
| src->str[len] = '\0'; |
| } |
| src->len = len; |
| return len; |
| } |
| |
| int MStringAppendChar(MString* src, char append) |
| { |
| char buf[2]; |
| |
| if(!src) return -1; |
| if(src->size > src->len + 1) |
| { |
| src->str[src->len] = append; |
| src->len ++; |
| src->str[src->len] = '\0'; |
| return src->len; |
| } |
| else |
| { |
| buf[0] = append; |
| buf[1] = '\0'; |
| return MStringAppend(src, buf, 0); |
| } |
| } |
| |
| int MStringPrintf (MString *str, const char *format, ...) |
| { |
| char* tmp; |
| int len; |
| va_list args; |
| |
| va_start(args, format); |
| len = vasprintf(&tmp, format, args); |
| if(len >= 0) |
| { |
| len = MStringAppend(str, tmp, 0); |
| free(tmp); |
| } |
| va_end(args); |
| return len; |
| } |
| |
| #ifndef __GNUC__ |
| char *strndup(const char *s, size_t n) |
| { |
| char* str; |
| |
| str = (char*) malloc(n + 1); |
| if(!str) return NULL; |
| strncpy(str, s, n); |
| str[n] = '\0'; |
| return str; |
| } |
| |
| int vasprintf(char **ret, const char *format, va_list args) |
| { |
| int count; |
| va_list copy; |
| va_copy(copy, args); |
| |
| *ret = NULL; |
| |
| count = vsnprintf(NULL, 0, format, args); |
| if (count >= 0) |
| { |
| char* buffer = (char*) malloc(count + 1); |
| if (buffer != NULL) |
| { |
| count = vsnprintf(buffer, count + 1, format, copy); |
| if (count < 0) |
| free(buffer); |
| else |
| *ret = buffer; |
| } |
| else |
| count = -1; |
| } |
| |
| va_end(copy); |
| return count; |
| } |
| |
| int asprintf(char **ret, const char *format, ...) |
| { |
| int count; |
| va_list args; |
| |
| va_start(args, format); |
| count = vasprintf(ret, format, args); |
| va_end(args); |
| return count; |
| } |
| #endif |