-
Notifications
You must be signed in to change notification settings - Fork 1
/
longstr.c
137 lines (115 loc) · 2.43 KB
/
longstr.c
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* $Id$
*
* Long string handler
*
* Shigeya Suzuki, April 1993
* Copyright(c)1993 Shigeya Suzuki
*/
#include <config.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sysexits.h>
#include <sys/types.h>
#include <sys/param.h>
#include "logging.h"
#include <limits.h>
#ifndef NCARGS
#ifdef _POSIX_ARG_MAX
#define NCARGS _POSIX_ARG_MAX
#else
#ifdef ARG_MAX
#define NCARGS ARG_MAX
#endif
#endif
#endif
#include "longstr.h"
/* These must be defined in main program
*/
extern char * xmalloc();
extern char * xrealloc();
void
ls_init(p)
struct longstr *p;
{
p->ls_buf = p->ls_ptr = NULL;
p->ls_size = p->ls_used = 0;
p->ls_allocsize = LONGSTR_CHUNK;
ls_reset(p);
}
/* Reset command line buffer
* We do not re-allocate buffer on reset
*/
void
ls_reset(p)
struct longstr *p;
{
if (p->ls_buf == NULL) {
p->ls_buf = xmalloc(p->ls_allocsize);
p->ls_size = p->ls_allocsize;
}
p->ls_used = 0;
p->ls_ptr = p->ls_buf;
}
/* Grow command line buffer
*/
void
ls_grow(p, size)
struct longstr *p;
size_t size;
{
/* Rounds, but allocate at least one block */
size_t diff = size - (p->ls_size - p->ls_used);
int chunk = diff < p->ls_allocsize ? p->ls_allocsize
: ((diff / p->ls_allocsize)+1) * p->ls_allocsize;
if ( (p->ls_size + chunk) >= NCARGS) { /* exceeds limit */
logandexit(EX_UNAVAILABLE, "limit %d exceeded (%d)",
NCARGS, p->ls_size + chunk);
}
#ifdef DEBUG
fprintf(stderr, "ls_grow(%d/0x%x:0x%x[%d]): %d -> %d (diff=%d, chunk=%d)\n",
size,
p->ls_buf, p->ls_ptr, p->ls_ptr - p->ls_buf,
p->ls_size, p->ls_size+chunk,
diff, chunk);
#endif
p->ls_buf = xrealloc(p->ls_buf, p->ls_size+chunk);
p->ls_ptr = p->ls_buf + p->ls_used;
p->ls_size += chunk;
}
/* ls_append -- add memory block at end
* string will be null-terminated, thus at least one byte longer.
*/
void
ls_append(p, str, len)
struct longstr *p;
char *str;
size_t len;
{
if (p->ls_size == 0 || (p->ls_size - p->ls_used) < len) {
ls_grow(p, len+1);
}
memcpy(p->ls_ptr, str, len);
p->ls_ptr += len;
p->ls_used += len;
*(p->ls_ptr) = 0;
}
/* ls_appendstr -- add string at end
*/
void
ls_appendstr(p, str)
struct longstr *p;
char *str;
{
ls_append(p, str, strlen(str));
}
/* ls_appendchar -- add a char at end
*/
void
ls_appendchar(p, ch)
struct longstr *p;
int ch;
{
char buf = ch;
ls_append(p, &buf, 1);
}