~donmcc/astr

ref: da1e8f414d3ebbcc625064018e67e92082c78723 astr/astr.c -rw-r--r-- 2.1 KiB
da1e8f41Don McCaughey Install automake package on Debian Linux build. 10 months ago
                                                                                
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
#include "astr.h"

#include <errno.h>
#include <stdio.h>


char *
astr_alloc_formatted(char const *format, ...)
{
    va_list arguments;
    va_start(arguments, format);
    char *s = astr_alloc_formatted_from_va_list(format, arguments);
    va_end(arguments);
    return s;
}


size_t
astr_formatted_length(char const *format, ...)
{
    va_list arguments;
    va_start(arguments, format);
    size_t length = astr_formatted_length_from_va_list(format, arguments);
    va_end(arguments);
    return length;
}


size_t
astr_formatted_length_from_va_list(char const *format, va_list arguments)
{
    if (!format) {
        errno = EINVAL;
        return 0;
    }

    va_list arguments_copy;
    va_copy(arguments_copy, arguments);
    int length = vsnprintf(NULL, 0, format, arguments_copy);
    if (length < 0) return 0;
    return length;
}


int
astr_realloc_append_formatted(char **s, char const *format, ...)
{
    va_list arguments;
    va_start(arguments, format);
    int result = astr_realloc_append_formatted_from_va_list(s, format, arguments);
    va_end(arguments);
    return result;
}


int
astr_realloc_append_formatted_from_va_list(char **s, 
                                           char const *format, 
                                           va_list arguments)
{
    if (!s || !format) {
        errno = EINVAL;
        return -1;
    }

    size_t length_to_append = astr_formatted_length_from_va_list(format, arguments);
    if (!length_to_append) return 0;

    size_t original_length = *s ? strlen(*s) : 0;
    size_t new_size = original_length + length_to_append + sizeof('\0');
    char *resized_s = realloc(*s, new_size);
    if (!resized_s) return -1;

    *s = resized_s;
    char *end_of_s = *s + original_length;
    va_list arguments_copy;
    va_copy(arguments_copy, arguments);
    vsprintf(end_of_s, format, arguments_copy);
    return 0;
}


extern char *
astr_alloc_empty(void);

extern char *
astr_alloc_formatted_from_va_list(char const *format, va_list arguments);

extern int 
astr_cmp(char const *s1, char const *s2);

extern bool
astr_empty(char const *s);

extern bool
astr_eq(char const *s1, char const *s2);