annotate str.c @ 257:068955620d10

str: str_free(NULL) should assert str_free is essentially an internal function. Therefore, it doesn't have to be nice to use, and instead it should have extra sanity checking instead. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 12 Jul 2017 09:17:17 +0300
parents 7b1c311a77e4
children 88f777a374ad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
1 /*
155
a68a3c91f9b6 str: use the generic getref/putref generator macros
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 120
diff changeset
2 * Copyright (c) 2014-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
3 *
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
5 * of this software and associated documentation files (the "Software"), to deal
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
6 * in the Software without restriction, including without limitation the rights
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
8 * copies of the Software, and to permit persons to whom the Software is
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
9 * furnished to do so, subject to the following conditions:
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
10 *
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
11 * The above copyright notice and this permission notice shall be included in
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
12 * all copies or substantial portions of the Software.
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
13 *
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
20 * SOFTWARE.
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
21 */
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
22
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
23 #include <stdlib.h>
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
24 #include <stdbool.h>
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
25 #include <alloca.h>
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
26
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
27 #include <jeffpc/str.h>
159
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
28 #include <jeffpc/mem.h>
19
017a4abcfe3d init: add a single initialize-the-library function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 12
diff changeset
29 #include <jeffpc/jeffpc.h>
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
30
190
471436f681f3 str: preallocate the empty string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
31 static struct str empty_string = STR_STATIC_INITIALIZER("");
192
94c9db63f1c3 str: preallocate " " string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 191
diff changeset
32 static struct str one_char[128] = {
230
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
33 ['\''] = STR_STATIC_INITIALIZER("'"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
34 ['\\'] = STR_STATIC_INITIALIZER("\\"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
35 ['\n'] = STR_STATIC_INITIALIZER("\n"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
36 ['\r'] = STR_STATIC_INITIALIZER("\r"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
37 ['\t'] = STR_STATIC_INITIALIZER("\t"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
38
192
94c9db63f1c3 str: preallocate " " string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 191
diff changeset
39 [' '] = STR_STATIC_INITIALIZER(" "),
230
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
40 ['!'] = STR_STATIC_INITIALIZER("!"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
41 ['"'] = STR_STATIC_INITIALIZER("\""),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
42 ['#'] = STR_STATIC_INITIALIZER("#"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
43 ['$'] = STR_STATIC_INITIALIZER("$"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
44 ['%'] = STR_STATIC_INITIALIZER("%"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
45 ['&'] = STR_STATIC_INITIALIZER("&"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
46 ['('] = STR_STATIC_INITIALIZER("("),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
47 [')'] = STR_STATIC_INITIALIZER(")"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
48 ['*'] = STR_STATIC_INITIALIZER("*"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
49 ['+'] = STR_STATIC_INITIALIZER("+"),
197
f35a81a465db str: preallocate "," string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 196
diff changeset
50 [','] = STR_STATIC_INITIALIZER(","),
194
4b12a5cec16b str: preallocate "-" string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 193
diff changeset
51 ['-'] = STR_STATIC_INITIALIZER("-"),
230
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
52 ['-'] = STR_STATIC_INITIALIZER("-"),
193
f377dd66ddb4 str: preallocate "." string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 192
diff changeset
53 ['.'] = STR_STATIC_INITIALIZER("."),
195
f02f6cd40052 str: preallocate "/" string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 194
diff changeset
54 ['/'] = STR_STATIC_INITIALIZER("/"),
230
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
55 [':'] = STR_STATIC_INITIALIZER(":"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
56 [';'] = STR_STATIC_INITIALIZER(";"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
57 ['<'] = STR_STATIC_INITIALIZER("<"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
58 ['='] = STR_STATIC_INITIALIZER("="),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
59 ['>'] = STR_STATIC_INITIALIZER(">"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
60 ['?'] = STR_STATIC_INITIALIZER("?"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
61 ['@'] = STR_STATIC_INITIALIZER("@"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
62 ['['] = STR_STATIC_INITIALIZER("["),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
63 [']'] = STR_STATIC_INITIALIZER("]"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
64 ['^'] = STR_STATIC_INITIALIZER("^"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
65 ['_'] = STR_STATIC_INITIALIZER("_"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
66 ['`'] = STR_STATIC_INITIALIZER("`"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
67 ['{'] = STR_STATIC_INITIALIZER("{"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
68 ['|'] = STR_STATIC_INITIALIZER("|"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
69 ['}'] = STR_STATIC_INITIALIZER("}"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
70 ['~'] = STR_STATIC_INITIALIZER("~"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
71
198
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
72 ['0'] = STR_STATIC_INITIALIZER("0"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
73 ['1'] = STR_STATIC_INITIALIZER("1"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
74 ['2'] = STR_STATIC_INITIALIZER("2"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
75 ['3'] = STR_STATIC_INITIALIZER("3"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
76 ['4'] = STR_STATIC_INITIALIZER("4"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
77 ['5'] = STR_STATIC_INITIALIZER("5"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
78 ['6'] = STR_STATIC_INITIALIZER("6"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
79 ['7'] = STR_STATIC_INITIALIZER("7"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
80 ['8'] = STR_STATIC_INITIALIZER("8"),
dc5dc389d0d2 str: preallocate "0" .. "9" strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 197
diff changeset
81 ['9'] = STR_STATIC_INITIALIZER("9"),
230
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
82
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
83 ['A'] = STR_STATIC_INITIALIZER("A"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
84 ['B'] = STR_STATIC_INITIALIZER("B"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
85 ['C'] = STR_STATIC_INITIALIZER("C"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
86 ['D'] = STR_STATIC_INITIALIZER("D"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
87 ['E'] = STR_STATIC_INITIALIZER("E"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
88 ['F'] = STR_STATIC_INITIALIZER("F"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
89 ['G'] = STR_STATIC_INITIALIZER("G"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
90 ['H'] = STR_STATIC_INITIALIZER("H"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
91 ['I'] = STR_STATIC_INITIALIZER("I"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
92 ['J'] = STR_STATIC_INITIALIZER("J"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
93 ['K'] = STR_STATIC_INITIALIZER("K"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
94 ['L'] = STR_STATIC_INITIALIZER("L"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
95 ['M'] = STR_STATIC_INITIALIZER("M"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
96 ['N'] = STR_STATIC_INITIALIZER("N"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
97 ['O'] = STR_STATIC_INITIALIZER("O"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
98 ['P'] = STR_STATIC_INITIALIZER("P"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
99 ['Q'] = STR_STATIC_INITIALIZER("Q"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
100 ['R'] = STR_STATIC_INITIALIZER("R"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
101 ['S'] = STR_STATIC_INITIALIZER("S"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
102 ['T'] = STR_STATIC_INITIALIZER("T"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
103 ['U'] = STR_STATIC_INITIALIZER("U"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
104 ['V'] = STR_STATIC_INITIALIZER("V"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
105 ['W'] = STR_STATIC_INITIALIZER("W"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
106 ['X'] = STR_STATIC_INITIALIZER("X"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
107 ['Y'] = STR_STATIC_INITIALIZER("Y"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
108 ['Z'] = STR_STATIC_INITIALIZER("Z"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
109
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
110 ['a'] = STR_STATIC_INITIALIZER("a"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
111 ['b'] = STR_STATIC_INITIALIZER("b"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
112 ['c'] = STR_STATIC_INITIALIZER("c"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
113 ['d'] = STR_STATIC_INITIALIZER("d"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
114 ['e'] = STR_STATIC_INITIALIZER("e"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
115 ['f'] = STR_STATIC_INITIALIZER("f"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
116 ['g'] = STR_STATIC_INITIALIZER("g"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
117 ['h'] = STR_STATIC_INITIALIZER("h"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
118 ['i'] = STR_STATIC_INITIALIZER("i"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
119 ['j'] = STR_STATIC_INITIALIZER("j"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
120 ['k'] = STR_STATIC_INITIALIZER("k"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
121 ['l'] = STR_STATIC_INITIALIZER("l"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
122 ['m'] = STR_STATIC_INITIALIZER("m"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
123 ['n'] = STR_STATIC_INITIALIZER("n"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
124 ['o'] = STR_STATIC_INITIALIZER("o"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
125 ['p'] = STR_STATIC_INITIALIZER("p"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
126 ['q'] = STR_STATIC_INITIALIZER("q"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
127 ['r'] = STR_STATIC_INITIALIZER("r"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
128 ['s'] = STR_STATIC_INITIALIZER("s"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
129 ['t'] = STR_STATIC_INITIALIZER("t"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
130 ['u'] = STR_STATIC_INITIALIZER("u"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
131 ['v'] = STR_STATIC_INITIALIZER("v"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
132 ['w'] = STR_STATIC_INITIALIZER("w"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
133 ['x'] = STR_STATIC_INITIALIZER("x"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
134 ['y'] = STR_STATIC_INITIALIZER("y"),
6c9d77cf8c1e str: preallocate more single-char strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 228
diff changeset
135 ['z'] = STR_STATIC_INITIALIZER("z"),
192
94c9db63f1c3 str: preallocate " " string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 191
diff changeset
136 };
191
626a2d545bbe str: allow simple static preallocation of one-char long strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 190
diff changeset
137
159
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
138 static struct mem_cache *str_cache;
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
139
174
532cbad2de95 init: mark val and str subsystem init functions as constructors
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 165
diff changeset
140 static void __attribute__((constructor)) init_str_subsys(void)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
141 {
159
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
142 str_cache = mem_cache_create("str-cache", sizeof(struct str), 0);
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
143 ASSERT(!IS_ERR(str_cache));
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
144 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
145
224
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
146 static struct str *__get_preallocated(const char *s)
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
147 {
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
148 unsigned char first_char;
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
149
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
150 /* NULL or empty string */
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
151 if (!s || (s[0] == '\0'))
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
152 return &empty_string;
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
153
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
154 first_char = s[0];
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
155
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
156 /* preallocated one-char long strings of 7-bit ASCII */
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
157 if ((first_char > '\0') && (first_char < '\x7f') &&
227
32fc570177ef str: rename static_alloc to static_struct
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 226
diff changeset
158 (s[1] == '\0') && one_char[first_char].static_struct)
224
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
159 return &one_char[first_char];
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
160
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
161 /* nothing pre-allocated */
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
162 return NULL;
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
163 }
eabb98107cba str: move preallocation lookups into a helper function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 198
diff changeset
164
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
165 static struct str *__alloc(char *s, bool heapalloc, bool mustdup)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
166 {
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
167 struct str *str;
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
168 bool copy;
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
169
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
170 /* sanity check */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
171 if (mustdup)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
172 ASSERT(!heapalloc);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
173
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
174 /* check preallocated strings */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
175 str = __get_preallocated(s);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
176 if (str)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
177 goto out;
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
178
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
179 /* can we inline it? */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
180 copy = (strlen(s) <= STR_INLINE_LEN);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
181
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
182 /* we'll be storing a pointer - strdup as necessary */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
183 if (!copy && mustdup) {
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
184 s = strdup(s);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
185 if (!s)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
186 goto out;
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
187
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
188 /* we're now using the heap */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
189 heapalloc = true;
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
190 }
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
191
159
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
192 str = mem_cache_alloc(str_cache);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
193 if (!str)
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
194 goto out;
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
195
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
196 refcnt_init(&str->refcnt, 1);
227
32fc570177ef str: rename static_alloc to static_struct
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 226
diff changeset
197 str->static_struct = false;
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
198 str->static_alloc = copy || !heapalloc;
165
cae007c76340 str: use a union and a flag to save str space
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 162
diff changeset
199 str->inline_alloc = copy;
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
200
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
201 if (copy) {
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
202 strcpy(str->inline_str, s);
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
203 if (heapalloc)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
204 free(s);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
205 } else {
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
206 str->str = s;
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
207 }
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
208
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
209 return str;
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
210
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
211 out:
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
212 if (heapalloc)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
213 free(s);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
214
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
215 return str;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
216 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
217
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
218 /*
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
219 * Passed in str cannot be freed, and it must be dup'd. (E.g., it could be
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
220 * a string on the stack.)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
221 */
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
222 struct str *str_dup(const char *s)
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
223 {
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
224 return __alloc((char *) s, false, true);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
225 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
226
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
227 /* Passed in str must be freed. */
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
228 struct str *str_alloc(char *s)
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
229 {
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
230 return __alloc(s, true, false);
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
231 }
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
232
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
233 /*
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
234 * Passed in str cannot be freed, and it doesn't have to be dup'd. (E.g.,
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
235 * it could be a string in .rodata.)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
236 */
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
237 struct str *str_alloc_static(const char *s)
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
238 {
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
239 return __alloc((char *) s, false, false);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
240 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
241
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
242 size_t str_len(const struct str *s)
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
243 {
165
cae007c76340 str: use a union and a flag to save str space
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 162
diff changeset
244 return strlen(str_cstr(s));
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
245 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
246
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
247 int str_cmp(const struct str *a, const struct str *b)
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
248 {
165
cae007c76340 str: use a union and a flag to save str space
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 162
diff changeset
249 return strcmp(str_cstr(a), str_cstr(b));
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
250 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
251
232
7b1c311a77e4 str: the number of strings passed to str_cat() should be a size_t
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 230
diff changeset
252 struct str *str_cat(size_t n, ...)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
253 {
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
254 size_t totallen;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
255 struct str *ret;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
256 char *buf, *out;
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
257 size_t *len;
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
258 va_list ap;
232
7b1c311a77e4 str: the number of strings passed to str_cat() should be a size_t
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 230
diff changeset
259 size_t i;
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
260
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
261 if (!n)
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
262 return NULL;
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
263
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
264 if (n == 1) {
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
265 va_start(ap, n);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
266 ret = va_arg(ap, struct str *);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
267 va_end(ap);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
268 return ret;
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
269 }
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
270
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
271 totallen = 0;
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
272 len = alloca(sizeof(size_t) * n);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
273
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
274 va_start(ap, n);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
275 for (i = 0; i < n; i++) {
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
276 struct str *str = va_arg(ap, struct str *);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
277
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
278 if (!str)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
279 continue;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
280
165
cae007c76340 str: use a union and a flag to save str space
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 162
diff changeset
281 len[i] = strlen(str_cstr(str));
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
282
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
283 totallen += len[i];
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
284 }
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
285 va_end(ap);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
286
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
287 buf = malloc(totallen + 1);
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
288 ASSERT(buf);
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
289
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
290 out = buf;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
291
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
292 va_start(ap, n);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
293 for (i = 0; i < n; i++) {
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
294 struct str *str = va_arg(ap, struct str *);
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
295
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
296 if (!str)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
297 continue;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
298
165
cae007c76340 str: use a union and a flag to save str space
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 162
diff changeset
299 strcpy(out, str_cstr(str));
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
300
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
301 out += len[i];
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
302
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
303 str_putref(str);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
304 }
41
ce17740b7bf2 str: str_cat should handle unlimited number of arguments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
305 va_end(ap);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
306
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
307 ret = str_alloc(buf);
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
308 ASSERT(ret);
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
309
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
310 return ret;
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
311 }
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
312
120
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
313 struct str *str_vprintf(const char *fmt, va_list args)
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
314 {
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
315 char *tmp;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
316 int ret;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
317
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
318 ret = vasprintf(&tmp, fmt, args);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
319 if (ret < 0)
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
320 return ERR_PTR(-errno);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
321 if (ret == 0)
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
322 return NULL;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
323
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
324 return STR_ALLOC(tmp);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
325 }
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
326
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
327 struct str *str_printf(const char *fmt, ...)
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
328 {
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
329 struct str *ret;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
330 va_list args;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
331
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
332 va_start(args, fmt);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
333 ret = str_vprintf(fmt, args);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
334 va_end(args);
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
335
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
336 return ret;
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
337 }
b43b8fc87c0b str: introduce str_printf and str_vprintf
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 67
diff changeset
338
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
339 void str_free(struct str *str)
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
340 {
257
068955620d10 str: str_free(NULL) should assert
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 232
diff changeset
341 ASSERT(str);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
342 ASSERT3U(refcnt_read(&str->refcnt), ==, 0);
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
343
228
2ffb2b971149 str: add support for static strings
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 227
diff changeset
344 if (!str->inline_alloc && !str->static_alloc)
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
345 free(str->str);
159
59d3f2a362a9 str: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 155
diff changeset
346 mem_cache_free(str_cache, str);
6
4317d47b267f str: a reference counted string
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
347 }