Mercurial > hg > dmlib
annotate src/dmstring.c @ 1884:47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
returns length of the generated string in int pointer *len.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 25 Jun 2018 13:24:27 +0300 |
parents | e06abfde6c39 |
children | 750a7e125546 |
rev | line source |
---|---|
0 | 1 #include "dmlib.h" |
2 #include <stdarg.h> | |
3 | |
813 | 4 |
5 /* Returns the filename and path without the last filename extension, | |
6 * E.g. everything before the last '.', if any. | |
7 */ | |
8 char *dm_basefilename(const char *filename) | |
9 { | |
10 char *tmp, *fext; | |
11 | |
12 if (filename == NULL || | |
13 (tmp = dm_strdup(filename)) == NULL) | |
14 return NULL; | |
15 | |
16 if ((fext = strrchr(tmp, '.')) != NULL) | |
17 { | |
18 char *fpath = strrchr(tmp, DM_DIR_SEPARATOR); | |
19 if (fpath == NULL || (fpath != NULL && fext > fpath)) | |
20 *fext = 0; | |
21 } | |
22 | |
23 return tmp; | |
24 } | |
25 | |
26 | |
27 /* Replace filename extension based on format pattern. | |
28 * Usage: res = dm_strdup_fext(orig_filename, "foo_%s.cmp"); | |
29 */ | |
30 char *dm_strdup_fext(const char *filename, const char *fmt) | |
31 { | |
32 char *result, *tmp; | |
33 | |
34 if ((tmp = dm_basefilename(filename)) == NULL) | |
35 return NULL; | |
36 | |
37 result = dm_strdup_printf(fmt, tmp); | |
38 | |
39 dmFree(tmp); | |
40 | |
41 return result; | |
42 } | |
43 | |
44 | |
817 | 45 /* Check if end of the given string str matches needle |
46 * case-insensitively, return pointer to start of the match, | |
47 * if found, NULL otherwise. | |
48 */ | |
816 | 49 char *dm_strrcasecmp(char *str, const char *needle) |
50 { | |
51 if (str == NULL || needle == NULL) | |
52 return NULL; | |
53 | |
54 const size_t | |
55 slen = strlen(str), | |
56 nlen = strlen(needle); | |
1102
e06abfde6c39
Cosmetics pass: Remove excess whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
836
diff
changeset
|
57 |
816 | 58 if (slen < nlen) |
59 return NULL; | |
60 | |
61 if (strcasecmp(str - nlen - 1, needle) == 0) | |
62 return str - nlen - 1; | |
63 else | |
64 return NULL; | |
65 } | |
66 | |
67 | |
744
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
68 /* Implementation of strdup() with a NULL check |
0 | 69 */ |
70 char *dm_strdup(const char *s) | |
71 { | |
72 char *res; | |
73 if (s == NULL) | |
74 return NULL; | |
75 | |
76 if ((res = dmMalloc(strlen(s) + 1)) == NULL) | |
77 return NULL; | |
78 | |
79 strcpy(res, s); | |
80 return res; | |
81 } | |
82 | |
83 | |
744
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
84 /* Implementation of strndup() with NULL check |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
85 */ |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
86 char *dm_strndup(const char *s, const size_t n) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
87 { |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
88 char *res; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
89 if (s == NULL) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
90 return NULL; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
91 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
92 size_t len = strlen(s); |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
93 if (len > n) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
94 len = n; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
95 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
96 if ((res = dmMalloc(len + 1)) == NULL) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
97 return NULL; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
98 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
99 memcpy(res, s, len); |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
100 res[len] = 0; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
101 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
102 return res; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
103 } |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
104 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
105 |
0 | 106 /* Simulate a sprintf() that allocates memory |
107 */ | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
108 char *dm_strdup_vprintf_len(const char *fmt, va_list args, int *len) |
0 | 109 { |
110 int size = 64; | |
836 | 111 char *buf, *tmp; |
0 | 112 |
113 if ((buf = dmMalloc(size)) == NULL) | |
114 return NULL; | |
115 | |
116 while (1) | |
117 { | |
118 va_list ap; | |
119 va_copy(ap, args); | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
120 *len = vsnprintf(buf, size, fmt, ap); |
0 | 121 va_end(ap); |
122 | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
123 if (*len > -1 && *len < size) |
0 | 124 return buf; |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
125 if (*len > -1) |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
126 size = *len + 1; |
0 | 127 else |
128 size *= 2; | |
129 | |
836 | 130 if ((tmp = dmRealloc(buf, size)) == NULL) |
131 { | |
132 dmFree(buf); | |
0 | 133 return NULL; |
836 | 134 } |
135 else | |
136 buf = tmp; | |
0 | 137 } |
138 } | |
139 | |
140 | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
141 char *dm_strdup_vprintf(const char *fmt, va_list args) |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
142 { |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
143 int len; |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
144 return dm_strdup_vprintf_len(fmt, args, &len); |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
145 } |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
146 |
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
147 |
0 | 148 char *dm_strdup_printf(const char *fmt, ...) |
149 { | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
150 int len; |
0 | 151 char *res; |
152 va_list ap; | |
153 | |
154 va_start(ap, fmt); | |
1884
47fe47f01fea
Implement dm_strdup_vprintf_len(const char *fmt, va_list args, int *len), which
Matti Hamalainen <ccr@tnsp.org>
parents:
1102
diff
changeset
|
155 res = dm_strdup_vprintf_len(fmt, ap, &len); |
0 | 156 va_end(ap); |
157 | |
158 return res; | |
159 } |