/usr/include/dacs/ds.h is in libdacs-dev 1.4.38a-2build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | /*
* Copyright (c) 2003-2015
* Distributed Systems Software. All rights reserved.
* See the file LICENSE for redistribution information.
*
* $Id: ds.h 2905 2016-07-05 14:54:12Z brachman $
*/
/*****************************************************************************
* COPYRIGHT AND PERMISSION NOTICE
*
* Copyright (c) 2001-2003 The Queen in Right of Canada
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, provided that the above copyright notice(s) and this
* permission notice appear in all copies of the Software and that both the
* above copyright notice(s) and this permission notice appear in supporting
* documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
* BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall not
* be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization of the
* copyright holder.
***************************************************************************/
#ifndef _DS_H_
#define _DS_H_
/*
* Package for safely allocating and using dynamically constructed character
* strings and dynamically constructed vectors.
*/
#include "dacs_config.h"
#include "range.h"
#include <regex.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#define HAVE_DS
#ifndef MAYBE_UNUSED
#define MAYBE_UNUSED __attribute__ ((__unused__))
#endif
#ifndef ALLOC
#define ALLOC(OBJ) ((OBJ *) malloc(sizeof(OBJ)))
#endif
#ifndef ALLOC_N
#define ALLOC_N(OBJ, N) ((OBJ *) malloc(sizeof(OBJ) * (N)))
#endif
/* Multi-source input descriptor */
typedef struct Dsio {
FILE *fp; /* If non-NULL, the input stream */
char *buf; /* If no input stream, the input buffer... */
char *ptr; /* ... and a pointer into the input buffer */
unsigned long length; /* The length of the input, if known, in bytes */
unsigned long rem; /* Bytes remaining in input, if known */
int have_length; /* Non-zero if length is unavailable */
int got_peeked_char; /* Non-zero if there's a peeked character */
char peeked_char; /* The peeked character */
} Dsio;
/* A dynamic string descriptor */
typedef struct Ds {
unsigned int alloc_flag : 1; /* Set if this struct was malloc-ed */
unsigned int clear_flag : 1; /* Set to zero freed memory */
unsigned int exact_flag : 1; /* Allocate the exact amount required */
unsigned int delnl_flag : 1; /* Delete newlines read from stream */
unsigned int crnl_flag : 1; /* Make \r\n equivalent to \n from stream */
unsigned int escnl_flag : 1; /* Allow lines to be continued */
void *buf; /* Pointer to a malloc-ed buffer, or NULL */
size_t nalloc; /* Allocated size of the buffer */
size_t len; /* Bytes put into the buffer, not */
/* necessarily the strlen */
size_t len_limit; /* Maximum value of len (0 means no limit) */
void *(*malloc)(size_t size);
void (*free)(void *ptr);
Dsio *io;
} Ds;
enum ds_prompt_flag {
DS_PROMPT_ECHO = 0,
DS_PROMPT_NOECHO = 1,
DS_PROMPT_HIDE = 2, /* Not implemented. */
DS_PROMPT_MAYECHO = 3 /* Not implemented. */
};
/*
* Return a pointer to the dynamically allocated buffer.
* Be careful though; if the buffer is reallocated, this pointer could become
* invalid.
*/
static inline char *
ds_buf(Ds *ds)
{
return((char *) ds->buf);
}
static inline unsigned char *
ds_ucbuf(Ds *ds)
{
return((unsigned char *) ds->buf);
}
/*
* Return the number of bytes in the buffer that are in use (which is less
* than or equal to the number of bytes allocated for the buffer).
*/
static inline size_t
ds_len(Ds *ds)
{
return(ds->len);
}
/*
* Return the number of bytes allocated for the buffer (which is greater than
* or equal to the number of bytes "in use").
*/
static inline size_t
ds_size(Ds *ds)
{
return(ds->nalloc);
}
/*
* Return the number of bytes remaining for use.
*/
static inline size_t
ds_rem(Ds *ds)
{
return(ds->nalloc - ds->len);
}
/*
* Return 0 if DS1 and DS2 are not identical strings (possibly binary),
* otherwise return 1.
*/
static inline int
ds_eq(Ds *ds1, Ds *ds2)
{
if (ds1 == ds2)
return(1);
if (ds1->len != ds2->len)
return(0);
return(memcmp((const void *) ds1->buf, (const void *) ds2->buf, ds1->len)
== 0);
}
/* XXX Should be integrated with Ds */
extern char *ds_errmsg;
#ifdef __cplusplus
extern "C" {
#endif
extern Ds *ds_alloc(void);
extern Ds *ds_alloc_size(size_t nbytes);
extern Ds *ds_init(Ds *ds);
extern Ds *ds_init_size(Ds *ds, size_t nbytes);
extern Ds *ds_dup(Ds *dsx);
extern Ds *ds_reinit(Ds *ds);
extern Ds *ds_reinit_size(Ds *ds, size_t nbytes);
extern Ds *ds_reset(Ds *ds);
extern Ds *ds_reset_buf(Ds *ds);
extern char *ds_fill(Ds *ds, size_t nbytes);
extern void ds_free(Ds *ds);
extern Ds *ds_trim(Ds *ds);
extern Ds *ds_grow(Ds *ds, size_t new_size);
extern int ds_appendc(Ds *ds, int ch);
extern char *ds_append(Ds *ds, char *str);
extern char *ds_appendn(Ds *ds, char *str, size_t len);
extern char *ds_concat(Ds *ds, char *str);
extern char *ds_concatc(Ds *ds, int ch);
extern char *ds_concatn(Ds *ds, char *str, size_t len);
extern char *ds_prepend(Ds *ds, char *str);
extern int ds_prependc(Ds *ds, int ch);
extern Ds *ds_set(Ds *ds, char *str);
extern Ds *ds_setn(Ds *dsx, unsigned char *s, size_t slen);
extern char *ds_copyb(Ds *ds, void *src, size_t len, unsigned int offset);
extern Ds *ds_copyspn(Ds *dsx, unsigned char *s, char *end_chars);
extern char *ds_insertb(Ds *ds, void *src, size_t len, unsigned int offset);
extern Ds *ds_range(Ds *dsx, char *str, char *range_spec, Range_syntax *ors);
extern size_t ds_chop(Ds *ds, size_t chop);
extern int ds_zapnull(Ds *ds);
extern int ds_getc(Ds *ds, FILE *fp, int *chp);
extern char *ds_gets(Ds *ds, FILE *fp);
extern char *ds_agets(Ds *ds, FILE *fp);
extern Ds *ds_load_file(Ds *ds, char *pathname);
extern Ds *ds_getf(FILE *fp);
extern Ds *ds_agetf(Ds *ds, FILE *fp);
extern char *ds_prompt(Ds *ds, char *prompt, unsigned int flag);
extern Ds *ds_subst(Ds *ds, unsigned char ch_src, unsigned char ch_rpl);
#ifndef NOTDEF
extern int ds_asprintf(Ds *ds, const char *fmt, ...)
__attribute__ ((format (printf, 2, 0)));
extern int ds_psprintf(Ds *ds, const char *fmt, ...)
__attribute__ ((format (printf, 2, 0)));
extern int ds_sprintf(Ds *ds, unsigned int offset, const char *fmt, ...)
__attribute__ ((format (printf, 3, 0)));
extern char *ds_xprintf(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern int ds_vasprintf(Ds *ds, const char *fmt, va_list ap)
__attribute__ ((format (printf, 2, 0)));
extern char *ds_vxprintf(const char *fmt, va_list ap)
__attribute__ ((format (printf, 1, 0)));
#else
extern int ds_asprintf(Ds *ds, const char *fmt, ...);
extern int ds_psprintf(Ds *ds, const char *fmt, ...);
extern int ds_sprintf(Ds *ds, unsigned int offset, const char *fmt, ...);
extern int ds_vasprintf(Ds *ds, const char *fmt, va_list ap);
extern char *ds_vxprintf(const char *fmt, va_list ap);
extern char *ds_xprintf(const char *fmt, ...);
#endif
extern FILE *ds_fopen_secure(const char *path, const char *mode, size_t size);
extern int ds_fclose(FILE *fp);
extern void ds_fclean(FILE *fp);
extern Ds *ds_dsappend(Ds *dsx, int no_nul, unsigned int n, ...);
extern Ds *ds_dsvaappend(Ds *dsx, int no_nul, unsigned int n, va_list ap);
extern Dsio *dsio_set(Ds *ds, FILE *fp, char *buf, unsigned long len,
int have_length);
extern int dsio_eof(Ds *ds);
extern int dsio_nextc(Ds *ds, int *ch_ptr);
extern int dsio_peekc(Ds *ds, int *ch_ptr);
extern char *dsio_agets(Ds *ds);
extern char *dsio_gets(Ds *ds);
extern char *dsio_agets_buf(Ds *ds, char *buf);
extern int dsio_load(Ds *ds);
extern char *dsio_load_str(Ds *ds);
extern int dsio_free(Ds *ds);
#ifdef HAVE_READLINE
extern char *ds_readline(Ds *ds, char *prompt, char *cprompt);
#endif
#ifdef __cplusplus
}
#endif
extern int ds_default_clear_flag;
extern int ds_default_delnl_flag;
extern size_t ds_default_len_limit;
extern void *(*ds_default_malloc_func)(size_t size);
extern void (*ds_default_free_func)(void *ptr);
/*
* Although Dsvec is a related but really separate idea, it is currently
* included in this library.
* The data structure and supporting functions comprise a means of constructing
* and dynamically extending a vector of objects (such as pointers or
* structures).
*/
typedef struct Dsvec {
unsigned int alloc_flag : 1; /* Set if this struct was malloc-ed */
unsigned int clear_flag : 1; /* Set to zero freed memory */
unsigned int exact_flag : 1; /* Allocate the exact amount required */
void **ptr; /* Pointer to a malloc-ed vector, or NULL */
size_t el_size; /* Size of each element, in bytes */
unsigned int nalloc; /* Number of elements allocated */
unsigned int nused; /* Number of elements used */
unsigned int nused_limit; /* Max value of nused (0 means no limit) */
void *(*malloc)(size_t size);
void (*free)(void *ptr);
} Dsvec;
/* Macro for accessing pointer at offset IND, which is of type TYPE. */
#define dsvec_ptr(DSV, IND, TYPE) ((TYPE) dsvec_ptr_index(DSV, IND))
/* Macro for accessing object at offset IND, which is of type TYPE. */
#define dsvec_obj(DSV, IND, TYPE) (&((TYPE) dsvec_base(DSV))[IND])
#define dsvec_new_obj(DSV, TYPE) (dsvec_add_obj(DSV) == -1 \
? (TYPE) NULL : dsvec_obj(DSV, DSV->nused - 1, TYPE))
#define dsvec_base_type(DSV, TYPE) (TYPE) dsvec_base(DSV)
static inline void **
dsvec_base(Dsvec *dsv)
{
if (dsv == NULL)
return(NULL);
return(dsv->ptr);
}
static inline unsigned int
dsvec_len(Dsvec *dsv)
{
if (dsv == NULL)
return(0);
return(dsv->nused);
}
static inline unsigned int
dsvec_size(Dsvec *dsv)
{
if (dsv == NULL)
return(0);
return(dsv->el_size);
}
typedef struct Mkargv {
int keepq; /* If non-zero, include the start/end quote character with the element. */
int keepws; /* If non-zero, include whitespace that precedes an element with the element. */
char *ifs; /* Any character in this string is a field separator character. */
char *startq; /* Any character in this string is a starting quote character. */
char *endq; /* Each character is an ending quote character, but only when it matches the
* corresponding starting quote character.
*/
} Mkargv;
/* For dsvec_select() */
typedef struct Select_arg {
char *regex;
regex_t *preg;
int regex_flags;
int anchored;
char *errbuf;
size_t errbuf_size;
} Select_arg;
/* For dsvec_complete() */
typedef struct Completions {
int start; /* If non-negative, the index of the first completion. */
int end; /* The index of the last completion. */
#ifdef NOTDEF
Dsvec *dsv;
#endif
int prefix_cnt; /* Number of initial common completion characters. */
int skip_cnt; /* Number of completion characters after prefix. */
} Completions;
/* XXX Should be integrated with Dsvec */
extern char *dsvec_errmsg;
extern int dsvec_default_initial_nalloc;
extern int dsvec_default_clear_flag;
extern int dsvec_default_nused_limit;
extern void *(*dsvec_default_malloc_func)(size_t size);
extern void (*dsvec_default_free_func)(void *ptr);
#ifdef __cplusplus
extern "C" {
#endif
extern Dsvec *dsvec_init(Dsvec *odsv, size_t size);
extern Dsvec *dsvec_alloc(size_t size);
extern Dsvec *dsvec_init_size(Dsvec *odsv, size_t size, int n);
extern Dsvec *dsvec_alloc_size(size_t size, int n);
extern void dsvec_free(Dsvec *dsv);
extern Dsvec *dsvec_grow(Dsvec *dsv, unsigned int new_nelements);
extern void *dsvec_ptr_index(Dsvec *dsv, unsigned int ind);
extern void *dsvec_ptr_rindex(Dsvec *dsv, unsigned int rind);
extern int dsvec_append(Dsvec *primary, Dsvec *secondary);
extern int dsvec_set(Dsvec *odsv, void *base, size_t size, int n);
extern int dsvec_add_obj(Dsvec *dsv);
extern Dsvec *dsvec_list(Dsvec *odsv, char **list);
extern Dsvec *dsvec_csv(char *str, char *ifs, char *startq, char *endq, int include_ws);
extern void dsvec_sort(Dsvec *dsv, int (*compar)(const void *, const void *));
extern int dsvec_compar_string(const void *ap, const void *bp);
extern int dsvec_compar_string_nocase(const void *ap, const void *bp);
extern int dsvec_find(Dsvec *dsv, void *el,
int (*compar)(const void *, const void *));
extern Dsvec *dsvec_select(Dsvec *dsv, void *el,
void *(*compar_init)(const void *),
void *compar_init_arg,
int (*compar)(const void *, const void *, void *));
extern void * dsvec_select_init(const void *arg);
extern void *dsvec_select_initx(const void *arg);
extern int dsvec_select_compar(const void *a, const void *b, void *compar_arg);
extern int dsvec_delete_ptr_index(Dsvec *dsv, unsigned int ind);
extern Dsvec *dsvec_load(Ds *ds, Dsvec *dsv);
extern Dsvec *ds_mkargv(Dsvec *dsv, char *str, Mkargv *conf);
extern Dsvec *ds_mkargv_add(Dsvec *dsv, char *el);
extern Dsvec *ds_mkargv_addv(Dsvec *dsv, int argc, char **argv);
extern int dsvec_add_ptr(Dsvec *dsv, void *ptr);
extern Dsvec *dsvec_copy(Dsvec *odsv, Dsvec *old_dsv);
extern Dsvec *dsvec_subset(Dsvec *odsv, Dsvec *old_dsv, unsigned int start,
int len);
extern int dsvec_delete(Dsvec *dsv, unsigned int ind, unsigned int nelements);
extern int dsvec_delete_ptr(Dsvec *dsv, void *ptr);
extern int dsvec_insert(Dsvec *primary, unsigned int ind, Dsvec *secondary);
extern int dsvec_insert_ptr(Dsvec *dsv, unsigned int ind, void *ptr);
extern int dsvec_prepend_ptr(Dsvec *dsv, void *ptr);
extern Dsvec *dsvec_range(Dsvec *odsv, Dsvec *primary, char *range_spec,
Range_syntax *rs);
extern int dsvec_replace(Dsvec *primary, unsigned int ind,
unsigned int nelements, Dsvec *secondary);
extern int dsvec_replace_ptr(Dsvec *dsv, void *ptr, unsigned int ind);
extern int dsvec_rotate(Dsvec *dsv, int npos);
extern int dsvec_shift(Dsvec *dsv, int count);
extern Dsvec *dsvec_slice(Dsvec *odsv, Dsvec *primary, unsigned int ind,
unsigned int len);
extern Dsvec *dsvec_lines(Dsvec *dsv, char *buf);
extern Dsvec *dsvec_load_lines(Dsvec *dsv, char *pathname);
extern int dsvec_streq(Dsvec *dsv1, Dsvec *dsv2);
extern int dsvec_strneq(Dsvec *dsv1, Dsvec *dsv2, size_t len);
extern Dsvec *dsvec_strlist(Dsvec *odsv, const char *str_spec);
extern void dsvec_str_emit(FILE *ofp, Dsvec *dsv);
extern int dsvec_is_subset(Dsvec *dsv, Dsvec *dsv_subset,
int (*compar)(const void *, const void *));
extern int dsvec_is_equiv(Dsvec *dsv_a, Dsvec *dsv_b,
int (*compar)(const void *, const void *));
extern int dsvec_is_identical(Dsvec *dsv_a, Dsvec *dsv_b,
int (*compar)(const void *, const void *));
extern int dsvec_binary_search(Dsvec *dsv, void *ww,
int (*compar)(void *, void *, void *, size_t *),
void *conf);
extern int dsvec_complete(Dsvec *dsv, char *word,
int (*compar)(void *, void *, void *, size_t *),
void *conf, Completions *completions);
extern int dsvec_selftest(FILE *out);
#ifdef NOTDEF
extern int dsvec_mkargv(Dsvec *dsv, char ***argvp, int *argcp);
#endif
#ifdef __cplusplus
}
#endif
static MAYBE_UNUSED Dsvec *
dsvec_set_init(Dsvec *odsv, void *base, size_t size)
{
Dsvec *dsv;
if (base == NULL || size == 0)
return(NULL);
if (odsv != NULL) {
if (odsv->el_size != size)
return(NULL);
dsv = odsv;
}
else
dsv = dsvec_init(odsv, size);
return(dsv);
}
/*
* Create or append N elements of type OBJ_TYPE to a vector, starting at the
* address BASE. If appending, the elements must be of the same size as the
* existing one.
* If N is NULL, then a NULL element marks the end of the copied list; the
* NULL element is NOT copied.
* DSV is set to point to the list and on entry must either be NULL or a
* valid vector.
*/
#define dsvec_set(DSV, BASE, OBJ_TYPE, N) \
{ \
int i, st; \
Dsvec *xdsv; \
OBJ_TYPE *ptr; \
\
st = ((xdsv = dsvec_set_init(DSV, BASE, sizeof(OBJ_TYPE))) == NULL) ? -1 : 0; \
ptr = BASE; \
for (i = 0; st == 0 && ((N == 0) || (i < N)); i++) { \
if (N == 0 && ptr[i] == NULL) \
break; \
if (dsvec_add_ptr(xdsv, ptr[i]) == -1) \
st = -1; \
} \
DSV = (st == -1) ? NULL : xdsv; \
}
#endif
|