~ubuntu-branches/ubuntu/quantal/foomatic-filters/quantal

« back to all changes in this revision

Viewing changes to .pc/strncpy-tochar-use-isempty.patch/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Raboud, Translation updates
  • Date: 2011-02-09 15:38:14 UTC
  • mfrom: (1.2.4 upstream) (6.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20110209153814-noiljpseb0kzdlzs
Tags: 4.0.6-1
* Upload to unstable.

[ Translation updates ]
* Japanese: Indent correctly.

* Explicitly depend on bash (Closes: #600179)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* util.c
2
 
 *
3
 
 * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
4
 
 * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
5
 
 *
6
 
 * This file is part of foomatic-rip.
7
 
 *
8
 
 * Foomatic-rip is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2 of the License, or
11
 
 * (at your option) any later version.
12
 
 *
13
 
 * Foomatic-rip is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the
20
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
 
 * Boston, MA 02111-1307, USA.
22
 
 */
23
 
 
24
 
#include "util.h"
25
 
#include "foomaticrip.h"
26
 
#include <ctype.h>
27
 
#include <stdlib.h>
28
 
#include <stdio.h>
29
 
#include <unistd.h>
30
 
#include <stdarg.h>
31
 
#include <assert.h>
32
 
 
33
 
 
34
 
const char* shellescapes = "|<>&!$\'\"#*?()[]{}";
35
 
 
36
 
const char * temp_dir()
37
 
{
38
 
    static const char *tmpdir = NULL;
39
 
 
40
 
    if (!tmpdir)
41
 
    {
42
 
        const char *dirs[] = { getenv("TMPDIR"), P_tmpdir, "/tmp", NULL };
43
 
        const char **dir;
44
 
 
45
 
        for (dir = dirs; *dir; dir++)
46
 
            if (access(*dir, W_OK) == 0) {
47
 
                tmpdir = *dir;
48
 
                break;
49
 
            }
50
 
        if (tmpdir)
51
 
        {
52
 
            _log("Storing temporary files in %s\n", tmpdir);
53
 
            setenv("TMPDIR", tmpdir, 1); /* for child processes */
54
 
        }
55
 
        else
56
 
            rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS,
57
 
                    "Cannot find a writable temp dir.");
58
 
    }
59
 
 
60
 
    return tmpdir;
61
 
}
62
 
 
63
 
int prefixcmp(const char *str, const char *prefix)
64
 
{
65
 
    return strncmp(str, prefix, strlen(prefix));
66
 
}
67
 
 
68
 
int prefixcasecmp(const char *str, const char *prefix)
69
 
{
70
 
    return strncasecmp(str, prefix, strlen(prefix));
71
 
}
72
 
 
73
 
int startswith(const char *str, const char *prefix)
74
 
{
75
 
    return str ? (strncmp(str, prefix, strlen(prefix)) == 0) : 0;
76
 
}
77
 
 
78
 
int endswith(const char *str, const char *postfix)
79
 
{
80
 
    int slen = strlen(str);
81
 
    int plen = strlen(postfix);
82
 
    const char *pstr;
83
 
 
84
 
    if (slen < plen)
85
 
        return 0;
86
 
 
87
 
    pstr = &str[slen - plen];
88
 
    return strcmp(str, postfix) == 0;
89
 
}
90
 
 
91
 
const char * skip_whitespace(const char *str)
92
 
{
93
 
    while (*str && isspace(*str))
94
 
        str++;
95
 
    return str;
96
 
}
97
 
 
98
 
void strlower(char *dest, size_t destlen, const char *src)
99
 
{
100
 
    char *pdest = dest;
101
 
    const char *psrc = src;
102
 
    while (*psrc && --destlen > 0)
103
 
    {
104
 
        *pdest = tolower(*psrc);
105
 
        pdest++;
106
 
        psrc++;
107
 
    }
108
 
    *pdest = '\0';
109
 
}
110
 
 
111
 
int isempty(const char *string)
112
 
{
113
 
    return !string || string[0] == '\0';
114
 
}
115
 
 
116
 
const char * strncpy_omit(char* dest, const char* src, size_t n, int (*omit_func)(int))
117
 
{
118
 
    const char* psrc = src;
119
 
    char* pdest = dest;
120
 
    int cnt = n -1;
121
 
    if (!pdest)
122
 
        return NULL;
123
 
    if (psrc) {
124
 
        while (*psrc != 0 && cnt > 0) {
125
 
            if (!omit_func(*psrc)) {
126
 
                *pdest = *psrc;
127
 
                pdest++;
128
 
                cnt--;
129
 
            }
130
 
            psrc++;
131
 
        }
132
 
    }
133
 
    *pdest = '\0';
134
 
    return psrc;
135
 
}
136
 
int omit_unprintables(int c) { return c>= '\x00' && c <= '\x1f'; }
137
 
int omit_shellescapes(int c) { return strchr(shellescapes, c) != NULL; }
138
 
int omit_specialchars(int c) { return omit_unprintables(c) || omit_shellescapes(c); }
139
 
int omit_whitespace(int c) { return c == ' ' || c == '\t'; }
140
 
int omit_whitespace_newline(int c) { return omit_whitespace(c) || c == '\n'; }
141
 
 
142
 
#ifndef HAVE_STRCASESTR
143
 
char *
144
 
strcasestr (const char *haystack, const char *needle)
145
 
{
146
 
    char *p, *startn = 0, *np = 0;
147
 
 
148
 
    for (p = haystack; *p; p++) {
149
 
        if (np) {
150
 
            if (toupper(*p) == toupper(*np)) {
151
 
                if (!*++np)
152
 
                    return startn;
153
 
            } else
154
 
                np = 0;
155
 
        } else if (toupper(*p) == toupper(*needle)) {
156
 
            np = needle + 1;
157
 
            startn = p;
158
 
        }
159
 
    }
160
 
 
161
 
    return 0;
162
 
}
163
 
#endif
164
 
 
165
 
size_t strlcpy(char *dest, const char *src, size_t size)
166
 
{
167
 
    char *pdest = dest;
168
 
    const char *psrc = src;
169
 
 
170
 
    if (!src) {
171
 
        dest[0] = '\0';
172
 
        return 0;
173
 
    }
174
 
 
175
 
    if (size) {
176
 
        while (--size && (*pdest++ = *psrc++) != '\0');
177
 
        *pdest = '\0';
178
 
    }
179
 
    if (!size)
180
 
        while (*psrc++);
181
 
    return (psrc - src -1);
182
 
}
183
 
 
184
 
size_t strlcat(char *dest, const char *src, size_t size)
185
 
{
186
 
    char *pdest = dest;
187
 
    const char *psrc = src;
188
 
    size_t i = size;
189
 
    size_t len;
190
 
 
191
 
    while (--i && *pdest)
192
 
        pdest++;
193
 
    len = pdest - dest;
194
 
 
195
 
    if (!i)
196
 
        return strlen(src) + len;
197
 
 
198
 
    while (i-- && *psrc)
199
 
        *pdest++ = *psrc++;
200
 
    *pdest = '\0';
201
 
 
202
 
    return len + (psrc - src);
203
 
}
204
 
 
205
 
void strrepl(char *str, const char *chars, char repl)
206
 
{
207
 
    char *p = str;
208
 
 
209
 
    while (*p) {
210
 
        if (strchr(chars, *p))
211
 
            *p = repl;
212
 
        p++;
213
 
    }
214
 
}
215
 
 
216
 
void strrepl_nodups(char *str, const char *chars, char repl)
217
 
{
218
 
    char *pstr = str;
219
 
    char *p = str;
220
 
    int prev = 0;
221
 
 
222
 
    while (*pstr) {
223
 
        if (strchr(chars, *pstr) || *pstr == repl) {
224
 
            if (!prev) {
225
 
                *p = repl;
226
 
                p++;
227
 
                prev = 1;
228
 
            }
229
 
        }
230
 
        else {
231
 
            *p = *pstr;
232
 
            p++;
233
 
            prev = 0;
234
 
        }
235
 
        pstr++;
236
 
    }
237
 
    *p = '\0';
238
 
}
239
 
 
240
 
void strclr(char *str)
241
 
{
242
 
    while (*str) {
243
 
        *str = '\0';
244
 
        str++;
245
 
    }
246
 
}
247
 
 
248
 
char * strnchr(const char *str, int c, size_t n)
249
 
{
250
 
    char *p = (char*)str;
251
 
 
252
 
    while (*p && --n > 0) {
253
 
        if (*p == (char)c)
254
 
            return p;
255
 
        p++;
256
 
    }
257
 
    return p;
258
 
}
259
 
 
260
 
void escapechars(char *dest, size_t size, const char *src, const char *esc_chars)
261
 
{
262
 
    const char *psrc = src;
263
 
 
264
 
    while (*psrc && --size > 0) {
265
 
        if (strchr(esc_chars, *psrc))
266
 
            *dest++ = '\\';
267
 
        *dest++ = *psrc++;
268
 
    }
269
 
}
270
 
 
271
 
const char * strncpy_tochar(char *dest, const char *src, size_t max, const char *stopchars)
272
 
{
273
 
    const char *psrc = src;
274
 
    char *pdest = dest;
275
 
    if (!*psrc) {
276
 
       return NULL;
277
 
    }
278
 
    while (*psrc && --max > 0 && !strchr(stopchars, *psrc)) {
279
 
        *pdest = *psrc;
280
 
        pdest++;
281
 
        psrc++;
282
 
    }
283
 
    *pdest = '\0';
284
 
    return psrc +1;
285
 
}
286
 
 
287
 
int find_in_path(const char *progname, const char *paths, char *found_in)
288
 
{
289
 
    char *pathscopy;
290
 
    char *path;
291
 
    char filepath[PATH_MAX];
292
 
 
293
 
    if (access(progname, X_OK) == 0)
294
 
        return 1;
295
 
 
296
 
    pathscopy = strdup(paths);
297
 
    for (path = strtok(pathscopy, ":"); path; path = strtok(NULL, ":")) {
298
 
        strlcpy(filepath, path, PATH_MAX);
299
 
        strlcat(filepath, "/", PATH_MAX);
300
 
        strlcat(filepath, progname, PATH_MAX);
301
 
 
302
 
        if (access(filepath, X_OK) == 0) {
303
 
            if (found_in)
304
 
                strlcpy(found_in, path, PATH_MAX);
305
 
            free(pathscopy);
306
 
            return 1;
307
 
        }
308
 
    }
309
 
 
310
 
    if (found_in)
311
 
        found_in[0] = '\0';
312
 
    free(pathscopy);
313
 
    return 0;
314
 
}
315
 
 
316
 
void file_basename(char *dest, const char *path, size_t dest_size)
317
 
{
318
 
    const char *p = strrchr(path, '/');
319
 
    char *pdest = dest;
320
 
    if (!pdest)
321
 
        return;
322
 
    if (p)
323
 
        p += 1;
324
 
    else
325
 
        p = path;
326
 
    while (*p != 0 && *p != '.' && --dest_size > 0) {
327
 
        *pdest++ = *p++;
328
 
    }
329
 
    *pdest = '\0';
330
 
}
331
 
 
332
 
void make_absolute_path(char *path, int len)
333
 
{
334
 
    char *tmp, *cwd;
335
 
 
336
 
    if (path[0] != '/') {
337
 
        tmp = malloc(len +1);
338
 
        strlcpy(tmp, path, len);
339
 
 
340
 
        cwd = malloc(len);
341
 
        getcwd(cwd, len);
342
 
        strlcpy(path, cwd, len);
343
 
        strlcat(path, "/", len);
344
 
        strlcat(path, tmp, len);
345
 
 
346
 
        free(tmp);
347
 
        free(cwd);
348
 
    }
349
 
}
350
 
 
351
 
int is_true_string(const char *str)
352
 
{
353
 
    return str && (!strcmp(str, "1") || !strcasecmp(str, "Yes") ||
354
 
        !strcasecmp(str, "On") || !strcasecmp(str, "True"));
355
 
}
356
 
 
357
 
int is_false_string(const char *str)
358
 
{
359
 
    return str && (!strcmp(str, "0") || !strcasecmp(str, "No") ||
360
 
        !strcasecmp(str, "Off") || !strcasecmp(str, "False") ||
361
 
        !strcasecmp(str, "None"));
362
 
}
363
 
 
364
 
int digit(char c)
365
 
{
366
 
    if (c >= '0' && c <= '9')
367
 
        return (int)c - (int)'0';
368
 
    return -1;
369
 
}
370
 
 
371
 
static const char * next_token(const char *string, const char *separators)
372
 
{
373
 
    if (!string)
374
 
        return NULL;
375
 
 
376
 
    while (*string && !strchr(separators, *string))
377
 
        string++;
378
 
 
379
 
    while (*string && strchr(separators, *string))
380
 
        string++;
381
 
 
382
 
    return string;
383
 
}
384
 
 
385
 
static unsigned count_separators(const char *string, const char *separators)
386
 
{
387
 
    const char *p;
388
 
    unsigned cnt = 0;
389
 
 
390
 
    if (!string)
391
 
        return 0;
392
 
 
393
 
    for (p = string; *p; p = next_token(p, separators))
394
 
        cnt++;
395
 
 
396
 
    return cnt;
397
 
}
398
 
 
399
 
/*
400
 
 * Returns a zero terminated array of strings
401
 
 */
402
 
char ** argv_split(const char *string, const char *separators, int *cntp)
403
 
{
404
 
    unsigned cnt;
405
 
    int i;
406
 
    char **argv;
407
 
 
408
 
    if (!string)
409
 
        return NULL;
410
 
 
411
 
    if ((cnt = count_separators(string, separators)) == 0)
412
 
        return NULL;
413
 
 
414
 
    argv = malloc((cnt +1) * sizeof(char *));
415
 
    argv[cnt] = NULL;
416
 
 
417
 
    for (i = 0; i < cnt; i++)
418
 
    {
419
 
        size_t len = strcspn(string, separators);
420
 
        char *s;
421
 
        s = malloc(len + 1);
422
 
        strncpy(s, string, len);
423
 
        s[len] = '\0';
424
 
        argv[i] = s;
425
 
        string = next_token(string, separators);
426
 
    }
427
 
 
428
 
    if (cntp)
429
 
        *cntp = cnt;
430
 
    return argv;
431
 
}
432
 
 
433
 
size_t argv_count(char **argv)
434
 
{
435
 
    size_t cnt = 0;
436
 
 
437
 
    if (!argv)
438
 
        return 0;
439
 
 
440
 
    while (*argv++)
441
 
        cnt++;
442
 
 
443
 
    return cnt;
444
 
}
445
 
 
446
 
void argv_free(char **argv)
447
 
{
448
 
    char **p;
449
 
 
450
 
    if (!argv)
451
 
        return;
452
 
 
453
 
    for (p = argv; *p; p++)
454
 
        free(*p);
455
 
 
456
 
    free(argv);
457
 
}
458
 
 
459
 
int line_count(const char *str)
460
 
{
461
 
    int cnt = 0;
462
 
    while (*str) {
463
 
        if (*str == '\n')
464
 
            cnt++;
465
 
        str++;
466
 
    }
467
 
    return cnt;
468
 
}
469
 
 
470
 
int line_start(const char *str, int line_number)
471
 
{
472
 
    const char *p = str;
473
 
    while (*p && line_number > 0) {
474
 
        if (*p == '\n')
475
 
            line_number--;
476
 
        p++;
477
 
    }
478
 
    return p - str;
479
 
}
480
 
 
481
 
void unhexify(char *dest, size_t size, const char *src)
482
 
{
483
 
    char *pdest = dest;
484
 
    const char *psrc = src;
485
 
    char cstr[3];
486
 
 
487
 
    cstr[2] = '\0';
488
 
 
489
 
    while (*psrc && pdest - dest < size -1) {
490
 
        if (*psrc == '<') {
491
 
            psrc++;
492
 
            do {
493
 
                cstr[0] = *psrc++;
494
 
                cstr[1] = *psrc++;
495
 
                if (!isxdigit(cstr[0]) || !isxdigit(cstr[1])) {
496
 
                    printf("Error replacing hex notation in %s!\n", src);
497
 
                    break;
498
 
                }
499
 
                *pdest++ = (char)strtol(cstr, NULL, 16);
500
 
            } while (*psrc != '>');
501
 
            psrc++;
502
 
        }
503
 
        else
504
 
            *pdest++ = *psrc++;
505
 
    }
506
 
    *pdest = '\0';
507
 
}
508
 
 
509
 
void extract_command(size_t *start, size_t *end, const char *cmdline, const char *cmd)
510
 
{
511
 
    char *copy = strdup(cmdline);
512
 
    char *tok = NULL;
513
 
    const char *delim = "|;";
514
 
 
515
 
    *start = *end = 0;
516
 
    for (tok = strtok(copy, delim); tok; tok = strtok(NULL, delim)) {
517
 
        while (*tok && isspace(*tok))
518
 
            tok++;
519
 
        if (startswith(tok, cmd)) {
520
 
            *start = tok - copy;
521
 
            *end = tok + strlen(tok) - copy;
522
 
            break;
523
 
        }
524
 
    }
525
 
 
526
 
    free(copy);
527
 
}
528
 
 
529
 
int contains_command(const char *cmdline, const char *cmd)
530
 
{
531
 
    size_t start = 0, end = 0;
532
 
 
533
 
    extract_command(&start, &end, cmdline, cmd);
534
 
    if (start == 0 && end == 0)
535
 
        return 0;
536
 
 
537
 
    return 1;
538
 
}
539
 
 
540
 
/*
541
 
 * Dynamic strings
542
 
 */
543
 
dstr_t * create_dstr()
544
 
{
545
 
    dstr_t *ds = malloc(sizeof(dstr_t));
546
 
    ds->len = 0;
547
 
    ds->alloc = 32;
548
 
    ds->data = malloc(ds->alloc);
549
 
    ds->data[0] = '\0';
550
 
    return ds;
551
 
}
552
 
 
553
 
void free_dstr(dstr_t *ds)
554
 
{
555
 
    free(ds->data);
556
 
    free(ds);
557
 
}
558
 
 
559
 
void dstrclear(dstr_t *ds)
560
 
{
561
 
    ds->len = 0;
562
 
    ds->data[0] = '\0';
563
 
}
564
 
 
565
 
void dstrassure(dstr_t *ds, size_t alloc)
566
 
{
567
 
        if (ds->alloc < alloc) {
568
 
                ds->alloc = alloc;
569
 
                ds->data = realloc(ds->data, ds->alloc);
570
 
        }
571
 
}
572
 
 
573
 
void dstrcpy(dstr_t *ds, const char *src)
574
 
{
575
 
    size_t srclen;
576
 
 
577
 
    if (!src) {
578
 
        ds->len = 0;
579
 
        ds->data[0] = '\0';
580
 
        return;
581
 
    }
582
 
 
583
 
    srclen = strlen(src);
584
 
 
585
 
    if (srclen >= ds->alloc) {
586
 
        do {
587
 
            ds->alloc *= 2;
588
 
        } while (srclen >= ds->alloc);
589
 
        ds->data = realloc(ds->data, ds->alloc);
590
 
    }
591
 
 
592
 
    strcpy(ds->data, src);
593
 
    ds->len = srclen;
594
 
}
595
 
 
596
 
void dstrncpy(dstr_t *ds, const char *src, size_t n)
597
 
{
598
 
    if (n >= ds->alloc) {
599
 
        do {
600
 
            ds->alloc *= 2;
601
 
        } while (n >= ds->alloc);
602
 
        ds->data = realloc(ds->data, ds->alloc);
603
 
    }
604
 
 
605
 
    strncpy(ds->data, src, n);
606
 
    ds->len = n;
607
 
    ds->data[ds->len] = '\0';
608
 
}
609
 
 
610
 
void dstrncat(dstr_t *ds, const char *src, size_t n)
611
 
{
612
 
    size_t needed = ds->len + n;
613
 
 
614
 
    if (needed >= ds->alloc) {
615
 
        do {
616
 
            ds->alloc *= 2;
617
 
        } while (needed >= ds->alloc);
618
 
        ds->data = realloc(ds->data, ds->alloc);
619
 
    }
620
 
 
621
 
    strncpy(&ds->data[ds->len], src, n);
622
 
    ds->len = needed;
623
 
    ds->data[ds->len] = '\0';
624
 
}
625
 
 
626
 
void dstrcpyf(dstr_t *ds, const char *src, ...)
627
 
{
628
 
    va_list ap;
629
 
    size_t srclen;
630
 
 
631
 
    va_start(ap, src);
632
 
    srclen = vsnprintf(ds->data, ds->alloc, src, ap);
633
 
    va_end(ap);
634
 
 
635
 
    if (srclen >= ds->alloc) {
636
 
        do {
637
 
            ds->alloc *= 2;
638
 
        } while (srclen >= ds->alloc);
639
 
        ds->data = realloc(ds->data, ds->alloc);
640
 
 
641
 
        va_start(ap, src);
642
 
        vsnprintf(ds->data, ds->alloc, src, ap);
643
 
        va_end(ap);
644
 
    }
645
 
 
646
 
    ds->len = srclen;
647
 
}
648
 
 
649
 
void dstrputc(dstr_t *ds, int c)
650
 
{
651
 
    if (ds->len +1 >= ds->alloc) {
652
 
        ds->alloc *= 2;
653
 
        ds->data = realloc(ds->data, ds->alloc);
654
 
    }
655
 
    ds->data[ds->len++] = c;
656
 
    ds->data[ds->len] = '\0';
657
 
}
658
 
 
659
 
void dstrcat(dstr_t *ds, const char *src)
660
 
{
661
 
    size_t srclen = strlen(src);
662
 
    size_t newlen = ds->len + srclen;
663
 
 
664
 
    if (newlen >= ds->alloc) {
665
 
        do {
666
 
            ds->alloc *= 2;
667
 
        } while (newlen >= ds->alloc);
668
 
        ds->data = realloc(ds->data, ds->alloc);
669
 
    }
670
 
 
671
 
    memcpy(&ds->data[ds->len], src, srclen +1);
672
 
    ds->len = newlen;
673
 
}
674
 
 
675
 
void dstrcatf(dstr_t *ds, const char *src, ...)
676
 
{
677
 
    va_list ap;
678
 
    size_t restlen = ds->alloc - ds->len;
679
 
    size_t srclen;
680
 
 
681
 
    va_start(ap, src);
682
 
    srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap);
683
 
    va_end(ap);
684
 
 
685
 
    if (srclen >= restlen) {
686
 
        do {
687
 
            ds->alloc *= 2;
688
 
            restlen = ds->alloc - ds->len;
689
 
        } while (srclen >= restlen);
690
 
        ds->data = realloc(ds->data, ds->alloc);
691
 
 
692
 
        va_start(ap, src);
693
 
        srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap);
694
 
        va_end(ap);
695
 
    }
