Mercurial > hg > dmlib
annotate src/dmstring.c @ 813:b0cd28b6c9f3
Add new utility functions.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 16 May 2014 15:17:48 +0300 |
parents | 1e5cf1144f36 |
children | 091461e0213f |
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 | |
744
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
45 /* Implementation of strdup() with a NULL check |
0 | 46 */ |
47 char *dm_strdup(const char *s) | |
48 { | |
49 char *res; | |
50 if (s == NULL) | |
51 return NULL; | |
52 | |
53 if ((res = dmMalloc(strlen(s) + 1)) == NULL) | |
54 return NULL; | |
55 | |
56 strcpy(res, s); | |
57 return res; | |
58 } | |
59 | |
60 | |
744
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
61 /* Implementation of strndup() with NULL check |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
62 */ |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
63 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
|
64 { |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
65 char *res; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
66 if (s == NULL) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
67 return NULL; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
68 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
69 size_t len = strlen(s); |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
70 if (len > n) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
71 len = n; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
72 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
73 if ((res = dmMalloc(len + 1)) == NULL) |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
74 return NULL; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
75 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
76 memcpy(res, s, len); |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
77 res[len] = 0; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
78 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
79 return res; |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
80 } |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
81 |
2726d91e3409
Add implementation of dm_strndup().
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
82 |
0 | 83 /* Simulate a sprintf() that allocates memory |
84 */ | |
85 char *dm_strdup_vprintf(const char *fmt, va_list args) | |
86 { | |
87 int size = 64; | |
88 char *buf; | |
89 | |
90 if ((buf = dmMalloc(size)) == NULL) | |
91 return NULL; | |
92 | |
93 while (1) | |
94 { | |
95 int n; | |
96 va_list ap; | |
97 va_copy(ap, args); | |
98 n = vsnprintf(buf, size, fmt, ap); | |
99 va_end(ap); | |
100 | |
101 if (n > -1 && n < size) | |
102 return buf; | |
103 if (n > -1) | |
104 size = n + 1; | |
105 else | |
106 size *= 2; | |
107 | |
108 if ((buf = dmRealloc(buf, size)) == NULL) | |
109 return NULL; | |
110 } | |
111 } | |
112 | |
113 | |
114 char *dm_strdup_printf(const char *fmt, ...) | |
115 { | |
116 char *res; | |
117 va_list ap; | |
118 | |
119 va_start(ap, fmt); | |
120 res = dm_strdup_vprintf(fmt, ap); | |
121 va_end(ap); | |
122 | |
123 return res; | |
124 } |