]> git.sur5r.net Git - i3/i3/blob - libi3/string.c
Make comment style more consistent
[i3/i3] / libi3 / string.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * string.c: Define an i3String type to automagically handle UTF-8/UCS-2
8  *           conversions. Some font backends need UCS-2 (X core fonts),
9  *           others want UTF-8 (Pango).
10  *
11  */
12 #include "libi3.h"
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include <glib.h>
18
19 struct _i3String {
20     char *utf8;
21     xcb_char2b_t *ucs2;
22     size_t num_glyphs;
23     size_t num_bytes;
24     bool pango_markup;
25 };
26
27 /*
28  * Build an i3String from an UTF-8 encoded string.
29  * Returns the newly-allocated i3String.
30  *
31  */
32 i3String *i3string_from_utf8(const char *from_utf8) {
33     return i3string_from_utf8_with_length(from_utf8, -1);
34 }
35
36 /*
37  * Build an i3String from an UTF-8 encoded string in Pango markup.
38  *
39  */
40 i3String *i3string_from_markup(const char *from_markup) {
41     i3String *str = i3string_from_utf8(from_markup);
42
43     /* Set the markup flag */
44     str->pango_markup = true;
45
46     return str;
47 }
48
49 /*
50  * Build an i3String from an UTF-8 encoded string with fixed length.
51  * To be used when no proper NULL-termination is available.
52  * Returns the newly-allocated i3String.
53  *
54  */
55 i3String *i3string_from_utf8_with_length(const char *from_utf8, ssize_t num_bytes) {
56     i3String *str = scalloc(1, sizeof(i3String));
57
58     /* g_utf8_make_valid NULL-terminates the string. */
59     str->utf8 = g_utf8_make_valid(from_utf8, num_bytes);
60
61     /* num_bytes < 0 means NULL-terminated string, need to calculate length */
62     str->num_bytes = num_bytes < 0 ? strlen(str->utf8) : (size_t)num_bytes;
63
64     return str;
65 }
66
67 /*
68  * Build an i3String from an UTF-8 encoded string in Pango markup with fixed
69  * length.
70  *
71  */
72 i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes) {
73     i3String *str = i3string_from_utf8_with_length(from_markup, num_bytes);
74
75     /* set the markup flag */
76     str->pango_markup = true;
77
78     return str;
79 }
80
81 /*
82  * Build an i3String from an UCS-2 encoded string.
83  * Returns the newly-allocated i3String.
84  *
85  */
86 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
87     i3String *str = scalloc(1, sizeof(i3String));
88
89     /* Copy the actual text to our i3String */
90     str->ucs2 = scalloc(num_glyphs, sizeof(xcb_char2b_t));
91     memcpy(str->ucs2, from_ucs2, num_glyphs * sizeof(xcb_char2b_t));
92
93     /* Store the length */
94     str->num_glyphs = num_glyphs;
95
96     str->utf8 = NULL;
97     str->num_bytes = 0;
98
99     return str;
100 }
101
102 /*
103  * Copies the given i3string.
104  * Note that this will not free the source string.
105  */
106 i3String *i3string_copy(i3String *str) {
107     i3String *copy = i3string_from_utf8(i3string_as_utf8(str));
108     copy->pango_markup = str->pango_markup;
109     return copy;
110 }
111
112 /*
113  * Free an i3String.
114  *
115  */
116 void i3string_free(i3String *str) {
117     if (str == NULL)
118         return;
119     free(str->utf8);
120     free(str->ucs2);
121     free(str);
122 }
123
124 static void i3string_ensure_utf8(i3String *str) {
125     if (str->utf8 != NULL)
126         return;
127     if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
128         str->num_bytes = strlen(str->utf8);
129 }
130
131 static void i3string_ensure_ucs2(i3String *str) {
132     if (str->ucs2 != NULL)
133         return;
134     str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
135 }
136
137 /*
138  * Returns the UTF-8 encoded version of the i3String.
139  *
140  */
141 const char *i3string_as_utf8(i3String *str) {
142     i3string_ensure_utf8(str);
143     return str->utf8;
144 }
145
146 /*
147  * Returns the UCS-2 encoded version of the i3String.
148  *
149  */
150 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
151     i3string_ensure_ucs2(str);
152     return str->ucs2;
153 }
154
155 /*
156  * Returns the number of bytes (UTF-8 encoded) in an i3String.
157  *
158  */
159 size_t i3string_get_num_bytes(i3String *str) {
160     i3string_ensure_utf8(str);
161     return str->num_bytes;
162 }
163
164 /*
165  * Whether the given i3String is in Pango markup.
166  */
167 bool i3string_is_markup(i3String *str) {
168     return str->pango_markup;
169 }
170
171 /*
172  * Set whether the i3String should use Pango markup.
173  */
174 void i3string_set_markup(i3String *str, bool pango_markup) {
175     str->pango_markup = pango_markup;
176 }
177
178 /*
179  * Escape pango markup characters in the given string.
180  */
181 i3String *i3string_escape_markup(i3String *str) {
182     const char *text = i3string_as_utf8(str);
183     char *escaped = g_markup_escape_text(text, -1);
184     i3String *result = i3string_from_utf8(escaped);
185     free(escaped);
186     return result;
187 }
188
189 /*
190  * Returns the number of glyphs in an i3String.
191  *
192  */
193 size_t i3string_get_num_glyphs(i3String *str) {
194     i3string_ensure_ucs2(str);
195     return str->num_glyphs;
196 }