696
 
 
697
 
    ds->len += srclen;
698
 
}
699
 
 
700
 
size_t fgetdstr(dstr_t *ds, FILE *stream)
701
 
{
702
 
    int c;
703
 
    size_t cnt = 0;
704
 
 
705
 
    ds->len = 0;
706
 
    if (ds->alloc == 0) {
707
 
        ds->alloc = 256;
708
 
        ds->data = malloc(ds->alloc);
709
 
    }
710
 
 
711
 
    while ((c = fgetc(stream)) != EOF) {
712
 
        if (ds->len +1 == ds->alloc) {
713
 
            ds->alloc *= 2;
714
 
            ds->data = realloc(ds->data, ds->alloc);
715
 
        }
716
 
        ds->data[ds->len++] = (char)c;
717
 
        cnt ++;
718
 
        if (c == '\n')
719
 
            break;
720
 
    }
721
 
    ds->data[ds->len] = '\0';
722
 
    return cnt;
723
 
}
724
 
 
725
 
/*
726
 
 * Replace the first occurrence of 'find' after the index 'start' with 'repl'
727
 
 * Returns the position right after the replaced string
728
 
 */
729
 
int dstrreplace(dstr_t *ds, const char *find, const char *repl, int start)
730
 
{
731
 
    char *p;
732
 
    dstr_t *copy = create_dstr();
733
 
    int end = -1;
734
 
 
735
 
    dstrcpy(copy, ds->data);
736
 
 
737
 
    if ((p = strstr(&copy->data[start], find)))
738
 
    {
739
 
        dstrncpy(ds, copy->data, p - copy->data);
740
 
        dstrcatf(ds, "%s", repl);
741
 
        end = ds->len;
742
 
        dstrcatf(ds, "%s", p + strlen(find));
743
 
    }
744
 
 
745
 
    free_dstr(copy);
746
 
    return end;
747
 
}
748
 
 
749
 
