/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "chain_string.h"
struct chain_string *new_chain_string(const char *value) {
/* -----------------------------------------------------------------------------
* Create a new chain string
*
* @param const char *
* @return struct chain_string *
* -------------------------------------------------------------------------- */
struct chain_string *new_pts;
new_pts = (struct chain_string *)malloc(sizeof(struct chain_string));
if (new_pts == NULL) {
logmsg(LOG_ERR, "new_chain_string() : malloc error");
return NULL;
}
new_pts->value = strdup(value);
if (new_pts->value == NULL) {
logmsg(LOG_ERR, "new_chain_string() : strdup error");
new_pts->length = 0;
}
else
new_pts->length = strlen(value);
new_pts->previous = NULL;
new_pts->next = NULL;
return new_pts;
}
struct chain_string *new_chains_string(struct chain_string * first, ...) {
/* -----------------------------------------------------------------------------
* Create new chain string with several string
*
* @param const char *
* @return struct chain_string *
* -------------------------------------------------------------------------- */
va_list args;
struct chain_string *pts;
struct chain_string *result = first;
va_start(args, first);
while ((pts = va_arg(args, struct chain_string *)) != NULL) {
append_chain_string(pts, result);
}
va_end(args);
return result;
}
void drop_all_chain_string(struct chain_string *root_chain_string) {
/* -----------------------------------------------------------------------------
* Destroy a chain string from the specified root
*
* @param struct chain_string *
* -------------------------------------------------------------------------- */
struct chain_string *pts;
struct chain_string *pts_tmp;
if (root_chain_string == NULL) return;
pts = root_chain_string;
while(pts != NULL) {
free(pts->value);
pts_tmp = pts->next;
free(pts);
pts = pts_tmp;
}
}
struct chain_string * add_chain_string(struct chain_string *new_chain_string,
struct chain_string *chain_string_dest,
unsigned int position) {
/* -----------------------------------------------------------------------------
* Insert a string in a chain string at the given position
* if the given position is greater thant the chain_string size,
* the new chain_string will be add to the end
*
* @param struct chain_string *, the chain string to insert
* @param struct chain_string *, where to insert
* @param int
* @return struct chain_string *, the new root chain string
* A <-> B <-> C <-> D .... insert T, position 1
* A <-> T <-> B <-> C <-> D
* -------------------------------------------------------------------------- */
struct chain_string *pts, *pts_last;
pts = get_chain_string(chain_string_dest, position);
pts_last = get_last_chain_string(new_chain_string);
new_chain_string->previous = pts->previous;
pts->previous = pts_last;
pts_last->next = pts;
if (new_chain_string->previous != NULL)
new_chain_string->previous->next = new_chain_string;
return (position == 0) ? new_chain_string : chain_string_dest;
}
struct chain_string * delete_chain_string(struct chain_string *chain_string_root,
unsigned int position) {
/* -----------------------------------------------------------------------------
* Delete a chain string at the given position
* if the given position is greater thant the chain_string size,
* the last chain_string will be deleted
*
* @param struct chain_string *, the chain string where to delete
* @param int
* @return struct chain_string *, the new root chain string
* A <-> B <-> C <-> D .... delete in position 1
* A <-> C <-> D
* -------------------------------------------------------------------------- */
struct chain_string *pts, *new_root;
pts = get_chain_string(chain_string_root, position);
if (pts == NULL) return chain_string_root;
if (pts->previous != NULL)
pts->previous->next = pts->next;
if (pts->next != NULL)
pts->next->previous = pts->previous;
if (pts == chain_string_root) {
if (pts->next != NULL)
new_root = pts->next;
else
new_root = NULL;
}
else
new_root = chain_string_root;
free(pts->value);
free(pts);
return new_root;
}
struct chain_string * delete_chain_string_by_value(struct chain_string *chain_string_root,
const char *value) {
/* -----------------------------------------------------------------------------
* Delete a chain string by value
* The first chain string with the given value will be deleted
*
* @param struct chain_string *, the chain string where to delete
* @param const char *
* @return struct chain_string *, the new root chain string
* A <-> B <-> C <-> D .... delete in position 1
* A <-> C <-> D
* -------------------------------------------------------------------------- */
struct chain_string *pts, *new_root;
pts = get_chain_string_by_value(chain_string_root, value);
if (pts == NULL) return chain_string_root;
if (pts->previous != NULL)
pts->previous->next = pts->next;
if (pts->next != NULL)
pts->next->previous = pts->previous;
if (pts == chain_string_root) {
if (pts->next != NULL)
new_root = pts->next;
else
new_root = NULL;
}
else
new_root = chain_string_root;
free(pts->value);
free(pts);
return new_root;
}
unsigned int replace_chain_string_value(struct chain_string *chain_string_root,
const char *oldvalue,
const char *newvalue) {
/* -----------------------------------------------------------------------------
* Replace a value by another
*
* @param struct chain_string *, the chain string where to do the replace
* @param const char *, the string to replace
* @param const char *, the string replacment
* @return int
* -------------------------------------------------------------------------- */
struct chain_string *pts = NULL;
pts = get_chain_string_by_value(chain_string_root, oldvalue);
if (pts == NULL)
return 0;
free(pts->value);
pts->value = strdup(newvalue);
if (pts->value == NULL)
return 0;
return 1;
}
struct chain_string *get_chain_string(struct chain_string *chain_string_root,
unsigned int position) {
/* -----------------------------------------------------------------------------
* Get a chain string by position
* if the given position is greater thant the chain_string size,
* the last chain_string will be got
*
* @param struct chain_string *, the chain string where to search
* @param int
* @return struct chain_string *
* -------------------------------------------------------------------------- */
struct chain_string *pts;
unsigned int count = 0;
for (pts = chain_string_root; pts != NULL && count < position; count++, pts = pts->next);
return pts;
}
struct chain_string *get_chain_string_by_value(struct chain_string *chain_string_root,
const char *value) {
/* -----------------------------------------------------------------------------
* Get a chain string by value
*
* @param struct chain_string *, the chain string where to search
* @param const char *
* @return struct chain_string * or NULL if not found
* -------------------------------------------------------------------------- */
struct chain_string *pts;
for (pts = chain_string_root; pts != NULL && strcmp(pts->value, value) != 0; pts = pts->next);
return pts;
}
struct chain_string *get_last_chain_string(struct chain_string *chain_string_root) {
/* -----------------------------------------------------------------------------
* Get the last chain string
*
* @param struct chain_string *, the chain string where to search
* @return struct chain_string *
* -------------------------------------------------------------------------- */
struct chain_string *pts;
for (pts = chain_string_root; pts->next != NULL; pts = pts->next);
return pts;
}
unsigned int get_nb_chain_string(struct chain_string *chain_string_root) {
/* -----------------------------------------------------------------------------
* Get the number of elements
*
* @param struct chain_string *, the chain string where to search
* @return int
* -------------------------------------------------------------------------- */
struct chain_string *pts;
unsigned int count = 0;
for (pts = chain_string_root; pts != NULL; count++, pts = pts->next);
return count;
}
struct chain_string *explode_to_chain_string(const char * strin, const char * delimiters) {
/* -----------------------------------------------------------------------------
* Parse a string and explode it to several chain string by delimiters
*
* @param const char *, source string
* @param const char *, delimiters
* @return struct chain_string *
* -------------------------------------------------------------------------- */
struct chain_string *pts = NULL;
char *strin_cp = NULL;
char *strin_cp_tmp = NULL;
char *word = NULL;
char *pts_tok = NULL;
strin_cp = strdup(strin);
if (strin_cp == NULL) {
return NULL;
}
strin_cp_tmp = strin_cp;
word = strtok_r(strin_cp_tmp, delimiters, &pts_tok);
if (word != NULL) {
pts = new_chain_string(word);
while ((word = strtok_r(NULL, delimiters, &pts_tok)) != NULL) {
append_chain_string(new_chain_string(word), pts);
}
}
else {
free(strin_cp);
return NULL;
}
free(strin_cp);
return pts;
}
struct chain_string *copy_chain_string(struct chain_string *chain_string_root) {
/* -----------------------------------------------------------------------------
* Copy chain string
*
* @param struct chain_string *, the chain string where to copy
* @return struct chain_string *, thz new copy
* -------------------------------------------------------------------------- */
struct chain_string *chain_string_copy;
struct chain_string *pts;
if (chain_string_root == NULL) return NULL;
pts = chain_string_root;
chain_string_copy = new_chain_string((const char *)pts->value);
pts = pts->next;
while(pts != NULL) {
append_chain_string(new_chain_string((const char *)pts->value), chain_string_copy);
pts = pts->next;
}
return chain_string_copy;
}
void append_chain_string(struct chain_string *new_chain_string,
struct chain_string *chain_string_dest) {
/* -----------------------------------------------------------------------------
* Insert a chain string at the end
*
* @param struct chain_string *, the chain string to add
* @param struct chain_string *, the root chain string
* A <-> B <-> C <-> D .... insert T at the end
* A <-> B <-> C <-> D <-> T
* -------------------------------------------------------------------------- */
struct chain_string *pts;
for (pts = chain_string_dest; pts->next != NULL; pts = pts->next);
new_chain_string->previous = pts;
pts->next = new_chain_string;
}
char * chain_string_join(struct chain_string *chain_string_root,
const char *glue, unsigned int position) {
/* -----------------------------------------------------------------------------
* Join all chain string element in one string with the given glue
*
* @param struct chain_string *, the root chain string
* @param const char *, glue,
* @param int, the offset
* @return char *, a new string dynamically allocated or NULL
* -------------------------------------------------------------------------- */
char *result = NULL, *result_realloc = NULL;
struct chain_string *pts = NULL;
unsigned int count = 0;
int len = 0, total_size = 0, len_glue = 0;
for (pts = chain_string_root; pts != NULL && count < position; count++, pts = pts->next);
if (pts == NULL) return NULL;
len_glue = strlen(glue);
while (pts != NULL) {
len = strlen(pts->value);
total_size += len;
if (pts->next != NULL)
total_size += len_glue;
result_realloc = (char *)realloc(result, (total_size + 1) * sizeof(char));
if (result_realloc == NULL)
return NULL;
result = result_realloc;
if (pts->next != NULL) {
memcpy(&result[total_size - len - len_glue], pts->value, len * sizeof(char));
memcpy(&result[total_size - len_glue], glue, len_glue * sizeof(char));
}
else {
memcpy(&result[total_size - len], pts->value, len * sizeof(char));
result[total_size] = '\0';
}
pts = pts->next;
}
return result;
}
void print_chain_string(struct chain_string *chain_string_root) {
/* -----------------------------------------------------------------------------
* Print a chain string to stdout
*
* @param struct chain_string *, the root chain string
* -------------------------------------------------------------------------- */
struct chain_string *pts;
for (pts = chain_string_root; pts != NULL; pts = pts->next) {
printf("%s -> ", pts->value);
}
printf("\n");
}
void print_reverse_chain_string(struct chain_string *chain_string_root_reverse) {
/* -----------------------------------------------------------------------------
* Print a chain string to stdout from the end
*
* @param struct chain_string *, the root chain string
* -------------------------------------------------------------------------- */
struct chain_string *pts;
for (pts = chain_string_root_reverse; pts != NULL; pts = pts->previous) {
printf("%s -> ", pts->value);
}
printf("\n");
}
void print_all_chain_string(struct chain_string *chain_string_root) {
/* -----------------------------------------------------------------------------
* Print a chain string to stdout from the beginning to the end and from the end
* to the beginning
*
* @param struct chain_string *, the root chain string
* -------------------------------------------------------------------------- */
struct chain_string *pts = NULL;
struct chain_string *last_pts = NULL;
for (pts = chain_string_root; pts != NULL; last_pts = pts, pts = pts->next) {
printf("%s -> ", pts->value);
}
printf("\n");
for (pts = last_pts; pts != NULL; pts = pts->previous) {
printf("%s -> ", pts->value);
}
printf("\n");
}
syntax highlighted by Code2HTML, v. 0.9.1