Back to index

lightning-sunbird  0.9+nobinonly
Defines | Typedefs | Functions | Variables
cord.h File Reference
#include <stddef.h>
#include <stdio.h>
#include "private/cord_pos.h"
#include <stdarg.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define CORD_EMPTY   0
#define CORD_IS_STRING(s)   (*(s) != '\0')
#define CORD_NO_FN   ((CORD_batched_iter_fn)0)
#define CORD_iter(x, f1, cd)   CORD_iter5(x, 0, f1, CORD_NO_FN, cd)
#define CORD_FOR(pos, cord)   for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))
#define CORD_nul(i)   CORD_chars('\0', (i))
#define CORD_NOT_FOUND   ((size_t)(-1))

Typedefs

typedef const char * CORD
typedef char(* CORD_fn )(size_t i, void *client_data)
typedef int(* CORD_iter_fn )(char c, void *client_data)
typedef int(* CORD_batched_iter_fn )(const char *s, void *client_data)

Functions

CORD CORD_cat (CORD x, CORD y)
CORD CORD_cat_char_star (CORD x, const char *y, size_t leny)
size_t CORD_len (CORD x)
CORD CORD_from_fn (CORD_fn fn, void *client_data, size_t len)
CORD CORD_substr (CORD x, size_t i, size_t n)
CORD CORD_balance (CORD x)
int CORD_iter5 (CORD x, size_t i, CORD_iter_fn f1, CORD_batched_iter_fn f2, void *client_data)
int CORD_iter (CORD x, CORD_iter_fn f1, void *client_data)
int CORD_riter4 (CORD x, size_t i, CORD_iter_fn f1, void *client_data)
int CORD_riter (CORD x, CORD_iter_fn f1, void *client_data)
void CORD_dump (CORD x)
CORD CORD_cat_char (CORD x, char c)
CORD CORD_catn (int n,...)
char CORD_fetch (CORD x, size_t i)
int CORD_cmp (CORD x, CORD y)
int CORD_ncmp (CORD x, size_t x_start, CORD y, size_t y_start, size_t len)
size_t CORD_str (CORD x, size_t start, CORD s)
CORD CORD_chars (char c, size_t i)
CORD CORD_from_file (FILE *f)
CORD CORD_from_file_eager (FILE *f)
CORD CORD_from_file_lazy (FILE *f)
char * CORD_to_char_star (CORD x)
CORD CORD_from_char_star (const char *s)
const char * CORD_to_const_char_star (CORD x)
int CORD_put (CORD x, FILE *f)
size_t CORD_chr (CORD x, size_t i, int c)
size_t CORD_rchr (CORD x, size_t i, int c)
int CORD_sprintf (CORD *out, CORD format,...)
int CORD_vsprintf (CORD *out, CORD format, va_list args)
int CORD_fprintf (FILE *f, CORD format,...)
int CORD_vfprintf (FILE *f, CORD format, va_list args)
int CORD_printf (CORD format,...)
int CORD_vprintf (CORD format, va_list args)

Variables

void(* CORD_oom_fn )(void)

Define Documentation

#define CORD_EMPTY   0

Definition at line 72 of file cord.h.

#define CORD_FOR (   pos,
  cord 
)    for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))

Definition at line 190 of file cord.h.

#define CORD_IS_STRING (   s)    (*(s) != '\0')

Definition at line 75 of file cord.h.

#define CORD_iter (   x,
  f1,
  cd 
)    CORD_iter5(x, 0, f1, CORD_NO_FN, cd)

Definition at line 138 of file cord.h.

Definition at line 123 of file cord.h.

#define CORD_NOT_FOUND   ((size_t)(-1))

Definition at line 277 of file cord.h.

#define CORD_nul (   i)    CORD_chars('\0', (i))

Definition at line 230 of file cord.h.


Typedef Documentation

typedef const char* CORD

Definition at line 69 of file cord.h.

typedef int(* CORD_batched_iter_fn)(const char *s, void *client_data)

Definition at line 122 of file cord.h.

typedef char(* CORD_fn)(size_t i, void *client_data)

Definition at line 92 of file cord.h.

typedef int(* CORD_iter_fn)(char c, void *client_data)

Definition at line 118 of file cord.h.


Function Documentation

Definition at line 704 of file cordbscs.c.