void dstrprepend(dstr_t *ds, const char *str)
750
 
{
751
 
    dstr_t *copy = create_dstr();
752
 
    dstrcpy(copy, ds->data);
753
 
    dstrcpy(ds, str);
754
 
    dstrcatf(ds, "%s", copy->data);
755
 
    free_dstr(copy);
756
 
}
757
 
 
758
 
void dstrinsert(dstr_t *ds, int idx, const char *str)
759
 
{
760
 
    char * copy = strdup(ds->data);
761
 
    size_t len = strlen(str);
762
 
 
763
 
    if (idx >= ds->len)
764
 
        idx = ds->len;
765
 
    else if (idx < 0)
766
 
        idx = 0;
767
 
 
768
 
    if (ds->len + len >= ds->alloc) {
769
 
        do {
770
 
            ds->alloc *= 2;
771
 
        } while (ds->len + len >= ds->alloc);
772
 
        free(ds->data);
773
 
        ds->data = malloc(ds->alloc);
774
 
    }
775
 
 
776
 
    strncpy(ds->data, copy, idx);
777
 
    ds->data[idx] = '\0';
778
 
    strcat(ds->data, str);
779
 
    strcat(ds->data, &copy[idx]);
780
 
    ds->len += len;
781
 
    free(copy);
782
 
}
783
 
 
784
 
void dstrinsertf(dstr_t *ds, int idx, const char *str, ...)
785
 
{
786
 
    va_list ap;
787
 
    char *strf;
788
 
    size_t len;
789
 
 
790
 
    va_start(ap, str);
791
 
    len = vsnprintf(NULL, 0, str, ap);
792
 
    va_end(ap);
793
 
 
794
 
    strf = malloc(len +1);
795
 
    va_start(ap, str);
796
 
    vsnprintf(strf, len +1, str, ap);
797
 
    va_end(ap);
798
 
 
799
 
    dstrinsert(ds, idx, strf);
800
 
 
801
 
    free(strf);
802
 
}
803
 
 
804
 
void dstrremove(dstr_t *ds, int idx, size_t count)
805
 
{
806
 
    char *p1, *p2;
807
 
 
808
 
    if (idx + count >= ds->len)
809
 
        return;
810
 
 
811
 
    p1 = &ds->data[idx];
812
 
    p2 = &ds->data[idx + count];
813
 
 
814
 
    while (*p2) {
815
 
        *p1 = *p2;
816
 
        p1++;
817
 
        p2++;
818
 
    }
819
 
    *p1 = '\0';
820
 
}
821
 
 
822
 
static inline int isnewline(int c)
823
 
{
824
 
    return c == '\n' || c == '\r';
825
 
}
826
 
 
827
 
