⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp-stringbuffer.c

📁 this is sample about DHCP-agent
💻 C
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-stringbuffer.c,v 1.11 2002/12/30 06:29:19 actmodern Exp $ * * Copyright 2002 Thamer Alharbash * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *  * Sringbuffer object: *  * (*) allows printfing into a string, * (*) fast string manipulation by keeping track of string length. * (*) alignment of string against columns. * * Internally stringbuffer does not count the terminating null as the length. * Therefore the raw string routines will always assume +1 when given length. */#define MODULE_NAME "dhcp-stringbuffer"#include "dhcp-local.h"#include "dhcp-libutil.h"/* * * * * * * * * * * * * * raw string routines.  * * * * * * * * * * * * * *//* just malloc out a string. */static char *allocate_string(int len){    char *s;    s = xmalloc(sizeof(char) * len + 1); /* add for null termination. */    s[len] = 0;    return s;}/* extend a string. */static char *extend_string(char *str, int cur_len, int ex_len){    str = xrealloc(str, (cur_len * sizeof(char)) + (ex_len * sizeof(char)) + (1 * sizeof(char)));    str[cur_len] = 0; /* make sure it's null terminated. */    return str;}/* get a substring. */static char *substring(char *begin, int len){    char *new_string;    new_string = allocate_string(len);    memcpy(new_string, begin, len);    new_string[len] = 0;    return new_string;}/* FIXME: get rid of pesky strlen() *//* used in aligning -- we try to get words up to end. */static char *get_string_align(char *s, int end, int *len){    char *cur_ptr;    if(s == 0 || *s == 0) /* end of string or no string. */        return NULL;    /* if strlen is smaller than len go ahead and just return it. */    if(strlen(s) < end) {        *len = strlen(s);        return xstrdup(s);    }    /* otherwise we need to hop to len */    cur_ptr = &s[end - 1];    /* now check to see if we have a whitespace behind cur_ptr     * if we do return at that point. */    for(; cur_ptr != s; cur_ptr--) {        if(*cur_ptr == ' ' || *cur_ptr == '\t') {            /* copy here and return. */            *len = (cur_ptr - s) + 1;            return (substring(s, *len));        }    }    /* keep walking till we find whitspace or end. */    for(cur_ptr = &s[end - 1]; *cur_ptr != 0 && *cur_ptr != ' ' && *cur_ptr != '\t'; cur_ptr++);    *len = (cur_ptr - s) + 1;    return (substring(s, *len));}/* zap newlines by placing spaces in their place. * we use this before aligning. */static void stringbuffer_zap_newline(stringbuffer_t *sb){    stringbuffer_replace_c(sb, '\n', ' ');    stringbuffer_replace_c(sb, '\r', ' ');}/* * * * * * * * * * * * * * * * stringbuffer routines.    * * * * * * * * * * * * * * * *//* create a new stringbuffer */stringbuffer_t *stringbuffer_create(void){    stringbuffer_t *sb;    sb = xmalloc(sizeof(stringbuffer_t));    sb->len = 0;    sb->capacity = 0;    sb->buf = allocate_string(0);    return sb;}/* destroy the stringbuffer */void stringbuffer_destroy(stringbuffer_t *sb){    xfree(sb->buf);    xfree(sb);}/* clear a string. */void stringbuffer_clear(stringbuffer_t *sb){    sb->len = 0;    sb->buf[0] = 0;}/* append character to stringbuffer */void stringbuffer_append_c(stringbuffer_t *sb, char c){    if(sb->capacity <= (sb->len)) {        sb->buf = extend_string(sb->buf, sb->len, STRINGBUFFER_CHUNKSIZE);        sb->capacity += STRINGBUFFER_CHUNKSIZE;    }    sb->buf[sb->len] = c;    sb->len++;    sb->buf[sb->len] = 0;}/* append string to stringbuffer */void stringbuffer_append(stringbuffer_t *sb, const char *s){    int len = strlen(s);    /* increase capacity if needed. */    if(sb->capacity <= (len + sb->len)) {        /* if we're bigger than the chunksize then allocate len. */        if(len > STRINGBUFFER_CHUNKSIZE) {            sb->buf = extend_string(sb->buf, sb->capacity, len);            sb->capacity += len;        } else {            /* otherwise allocate chunksize. */            sb->buf = extend_string(sb->buf, sb->capacity, STRINGBUFFER_CHUNKSIZE);            sb->capacity += STRINGBUFFER_CHUNKSIZE;        }    }    /* copy new string into place: keep in mind we know all     * lengths so strcat() would be less effecient. */    memcpy(&sb->buf[sb->len], s, len);    sb->len += len;    sb->buf[sb->len] = 0;    return;}/* remove whitespace (including tabs) */stringbuffer_t *stringbuffer_trim_whitespace(stringbuffer_t *sb){    char *newbuf;    int new_len;    int i, j;    if(sb->len == 0) /* empty string. */        return sb;    /* find beginning of string after tabs and whitespaces. */    for(i = 0; i < sb->len && (sb->buf[i] == ' ' || sb->buf[i] == '\t'); i++);    if(sb->buf[i] != '\0') {        /* we do have whitespace in the beginning so find the end. */        for(j = (sb->len -1);(sb->buf[j] == ' ' || sb->buf[j] == '\t'); j--);        /* increment j since it's on the non whitespace character. */        j++;        /* create a new string. */        new_len = j - i;        newbuf = allocate_string(new_len);        /* copy in. */        memcpy(newbuf, &sb->buf[i], (j - i) * sizeof(char));        newbuf[new_len] = 0;        /* free up old. */        xfree(sb->buf);        /* set new. */        sb->buf = newbuf;        sb->len = new_len;        sb->capacity = new_len;    } else {        /* zap beginning of string. since its all whitespace. */        sb->buf[0] = 0;        sb->len = 0;    }    return sb;}/* get the last occurance of a specific character. useful for slicing. */char *stringbuffer_get_last_occurance(stringbuffer_t *sb, char c){    char *ptr, *ptrend = NULL;    int i;    ptr = sb->buf;    for(i = 0;i < sb->len;i++) {        if(ptr[i] == c)            ptrend = &ptr[i];    }    return ptrend;}/* remove the last newline character. */void stringbuffer_trim_newline(stringbuffer_t *sb){    char *ptr;    ptr = stringbuffer_get_last_occurance(sb, '\n');    if(ptr != NULL)        *ptr = 0;    ptr = stringbuffer_get_last_occurance(sb, '\r');    if(ptr != NULL)        *ptr = 0;    sb->len = strlen(sb->buf);    return;}/* return the C string from the buffer. */const char *stringbuffer_getstring(stringbuffer_t *sb){    return sb->buf;}/* set a string into a stringbuffer */void stringbuffer_set(stringbuffer_t *dest, const char *s){    stringbuffer_clear(dest); /* zap */    stringbuffer_append(dest, s);}/* copy a stringbuffer into another stringbuffer */void stringbuffer_copy(stringbuffer_t *dest, stringbuffer_t *src){    stringbuffer_set(dest, stringbuffer_getstring(src));}/* replace in stringbuffer occurances of c with replace */void stringbuffer_replace_c(stringbuffer_t *sb, char c, char replace){    int i;    for(i = 0;i < sb->len;i++) {        if(sb->buf[i] == c)            sb->buf[i] = replace;    }    return;}/* replace in stringbuffer occurances of c with replace */void stringbuffer_replace(stringbuffer_t *sb, const char *string, const char *replace){    char *ptr;    int i;    int str_len = strlen(string);    stringbuffer_t *sb_replace;    if(string[0] == 0)        return; /* nothing to replace. */    sb_replace = stringbuffer_create();    ptr = sb->buf;    for(i = 0; i < sb->len; i++) {        if((sb->len - i) < str_len) {            /* copy in. */            stringbuffer_copy(sb, sb_replace);            /* append what's left. */            stringbuffer_append(sb, &ptr[i]);            /* free up. */            stringbuffer_destroy(sb_replace);            /* we're done. */            return;        }        if(ptr[i] == string[0]) {            /* we know that we have at least enough to complete string. */            if(!memcmp(&ptr[i], string, str_len)) {                                /* we have a match, replace. */                stringbuffer_append(sb_replace, replace);                i += (str_len - 1);                continue;            }        }        stringbuffer_append_c(sb_replace, ptr[i]);    }    /* we're done: we should only get here if the last string to       be replaced ended the string itself. */    /* copy in. */    stringbuffer_copy(sb, sb_replace);    /* free up. */    stringbuffer_destroy(sb_replace);    /* we're done. */    return;}/* align a stringbuffer on begin and end columns. */void stringbuffer_align(stringbuffer_t *sb, int begin, int end){    char *ptr, *word_string;    stringbuffer_t *aligned_string;    int len, i;    stringbuffer_zap_newline(sb);    aligned_string = stringbuffer_create();    ptr = sb->buf;    while(1) {        word_string = get_string_align(ptr, end, &len);        if(word_string == NULL)            break;        ptr += len;        for(i = 0; i < begin; i++)            stringbuffer_append(aligned_string, " ");        stringbuffer_append(aligned_string, word_string);        stringbuffer_append(aligned_string, "\n");        xfree(word_string);    }    stringbuffer_copy(sb, aligned_string);    stringbuffer_destroy(aligned_string);    return;}/* stringbuffer_*printf* these all use snprintf/snvprintf internally *//* append vprintf with alignment. */void stringbuffer_avprintf_align(stringbuffer_t *sb, int start, int end, const char *fmt, va_list ap){    stringbuffer_t *tmp_sb;    char *str;    int total, len;    /* our first malloc is bogus. */    len = 1;    str = xmalloc(sizeof(char) * len);    total = vsnprintf(str, len, fmt, ap);    /* total is the real length needed. */    xfree(str);    len = total + 1;    str = xmalloc(sizeof(char) * len);    vsnprintf(str, len, fmt, ap);    /* now align if we want to align. */    if(start != 0 && end != 0) {        tmp_sb = stringbuffer_create();        stringbuffer_append(tmp_sb, str);        stringbuffer_align(tmp_sb, start, end);        stringbuffer_append(sb, stringbuffer_getstring(tmp_sb));        stringbuffer_destroy(tmp_sb);    } else {        stringbuffer_append(sb, str);    }    xfree(str);    return;}/* append printf. */void stringbuffer_aprintf(stringbuffer_t *sb, const char *fmt, ...){    va_list ap;    va_start(ap, fmt);    stringbuffer_avprintf(sb, fmt, ap);    va_end(ap);}/* append printf with alignment. */void stringbuffer_aprintf_align(stringbuffer_t *sb, int start, int end, const char *fmt, ...){    va_list ap;    va_start(ap, fmt);    stringbuffer_avprintf_align(sb, start, end, fmt, ap);    va_end(ap);}/* append vprintf. */void stringbuffer_avprintf(stringbuffer_t *sb, const char *fmt, va_list ap){    stringbuffer_avprintf_align(sb, 0, 0, fmt, ap);}/* newline marking and sweeping. this wrecks the string inside * the stringbuffer. *//* mark newlines to walk through.  * our sentinel is the null terminator. * two null terminations marks the end of the string. * we're guaranteed it is a unique sentinel since * we never accept null terminators from outside sources * and never build our own strings (obviously!) with * null terminators inside of them. */int stringbuffer_marknewlines(stringbuffer_t *sb){    char *c;    int newline_count = 0;    /* first append one null termination to the end     * to act as a proper terminator. */    stringbuffer_append_c(sb, 0);    c = sb->buf;    while(1) {        if(*c == '\n') {            newline_count++;            *c = 0;        }        c++;        if(*c == 0)            break;    }    return newline_count; /* return our line count. */}/* called _after_ newlines are marked. */const char *stringbuffer_getnextline(stringbuffer_t *sb, const char *cptr){    const char *ptr;    if(cptr == NULL) {        /* get first line. */        cptr = sb->buf;    } else {        for(ptr = cptr; *ptr != 0; ptr++);        if(*ptr == 0 && *(ptr + 1) == 0) {            return NULL;        } else {            cptr = ptr + 1;        }    }    return cptr;}int stringbuffer_getlen(stringbuffer_t *sb){    return sb->len;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -