1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/* str.c -- es string operations ($Revision: 1.1.1.1 $) */
#include "es.h"
#include "gc.h"
#include "print.h"
/* grow -- buffer grow function for str() */
static void str_grow(Format *f, size_t more) {
Buffer *buf = expandbuffer(f->u.p, more);
f->u.p = buf;
f->buf = buf->str + (f->buf - f->bufbegin);
f->bufbegin = buf->str;
f->bufend = buf->str + buf->len;
}
/* strv -- print a formatted string into gc space */
extern char *strv(const char *fmt, va_list args) {
Buffer *buf;
Format format;
gcdisable();
buf = openbuffer(0);
format.u.p = buf;
#if NO_VA_LIST_ASSIGN
memcpy(format.args, args, sizeof(va_list));
#else
format.args = args;
#endif
format.buf = buf->str;
format.bufbegin = buf->str;
format.bufend = buf->str + buf->len;
format.grow = str_grow;
format.flushed = 0;
printfmt(&format, fmt);
fmtputc(&format, '\0');
gcenable();
return sealbuffer(format.u.p);
}
/* str -- create a string (in garbage collection space) by printing to it */
extern char *str VARARGS1(const char *, fmt) {
char *s;
va_list args;
VA_START(args, fmt);
s = strv(fmt, args);
va_end(args);
return s;
}
#define PRINT_ALLOCSIZE 64
/* mprint_grow -- buffer grow function for mprint() */
static void mprint_grow(Format *format, size_t more) {
char *buf;
size_t len = format->bufend - format->bufbegin + 1;
len = (len >= more)
? len * 2
: ((len + more) + PRINT_ALLOCSIZE) &~ (PRINT_ALLOCSIZE - 1);
buf = erealloc(format->bufbegin, len);
format->buf = buf + (format->buf - format->bufbegin);
format->bufbegin = buf;
format->bufend = buf + len - 1;
}
/* mprint -- create a string in ealloc space by printing to it */
extern char *mprint VARARGS1(const char *, fmt) {
Format format;
format.u.n = 1;
VA_START(format.args, fmt);
format.buf = ealloc(PRINT_ALLOCSIZE);
format.bufbegin = format.buf;
format.bufend = format.buf + PRINT_ALLOCSIZE - 1;
format.grow = mprint_grow;
format.flushed = 0;
printfmt(&format, fmt);
*format.buf = '\0';
va_end(format.args);
return format.bufbegin;
}
/*
* StrList -- lists of strings
* to even include these is probably a premature optimization
*/
DefineTag(StrList, static);
extern StrList *mkstrlist(char *str, StrList *next) {
gcdisable();
assert(str != NULL);
Ref(StrList *, list, gcnew(StrList));
list->str = str;
list->next = next;
gcenable();
RefReturn(list);
}
static void *StrListCopy(void *op) {
void *np = gcnew(StrList);
memcpy(np, op, sizeof (StrList));
return np;
}
static size_t StrListScan(void *p) {
StrList *list = p;
list->str = forward(list->str);
list->next = forward(list->next);
return sizeof (StrList);
}
|