void dstrcatline(dstr_t *ds, const char *str)
828
 
{
829
 
    size_t eol = strcspn(str, "\n\r");
830
 
    if (isnewline(str[eol]))
831
 
        eol++;
832
 
    dstrncat(ds, str, eol);
833
 
}
834
 
 
835
 
int dstrendswith(dstr_t *ds, const char *str)
836
 
{
837
 
    int len = strlen(str);
838
 
    char *pstr;
839
 
 
840
 
    if (ds->len < len)
841
 
        return 0;
842
 
    pstr = &ds->data[ds->len - len];
843
 
    return strcmp(pstr, str) == 0;
844
 
 
845
 
}
846
 
 
847
 
void dstrfixnewlines(dstr_t *ds)
848
 
{
849
 
    if (ds->data[ds->len -1] == '\r') {
850
 
        ds->data[ds->len -1] = '\n';
851
 
    }
852
 
    else if (ds->data[ds->len -2] == '\r') {
853
 
        ds->data[ds->len -1] = '\n';
854
 
        ds->data[ds->len -2] = '\0';
855
 
        ds->len -= 1;
856
 
    }
857
 
}
858
 
 
859
 
void dstrremovenewline(dstr_t *ds)
860
 
{
861
 
    if (!ds->len)
862
 
        return;
863
 
 
864
 
    if (ds->data[ds->len -1] == '\r' || ds->data[ds->len -1] == '\n') {
865
 
        ds->data[ds->len -1] = '\0';
866
 
        ds->len -= 1;
867
 
    }
868
 
 
869
 
    if (ds->len < 2)
870
 
        return;
871
 
 
872
 
    if (ds->data[ds->len -2] == '\r') {
873
 
        ds->data[ds->len -2] = '\0';
874
 
        ds->len -= 2;
875
 
    }
876
 
}
877
 
 
878
 
