| iMatix home page
| << | < | > | >>
SFL Logo SFL
Version 2.11

 

strreformat

#include "sflstr.h"
char *
strreformat (const char *source, size_t width, const char *prefix)

Synopsis

Reformats a string to fit within lines of the specified width. Prefixes each line with some optional text (included in the width). Allocates a fresh block of memory to contain the newly formatted line.

Source Code - (sflstr.c)

{
    size_t
        total_size,                     /*  Total size of buffer             */
        prefix_len,                     /*  Size of prefix string            */
        token_len;                      /*  Size of current token            */
    char
        **tokens,                       /*  String broken into words         */
        *token,                         /*  Current token                    */
        *buffer,                        /*  Target multiline buffer          */
        *bufptr;                        /*  Next position in buffer          */
    int
        cur_width,                      /*  Current line width incl. prefix  */
        token_nbr;                      /*  Token number, 0..n               */

    ASSERT (source);
    if (source == NULL)
        return NULL;

    /*  Ignore prefix if NULL                                                */
    if (prefix == NULL)
        prefix = "";

    /*  Calculate maximum size of resulting buffer, which is difficult to
     *  predict accurately.  We allow for 8 wasted characters on each line
     *  plus the line ending.
     */
    prefix_len = strlen (prefix);
    total_size = strlen (source) / (width - prefix_len) + 1;
    total_size = total_size * (width + 9);
    buffer = mem_alloc (total_size);
    tokens = tok split (source);

    ASSERT (strlen (prefix) < width);
    ASSERT (total_size > tok text size (tokens));

    cur_width = 0;
    bufptr = buffer;
    for (token_nbr = 0; tokens [token_nbr]; token_nbr++)
      {
        token = tokens [token_nbr];
        token_len = strlen (token);

        /*  First decide if next token will fit on line or not               */
        if (token_len + cur_width > width)
          {
            *bufptr++ = '\n';           /*  Start new line                   */
            cur_width = 0;
          }
        /*  Put prefix at at start of line if necessary                      */
        if (cur_width == 0)
          {
            /*  If prefix would overflow buffer, we quit                     */
            if ((bufptr - buffer) + prefix_len >= total_size)
                break;
            memcpy (bufptr, prefix, prefix_len);
            bufptr   += prefix_len;
            cur_width = prefix_len;
          }
        /*  If token would overflow buffer, we quit                          */
        if ((bufptr - buffer) + token_len + 1 >= total_size)
            break;

        /*  Now append token to line and add a space                         */
        memcpy (bufptr, token, token_len);
        bufptr    += token_len;
        cur_width += token_len + 1;
        *bufptr++ = ' ';
      }
    *bufptr = '\0';                     /*  Terminate the last line          */
    tok free (tokens);
    return (buffer);
}

| << | < | > | >> iMatix Copyright © 1996-2000 iMatix Corporation