7 /* string array utilities
11 /* ARGV *argv_alloc(len)
14 /* ARGV *argv_free(argvp)
17 /* void argv_add(argvp, arg, ..., ARGV_END)
21 /* void argv_addn(argvp, arg, arg_len, ..., ARGV_END)
26 /* void argv_terminate(argvp);
29 /* void argv_truncate(argvp, len);
33 /* The functions in this module manipulate arrays of string
34 /* pointers. An ARGV structure contains the following members:
36 /* The length of the \fIargv\fR array member.
38 /* The number of \fIargv\fR elements used.
40 /* An array of pointers to null-terminated strings.
42 /* argv_alloc() returns an empty string array of the requested
43 /* length. The result is ready for use by argv_add(). The array
44 /* is null terminated.
46 /* argv_add() copies zero or more strings and adds them to the
47 /* specified string array. The array is null terminated.
48 /* Terminate the argument list with a null pointer. The manifest
49 /* constant ARGV_END provides a convenient notation for this.
51 /* argv_addn() is like argv_add(), but each string is followed
52 /* by a string length argument.
54 /* argv_free() releases storage for a string array, and conveniently
55 /* returns a null pointer.
57 /* argv_terminate() null-terminates its string array argument.
59 /* argv_truncate() trucates its argument to the specified
60 /* number of entries, but does not reallocate memory. The
61 /* result is null-terminated.
63 /* msg(3) diagnostics interface
65 /* Fatal errors: memory allocation problem.
69 /* The Secure Mailer license must be distributed with this software.
72 /* IBM T.J. Watson Research
74 /* Yorktown Heights, NY 10598, USA
77 /* System libraries. */
80 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
84 /* Application-specific. */
90 /* argv_free - destroy string array */
92 ARGV
*argv_free(ARGV
*argvp
)
96 for (cpp
= argvp
->argv
; cpp
< argvp
->argv
+ argvp
->argc
; cpp
++)
98 myfree((char *) argvp
->argv
);
99 myfree((char *) argvp
);
103 /* argv_alloc - initialize string array */
105 ARGV
*argv_alloc(ssize_t len
)
111 * Make sure that always argvp->argc < argvp->len.
113 argvp
= (ARGV
*) mymalloc(sizeof(*argvp
));
115 sane_len
= (len
< 2 ? 2 : len
);
116 argvp
->argv
= (char **) mymalloc((sane_len
+ 1) * sizeof(char *));
117 argvp
->len
= sane_len
;
123 /* argv_extend - extend array */
125 static void argv_extend(ARGV
*argvp
)
129 new_len
= argvp
->len
* 2;
130 argvp
->argv
= (char **)
131 myrealloc((char *) argvp
->argv
, (new_len
+ 1) * sizeof(char *));
132 argvp
->len
= new_len
;
135 /* argv_add - add string to vector */
137 void argv_add(ARGV
*argvp
,...)
143 * Make sure that always argvp->argc < argvp->len.
145 #define ARGV_SPACE_LEFT(a) ((a)->len - (a)->argc - 1)
148 while ((arg
= va_arg(ap
, char *)) != 0) {
149 if (ARGV_SPACE_LEFT(argvp
) <= 0)
151 argvp
->argv
[argvp
->argc
++] = mystrdup(arg
);
154 argvp
->argv
[argvp
->argc
] = 0;
157 /* argv_addn - add string to vector */
159 void argv_addn(ARGV
*argvp
,...)
166 * Make sure that always argvp->argc < argvp->len.
169 while ((arg
= va_arg(ap
, char *)) != 0) {
170 if ((len
= va_arg(ap
, ssize_t
)) < 0)
171 msg_panic("argv_addn: bad string length %ld", (long) len
);
172 if (ARGV_SPACE_LEFT(argvp
) <= 0)
174 argvp
->argv
[argvp
->argc
++] = mystrndup(arg
, len
);
177 argvp
->argv
[argvp
->argc
] = 0;
180 /* argv_terminate - terminate string array */
182 void argv_terminate(ARGV
*argvp
)
186 * Trust that argvp->argc < argvp->len.
188 argvp
->argv
[argvp
->argc
] = 0;
191 /* argv_truncate - truncate string array */
193 void argv_truncate(ARGV
*argvp
, ssize_t len
)
201 msg_panic("argv_truncate: bad length %ld", (long) len
);
203 if (len
< argvp
->argc
) {
204 for (cpp
= argvp
->argv
+ len
; cpp
< argvp
->argv
+ argvp
->argc
; cpp
++)
207 argvp
->argv
[argvp
->argc
] = 0;