void dstrtrim(dstr_t *ds)
879
 
{
880
 
    int pos = 0;
881
 
 
882
 
    while (pos < ds->len && isspace(ds->data[pos]))
883
 
        pos++;
884
 
 
885
 
    if (pos > 0) {
886
 
        ds->len -= pos;
887
 
        memmove(ds->data, &ds->data[pos], ds->len +1);
888
 
    }
889
 
}
890
 
 
891
 
void dstrtrim_right(dstr_t *ds)
892
 
{
893
 
    if (!ds->len)
894
 
        return;
895
 
 
896
 
    while (isspace(ds->data[ds->len -1]))
897
 
        ds->len -= 1;
898
 
    ds->data[ds->len] = '\0';
899
 
}
900
 
 
901
 
 
902
 
 
903
 
/*
904
 
 *  LIST
905
 
 */
906
 
 
907
 
list_t * list_create()
908
 
{
909
 
    list_t *l = malloc(sizeof(list_t));
910
 
    l->first = NULL;
911
 
    l->last = NULL;
912
 
    return l;
913
 
}
914
 
 
915
 
list_t * list_create_from_array(int count, void ** data)
916
 
{
917
 
    int i;
918
 
    list_t *l = list_create();
919
 
 
920
 
    for (i = 0; i < count; i++)
921
 
        list_append(l, data[i]);
922
 
 
923
 
    return l;
924
 
}
925
 
 
926
 