{
    Forest forest;
    register size_t len;
    
    if (x == 0) return(0);
    if (CORD_IS_STRING(x)) return(x);
    if (!min_len_init) CORD_init_min_len();
    len = LEN(x);
    CORD_init_forest(forest, len);
    CORD_balance_insert(x, len, forest);
    return(CORD_concat_forest(forest, len));
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_cat ( CORD  x,
CORD  y 
)

Definition at line 231 of file cordbscs.c.

{
    register size_t result_len;
    register int depth;
    register size_t lenx;
    
    if (x == CORD_EMPTY) return(y);
    if (y == CORD_EMPTY) return(x);
    if (CORD_IS_STRING(y)) {
        return(CORD_cat_char_star(x, y, strlen(y)));
    } else if (CORD_IS_STRING(x)) {
        lenx = strlen(x);
        depth = DEPTH(y) + 1;
    } else {
        register int depthy = DEPTH(y);
        
        lenx = LEN(x);
        depth = DEPTH(x) + 1;
        if (depthy >= depth) depth = depthy + 1;
    }
    result_len = lenx + LEN(y);
    {
       register struct Concatenation * result;
       
       result = GC_NEW(struct Concatenation);
       if (result == 0) OUT_OF_MEMORY;
       result->header = CONCAT_HDR;
       result->depth = depth;
       if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
       result->len = result_len;
       result->left = x;
       result->right = y;
       return((CORD) result);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_cat_char ( CORD  x,
char  c 
)

Definition at line 58 of file cordxtra.c.

{
    register char * string;
    
    if (c == '\0') return(CORD_cat(x, CORD_nul(1)));
    string = GC_MALLOC_ATOMIC(2);
    if (string == 0) OUT_OF_MEMORY;
    string[0] = c;
    string[1] = '\0';
    return(CORD_cat_char_star(x, string, 1));
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_cat_char_star ( CORD  x,
const char *  y,
size_t  leny 
)

Definition at line 147 of file cordbscs.c.

{
    register size_t result_len;
    register size_t lenx;
    register int depth;
    
    if (x == CORD_EMPTY) return(y);
    if (leny == 0) return(x);
    if (CORD_IS_STRING(x)) {
        lenx = strlen(x);
        result_len = lenx + leny;
        if (result_len <= SHORT_LIMIT) {
            register char * result = GC_MALLOC_ATOMIC(result_len+1);
        
            if (result == 0) OUT_OF_MEMORY;
            memcpy(result, x, lenx);
            memcpy(result + lenx, y, leny);
            result[result_len] = '\0';
            return((CORD) result);
        } else {
            depth = 1;
        }
    } else {
       register CORD right;
       register CORD left;
       register char * new_right;
       register size_t right_len;
       
       lenx = LEN(x);
       
        if (leny <= SHORT_LIMIT/2
           && IS_CONCATENATION(x)
            && CORD_IS_STRING(right = ((CordRep *)x) -> concatenation.right)) {
            /* Merge y into right part of x. */
            if (!CORD_IS_STRING(left = ((CordRep *)x) -> concatenation.left)) {
              right_len = lenx - LEN(left);
            } else if (((CordRep *)x) -> concatenation.left_len != 0) {
                right_len = lenx - ((CordRep *)x) -> concatenation.left_len;
            } else {
              right_len = strlen(right);
            }
            result_len = right_len + leny;  /* length of new_right */
            if (result_len <= SHORT_LIMIT) {
              new_right = GC_MALLOC_ATOMIC(result_len + 1);
              memcpy(new_right, right, right_len);
              memcpy(new_right + right_len, y, leny);
              new_right[result_len] = '\0';
              y = new_right;
              leny = result_len;
              x = left;
              lenx -= right_len;
              /* Now fall through to concatenate the two pieces: */
            }
            if (CORD_IS_STRING(x)) {
                depth = 1;
            } else {
                depth = DEPTH(x) + 1;
            }
        } else {
            depth = DEPTH(x) + 1;
        }
        result_len = lenx + leny;
    }
    {
      /* The general case; lenx, result_len is known: */
       register struct Concatenation * result;
       
       result = GC_NEW(struct Concatenation);
       if (result == 0) OUT_OF_MEMORY;
       result->header = CONCAT_HDR;
       result->depth = depth;
       if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
       result->len = result_len;
       result->left = x;
       result->right = y;
       if (depth > MAX_DEPTH) {
           return(CORD_balance((CORD)result));
       } else {
           return((CORD) result);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_catn ( int  n,
  ... 
)

Definition at line 70 of file cordxtra.c.

{
    register CORD result = CORD_EMPTY;
    va_list args;
    register int i;

    va_start(args, nargs);
    for (i = 0; i < nargs; i++) {
        register CORD next = va_arg(args, CORD);
        result = CORD_cat(result, next);
    }
    va_end(args);
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_chars ( char  c,
size_t  i 
)

Definition at line 436 of file cordxtra.c.

{
    return(CORD_from_fn(CORD_nul_func, (void *)(unsigned long)c, i));
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t CORD_chr ( CORD  x,
size_t  i,
int  c 
)

Definition at line 325 of file cordxtra.c.

{
    chr_data d;
    
    d.pos = i;
    d.target = c;
    if (CORD_iter5(x, i, CORD_chr_proc, CORD_batched_chr_proc, &d)) {
        return(d.pos);
    } else {
       return(CORD_NOT_FOUND);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_cmp ( CORD  x,
CORD  y 
)

Definition at line 136 of file cordxtra.c.

{
    CORD_pos xpos;
    CORD_pos ypos;
    register size_t avail, yavail;
    
    if (y == CORD_EMPTY) return(x != CORD_EMPTY);
    if (x == CORD_EMPTY) return(-1);
    if (CORD_IS_STRING(y) && CORD_IS_STRING(x)) return(strcmp(x,y));
    CORD_set_pos(xpos, x, 0);
    CORD_set_pos(ypos, y, 0);
    for(;;) {
        if (!CORD_pos_valid(xpos)) {
            if (CORD_pos_valid(ypos)) {
              return(-1);
            } else {
                return(0);
            }
        }
        if (!CORD_pos_valid(ypos)) {
            return(1);
        }
        if ((avail = CORD_pos_chars_left(xpos)) <= 0
            || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
            register char xcurrent = CORD_pos_fetch(xpos);
            register char ycurrent = CORD_pos_fetch(ypos);
            if (xcurrent != ycurrent) return(xcurrent - ycurrent);
            CORD_next(xpos);
            CORD_next(ypos);
        } else {
            /* process as many characters as we can     */
            register int result;
            
            if (avail > yavail) avail = yavail;
            result = strncmp(CORD_pos_cur_char_addr(xpos),
                          CORD_pos_cur_char_addr(ypos), avail);
            if (result != 0) return(result);
            CORD_pos_advance(xpos, avail);
            CORD_pos_advance(ypos, avail);
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 141 of file cordbscs.c.

{
    CORD_dump_inner(x, 0);
    fflush(stdout);
}

Here is the call graph for this function:

char CORD_fetch ( CORD  x,
size_t  i 
)

Definition at line 254 of file cordxtra.c.

{
    CORD_pos xpos;
    
    CORD_set_pos(xpos, x, i);
    if (!CORD_pos_valid(xpos)) ABORT("bad index?");
    return(CORD_pos_fetch(xpos));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_fprintf ( FILE f,
CORD  format,
  ... 
)

Definition at line 346 of file cordprnt.c.

{
    va_list args;
    int result;
    CORD out;
    
    va_start(args, format);
    result = CORD_vsprintf(&out, format, args);
    va_end(args);
    if (result > 0) CORD_put(out, f);
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 235 of file cordxtra.c.

{
    char * result;
    size_t len = strlen(s);

    if (0 == len) return(CORD_EMPTY);
    result = GC_MALLOC_ATOMIC(len + 1);
    if (result == 0) OUT_OF_MEMORY;
    memcpy(result, s, len+1);
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 605 of file cordxtra.c.

{
    register long len;
    
    if (fseek(f, 0l, SEEK_END) != 0) {
        ABORT("Bad fd argument - fseek failed");
    }
    if ((len = ftell(f)) < 0) {
        ABORT("Bad fd argument - ftell failed");
    }
    rewind(f);
    if (len < LAZY_THRESHOLD) {
        return(CORD_from_file_eager(f));
    } else {
        return(CORD_from_file_lazy_inner(f, (size_t)len));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 441 of file cordxtra.c.

{
    register int c;
    CORD_ec ecord;
    
    CORD_ec_init(ecord);
    for(;;) {
        c = getc(f);
        if (c == 0) {
          /* Append the right number of NULs     */
          /* Note that any string of NULs is rpresented in 4 words,   */
          /* independent of its length.                               */
            register size_t count = 1;
            
            CORD_ec_flush_buf(ecord);
            while ((c = getc(f)) == 0) count++;
            ecord[0].ec_cord = CORD_cat(ecord[0].ec_cord, CORD_nul(count));
        }
        if (c == EOF) break;
        CORD_ec_append(ecord, c);
    }
    (void) fclose(f);
    return(CORD_balance(CORD_ec_to_cord(ecord)));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 589 of file cordxtra.c.

{
    register long len;
    
    if (fseek(f, 0l, SEEK_END) != 0) {
        ABORT("Bad fd argument - fseek failed");
    }
    if ((len = ftell(f)) < 0) {
        ABORT("Bad fd argument - ftell failed");
    }
    rewind(f);
    return(CORD_from_file_lazy_inner(f, (size_t)len));
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_from_fn ( CORD_fn  fn,
void client_data,
size_t  len 
)

Definition at line 269 of file cordbscs.c.

{
    if (len <= 0) return(0);
    if (len <= SHORT_LIMIT) {
        register char * result;
        register size_t i;
        char buf[SHORT_LIMIT+1];
        register char c;
        
        for (i = 0; i < len; i++) {
            c = (*fn)(i, client_data);
            if (c == '\0') goto gen_case;
            buf[i] = c;
        }
        buf[i] = '\0';
        result = GC_MALLOC_ATOMIC(len+1);
        if (result == 0) OUT_OF_MEMORY;
        strcpy(result, buf);
        result[len] = '\0';
        return((CORD) result);
    }
  gen_case:
    {
       register struct Function * result;
       
       result = GC_NEW(struct Function);
       if (result == 0) OUT_OF_MEMORY;
       result->header = FN_HDR;
       /* depth is already 0 */
       result->len = len;
       result->fn = fn;
       result->client_data = client_data;
       return((CORD) result);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_iter ( CORD  x,
CORD_iter_fn  f1,
void client_data 
)

Definition at line 508 of file cordbscs.c.

{
    return(CORD_iter5(x, 0, f1, CORD_NO_FN, client_data));
}

Here is the call graph for this function:

int CORD_iter5 ( CORD  x,
size_t  i,
CORD_iter_fn  f1,
CORD_batched_iter_fn  f2,
void client_data 
)

Definition at line 459 of file cordbscs.c.

{
    if (x == 0) return(0);
    if (CORD_IS_STRING(x)) {
       register const char *p = x+i;
       
       if (*p == '\0') ABORT("2nd arg to CORD_iter5 too big");
        if (f2 != CORD_NO_FN) {
            return((*f2)(p, client_data));
        } else {
           while (*p) {
                if ((*f1)(*p, client_data)) return(1);
                p++;
           }
           return(0);
        }
    } else if (IS_CONCATENATION(x)) {
       register struct Concatenation * conc
                     = &(((CordRep *)x) -> concatenation);
       
       
       if (i > 0) {
           register size_t left_len = LEFT_LEN(conc);
           
           if (i >= left_len) {
               return(CORD_iter5(conc -> right, i - left_len, f1, f2,
                              client_data));
           }
       }
       if (CORD_iter5(conc -> left, i, f1, f2, client_data)) {
           return(1);
       }
       return(CORD_iter5(conc -> right, 0, f1, f2, client_data));
    } else /* function */ {
        register struct Function * f = &(((CordRep *)x) -> function);
        register size_t j;
        register size_t lim = f -> len;
        
        for (j = i; j < lim; j++) {
            if ((*f1)((*(f -> fn))(j, f -> client_data), client_data)) {
                return(1);
            }
        }
        return(0);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t CORD_len ( CORD  x)

Definition at line 305 of file cordbscs.c.

{
    if (x == 0) {
       return(0);
    } else {
       return(GEN_LEN(x));
    }
}

Here is the caller graph for this function:

int CORD_ncmp ( CORD  x,
size_t  x_start,
CORD  y,
size_t  y_start,
size_t  len 
)

Definition at line 179 of file cordxtra.c.

{
    CORD_pos xpos;
    CORD_pos ypos;
    register size_t count;
    register long avail, yavail;
    
    CORD_set_pos(xpos, x, x_start);
    CORD_set_pos(ypos, y, y_start);
    for(count = 0; count < len;) {
        if (!CORD_pos_valid(xpos)) {
            if (CORD_pos_valid(ypos)) {
              return(-1);
            } else {
                return(0);
            }
        }
        if (!CORD_pos_valid(ypos)) {
            return(1);
        }
        if ((avail = CORD_pos_chars_left(xpos)) <= 0
            || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
            register char xcurrent = CORD_pos_fetch(xpos);
            register char ycurrent = CORD_pos_fetch(ypos);
            if (xcurrent != ycurrent) return(xcurrent - ycurrent);
            CORD_next(xpos);
            CORD_next(ypos);
            count++;
        } else {
            /* process as many characters as we can     */
            register int result;
            
            if (avail > yavail) avail = yavail;
            count += avail;
            if (count > len) avail -= (count - len);
            result = strncmp(CORD_pos_cur_char_addr(xpos),
                          CORD_pos_cur_char_addr(ypos), (size_t)avail);
            if (result != 0) return(result);
            CORD_pos_advance(xpos, (size_t)avail);
            CORD_pos_advance(ypos, (size_t)avail);
        }
    }
    return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_printf ( CORD  format,
  ... 
)

Definition at line 369 of file cordprnt.c.

{
    va_list args;
    int result;
    CORD out;
    
    va_start(args, format);
    result = CORD_vsprintf(&out, format, args);
    va_end(args);
    if (result > 0) CORD_put(out, stdout);
    return(result);
}

Here is the call graph for this function:

int CORD_put ( CORD  x,
FILE f 
)

Definition at line 279 of file cordxtra.c.

{
    if (CORD_iter5(x, 0, CORD_put_proc, CORD_batched_put_proc, f)) {
        return(EOF);
    } else {
       return(1);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t CORD_rchr ( CORD  x,
size_t  i,
int  c 
)

Definition at line 338 of file cordxtra.c.

{
    chr_data d;
    
    d.pos = i;
    d.target = c;
    if (CORD_riter4(x, i, CORD_rchr_proc, &d)) {
        return(d.pos);
    } else {
       return(CORD_NOT_FOUND);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_riter ( CORD  x,
CORD_iter_fn  f1,
void client_data 
)

Definition at line 556 of file cordbscs.c.

{
    return(CORD_riter4(x, CORD_len(x) - 1, f1, client_data));
}

Here is the call graph for this function:

int CORD_riter4 ( CORD  x,
size_t  i,
CORD_iter_fn  f1,
void client_data 
)

Definition at line 513 of file cordbscs.c.

{
    if (x == 0) return(0);
    if (CORD_IS_STRING(x)) {
       register const char *p = x + i;
       register char c;
               
       for(;;) {
           c = *p;
           if (c == '\0') ABORT("2nd arg to CORD_riter4 too big");
            if ((*f1)(c, client_data)) return(1);
           if (p == x) break;
            p--;
       }
       return(0);
    } else if (IS_CONCATENATION(x)) {
       register struct Concatenation * conc
                     = &(((CordRep *)x) -> concatenation);
       register CORD left_part = conc -> left;
       register size_t left_len;
       
       left_len = LEFT_LEN(conc);
       if (i >= left_len) {
           if (CORD_riter4(conc -> right, i - left_len, f1, client_data)) {
              return(1);
           }
           return(CORD_riter4(left_part, left_len - 1, f1, client_data));
       } else {
           return(CORD_riter4(left_part, i, f1, client_data));
       }
    } else /* function */ {
        register struct Function * f = &(((CordRep *)x) -> function);
        register size_t j;
        
        for (j = i; ; j--) {
            if ((*f1)((*(f -> fn))(j, f -> client_data), client_data)) {
                return(1);
            }
            if (j == 0) return(0);
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_sprintf ( CORD out,
CORD  format,
  ... 
)

Definition at line 335 of file cordprnt.c.

{
    va_list args;
    int result;
    
    va_start(args, format);
    result = CORD_vsprintf(out, format, args);
    va_end(args);
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t CORD_str ( CORD  x,
size_t  start,
CORD  s 
)

Definition at line 357 of file cordxtra.c.

{
    CORD_pos xpos;
    size_t xlen = CORD_len(x);
    size_t slen;
    register size_t start_len;
    const char * s_start;
    unsigned long s_buf = 0;       /* The first few characters of s   */
    unsigned long x_buf = 0;       /* Start of candidate substring.   */
                            /* Initialized only to make compilers     */
                            /* happy.                          */
    unsigned long mask = 0;
    register size_t i;
    register size_t match_pos;
    
    if (s == CORD_EMPTY) return(start);
    if (CORD_IS_STRING(s)) {
        s_start = s;
        slen = strlen(s);
    } else {
        s_start = CORD_to_char_star(CORD_substr(s, 0, sizeof(unsigned long)));
        slen = CORD_len(s);
    }
    if (xlen < start || xlen - start < slen) return(CORD_NOT_FOUND);
    start_len = slen;
    if (start_len > sizeof(unsigned long)) start_len = sizeof(unsigned long);
    CORD_set_pos(xpos, x, start);
    for (i = 0; i < start_len; i++) {
        mask <<= 8;
        mask |= 0xff;
        s_buf <<= 8;
        s_buf |= s_start[i];
        x_buf <<= 8;
        x_buf |= CORD_pos_fetch(xpos);
        CORD_next(xpos);
    }
    for (match_pos = start; ; match_pos++) {
       if ((x_buf & mask) == s_buf) {
           if (slen == start_len ||
              CORD_ncmp(x, match_pos + start_len,
                       s, start_len, slen - start_len) == 0) {
               return(match_pos);
           }
       }
       if ( match_pos == xlen - slen ) {
           return(CORD_NOT_FOUND);
       }
       x_buf <<= 8;
        x_buf |= CORD_pos_fetch(xpos);
        CORD_next(xpos);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

CORD CORD_substr ( CORD  x,
size_t  i,
size_t  n 
)

Definition at line 442 of file cordbscs.c.

{
    register size_t len = CORD_len(x);
    
    if (i >= len || n <= 0) return(0);
       /* n < 0 is impossible in a correct C implementation, but      */
       /* quite possible  under SunOS 4.X.                            */
    if (i + n > len) n = len - i;
#   ifndef __STDC__
      if (i < 0) ABORT("CORD_substr: second arg. negative");
       /* Possible only if both client and C implementation are buggy.       */
       /* But empirically this happens frequently.                    */
#   endif
    return(CORD_substr_checked(x, i, n));
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* CORD_to_char_star ( CORD  x)

Definition at line 224 of file cordxtra.c.

{
    register size_t len = CORD_len(x);
    char * result = GC_MALLOC_ATOMIC(len + 1);
    
    if (result == 0) OUT_OF_MEMORY;
    CORD_fill_buf(x, 0, len, result);
    result[len] = '\0';
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 247 of file cordxtra.c.

{
    if (x == 0) return("");
    if (CORD_IS_STRING(x)) return((const char *)x);
    return(CORD_to_char_star(x));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CORD_vfprintf ( FILE f,
CORD  format,
va_list  args 
)

Definition at line 359 of file cordprnt.c.

{
    int result;
    CORD out;
    
    result = CORD_vsprintf(&out, format, args);
    if (result > 0) CORD_put(out, f);
    return(result);
}

Here is the call graph for this function:

int CORD_vprintf ( CORD  format,
va_list  args 
)

Definition at line 382 of file cordprnt.c.

{
    int result;
    CORD out;
    
    result = CORD_vsprintf(&out, format, args);
    if (result > 0) CORD_put(out, stdout);
    return(result);
}

Here is the call graph for this function:

int CORD_vsprintf ( CORD out,
CORD  format,
va_list  args 
)

Definition at line 161 of file cordprnt.c.

{
    CORD_ec result;
    register int count;
    register char current;
    CORD_pos pos;
    char conv_spec[CONV_SPEC_LEN + 1];
    
    CORD_ec_init(result);
    for (CORD_set_pos(pos, format, 0); CORD_pos_valid(pos); CORD_next(pos)) {
              current = CORD_pos_fetch(pos);
              if (current == '%') {
            CORD_next(pos);
            if (!CORD_pos_valid(pos)) return(-1);
            current = CORD_pos_fetch(pos);
            if (current == '%') {
                     CORD_ec_append(result, current);
            } else {
              int width, prec;
              int left_adj = 0;
              int long_arg = 0;
              CORD arg;
              size_t len;
               
                     if (extract_conv_spec(pos, conv_spec,
                                         &width, &prec,
                                         &left_adj, &long_arg) < 0) {
                         return(-1);
                     }
                     current = CORD_pos_fetch(pos);
              switch(current) {
                  case 'n':
                     /* Assign length to next arg */
                     if (long_arg == 0) {
                         int * pos_ptr;
                         pos_ptr = va_arg(args, int *);
                         *pos_ptr = ec_len(result);
                     } else if (long_arg > 0) {
                         long * pos_ptr;
                         pos_ptr = va_arg(args, long *);
                         *pos_ptr = ec_len(result);
                     } else {
                         short * pos_ptr;
                         pos_ptr = va_arg(args, short *);
                         *pos_ptr = ec_len(result);
                     }
                     goto done;
                  case 'r':
                     /* Append cord and any padding     */
                     if (width == VARIABLE) width = va_arg(args, int);
                     if (prec == VARIABLE) prec = va_arg(args, int);
                     arg = va_arg(args, CORD);
                     len = CORD_len(arg);
                     if (prec != NONE && len > prec) {
                       if (prec < 0) return(-1);
                       arg = CORD_substr(arg, 0, prec);
                       len = prec;
                     }
                     if (width != NONE && len < width) {
                       char * blanks = GC_MALLOC_ATOMIC(width-len+1);

                       memset(blanks, ' ', width-len);
                       blanks[width-len] = '\0';
                       if (left_adj) {
                         arg = CORD_cat(arg, blanks);
                       } else {
                         arg = CORD_cat(blanks, arg);
                       }
                     }
                     CORD_ec_append_cord(result, arg);
                     goto done;
                  case 'c':
                     if (width == NONE && prec == NONE) {
                         register char c;

                         c = va_arg(args, char);
                         CORD_ec_append(result, c);
                         goto done;
                     }
                     break;
                  case 's':
                      if (width == NONE && prec == NONE) {
                         char * str = va_arg(args, char *);
                         register char c;

                         while (c = *str++) {
                             CORD_ec_append(result, c);
                         }
                         goto done;
                     }
                     break;
                  default:
                      break;
              }
              /* Use standard sprintf to perform conversion */
              {
                  register char * buf;
                  va_list vsprintf_args = args;
                     /* The above does not appear to be sanctioned    */
                     /* by the ANSI C standard.                */
                  int max_size = 0;
                  int res;
                     
                  if (width == VARIABLE) width = va_arg(args, int);
                  if (prec == VARIABLE) prec = va_arg(args, int);
                  if (width != NONE) max_size = width;
                  if (prec != NONE && prec > max_size) max_size = prec;
                  max_size += CONV_RESULT_LEN;
                  if (max_size >= CORD_BUFSZ) {
                      buf = GC_MALLOC_ATOMIC(max_size + 1);
                  } else {
                      if (CORD_BUFSZ - (result[0].ec_bufptr-result[0].ec_buf)
                          < max_size) {
                          CORD_ec_flush_buf(result);
                      }
                      buf = result[0].ec_bufptr;
                  }
                  switch(current) {
                      case 'd':
                      case 'i':
                      case 'o':
                      case 'u':
                      case 'x':
                      case 'X':
                      case 'c':
                          if (long_arg <= 0) {
                            (void) va_arg(args, int);
                          } else if (long_arg > 0) {
                            (void) va_arg(args, long);
                          }
                          break;
                      case 's':
                      case 'p':
                          (void) va_arg(args, char *);
                          break;
                      case 'f':
                      case 'e':
                      case 'E':
                      case 'g':
                      case 'G':
                          (void) va_arg(args, double);
                          break;
                      default:
                          return(-1);
                  }
                  res = vsprintf(buf, conv_spec, vsprintf_args);
                  len = (size_t)res;
                  if ((char *)(GC_word)res == buf) {
                     /* old style vsprintf */
                     len = strlen(buf);
                  } else if (res < 0) {
                      return(-1);
                  }
                  if (buf != result[0].ec_bufptr) {
                      register char c;

                     while (c = *buf++) {
                         CORD_ec_append(result, c);
                      }
                  } else {
                      result[0].ec_bufptr = buf + len;
                  }
              }
              done:;
            }
        } else {
            CORD_ec_append(result, current);
        }
    }
    count = ec_len(result);
    *out = CORD_balance(CORD_ec_to_cord(result));
    return(count);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 32 of file cordbscs.c.