void list_free(list_t *list)
927
 
{
928
 
    listitem_t *i = list->first, *tmp;
929
 
    while (i) {
930
 
        tmp = i->next;
931
 
        free(i);
932
 
        i = tmp;
933
 
    }
934
 
}
935
 
 
936
 
size_t list_item_count(list_t *list)
937
 
{
938
 
    size_t cnt = 0;
939
 
    listitem_t *i;
940
 
    for (i = list->first; i; i = i->next)
941
 
        cnt++;
942
 
    return cnt;
943
 
}
944
 
 
945
 
list_t * list_copy(list_t *list)
946
 
{
947
 
    list_t *l = list_create();
948
 
    listitem_t *i;
949
 
 
950
 
    for (i = list->first; i; i = i->next)
951
 
        list_append(l, i->data);
952
 
    return l;
953
 
}
954
 
 
955
 
void list_prepend(list_t *list, void *data)
956
 
{
957
 
    listitem_t *item;
958
 
 
959
 
    assert(list);
960
 
 
961
 
    item = malloc(sizeof(listitem_t));
962
 
    item->data = data;
963
 
    item->prev = NULL;
964
 
 
965
 
    if (list->first) {
966
 
        item->next = list->first;
967
 
        list->first->next = item;
968
 
        list->first = item;
969
 
    }
970
 
    else {
971
 
        item->next = NULL;
972
 
        list->first = item;
973
 
        list->last = item;
974
 
    }
975
 
}
976
 
 
977
 
void list_append(list_t *list, void *data)
978
 
{
979
 
    listitem_t *item;
980
 
 
981
 
    assert(list);
982
 
 
983
 
    item = malloc(sizeof(listitem_t));
984
 
    item->data = data;
985
 
    item->next = NULL;
986
 
 
987
 
    if (list->last) {
988
 
        item->prev = list->last;
989
 
        list->last->next = item;
990
 
        list->last = item;
991
 
    }
992
 
    else {
993
 
        item->prev = NULL;
994
 
        list->first = item;
995
 
        list->last = item;
996
 
    }
997
 
}
998
 
 
999
 
void list_remove(list_t *list, listitem_t *item)
1000
 
{
1001
 
    assert(item);
1002
 
 
1003
 
    if (item->prev)
1004
 
        item->prev->next = item->next;
1005
 
    if (item->next)
1006
 
        item->next->prev = item->prev;
1007
 
    if (item == list->first)
1008
 
        list->first = item->next;
1009
 
    if (item == list->last)
1010
 
        list->last = item->prev;
1011
 
 
1012
 
    free(item);
1013
 
}
1014
 
 
1015
 
listitem_t * list_get(list_t *list, int idx)
1016
 
{
1017
 
    listitem_t *i;
1018
 
    for (i = list->first; i && idx; i = i->next)
1019
 
        idx--;
1020
 
    return i;
1021
 
}
1022
 
 
1023
 
listitem_t * arglist_find(list_t *list, const char *name)
1024
 
{
1025
 
    listitem_t *i;
1026
 
    for (i = list->first; i; i = i->next) {
1027
 
        if (!strcmp((const char*)i->data, name))
1028
 
            return i;
1029
 
    }
1030
 
    return NULL;
1031
 
}
1032
 
 
1033
 
listitem_t * arglist_find_prefix(list_t *list, const char *name)
1034
 
{
1035
 
    listitem_t *i;
1036
 
    for (i = list->first; i; i= i->next) {
1037
 
        if (!prefixcmp((const char*)i->data, name))
1038
 
            return i;
1039
 
    }
1040
 
    return NULL;
1041
 
}
1042
 
 
1043
 
 
1044
 
char * arglist_get_value(list_t *list, const char *name)
1045
 
{
1046
 
    listitem_t *i;
1047
 
    char *p;
1048
 
 
1049
 
    for (i = list->first; i; i = i->next) {
1050
 
        if (i->next && !strcmp(name, (char*)i->data))
1051
 
            return (char*)i->next->data;
1052
 
        else if (!prefixcmp((char*)i->data, name)) {
1053
 
            p = &((char*)i->data)[strlen(name)];
1054
 
            return *p == '=' ? p +1 : p;
1055
 
        }
1056
 
    }
1057
 
    return NULL;
1058
 
}
1059
 
 
1060
 
char * arglist_get(list_t *list, int idx)
1061
 
{
1062
 
    listitem_t *i = list_get(list, idx);
1063
 
    return i ? (char*)i->data : NULL;
1064
 
}
1065
 
 
1066
 
int arglist_remove(list_t *list, const char *name)
1067
 
{
1068
 
    listitem_t *i;
1069
 
    char *i_name;
1070
 
 
1071
 
    for (i = list->first; i; i = i->next) {
1072
 
        i_name = (char*)i->data;
1073
 
        if (i->next && !strcmp(name, i_name)) {
1074
 
            list_remove(list, i->next);
1075
 
            list_remove(list, i);
1076
 
            return 1;
1077
 
        }
1078
 
        else if (!prefixcmp(i_name, name)) {
1079
 
            list_remove(list, i);
1080
 
            return 1;
1081
 
        }
1082
 
    }
1083
 
    return 0;
1084
 
}
1085
 
 
1086
 
int arglist_remove_flag(list_t *list, const char *name)
1087
 
{
1088
 
    listitem_t *i = arglist_find(list, name);
1089
 
    if (i) {
1090
 
        list_remove(list, i);
1091
 
        return 1;
1092
 
    }
1093
 
    return 0;
1094
 
}
1095
 
 
1096
 
int copy_file(FILE *dest,
1097
 
              FILE *src,
1098
 
              const char *alreadyread,
1099
 
              size_t alreadyread_len)
1100
 
{
1101
 
    char buf[8192];
1102
 
    size_t bytes;
1103
 
 
1104
 
    if (alreadyread && alreadyread_len)
1105
 
    {
1106
 
        if (fwrite(alreadyread, 1, alreadyread_len, dest) < alreadyread_len)
1107
 
        {
1108
 
            _log("Could not write to temp file\n");
1109
 
            return 0;
1110
 
        }
1111
 
    }
1112
 
 
1113
 
    while ((bytes = fread(buf, 1, 8192, src)))
1114
 
        fwrite(buf, 1, bytes, dest);
1115
 
 
1116
 
    return !ferror(src) && !ferror(dest);
1117
 
}
1118