]> git.sur5r.net Git - i3/i3/blob - libi3/format_placeholders.c
travis: check spelling of binaries and manpages, use docker
[i3/i3] / libi3 / format_placeholders.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  */
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 #include "libi3.h"
13
14 #ifndef STARTS_WITH
15 #define STARTS_WITH(string, needle) (strncasecmp((string), (needle), strlen((needle))) == 0)
16 #endif
17
18 /*
19  * Replaces occurrences of the defined placeholders in the format string.
20  *
21  */
22 char *format_placeholders(char *format, placeholder_t *placeholders, int num) {
23     if (format == NULL)
24         return NULL;
25
26     /* We have to first iterate over the string to see how much buffer space
27      * we need to allocate. */
28     int buffer_len = strlen(format) + 1;
29     for (char *walk = format; *walk != '\0'; walk++) {
30         for (int i = 0; i < num; i++) {
31             if (!STARTS_WITH(walk, placeholders[i].name))
32                 continue;
33
34             buffer_len = buffer_len - strlen(placeholders[i].name) + strlen(placeholders[i].value);
35             walk += strlen(placeholders[i].name) - 1;
36             break;
37         }
38     }
39
40     /* Now we can parse the format string. */
41     char buffer[buffer_len];
42     char *outwalk = buffer;
43     for (char *walk = format; *walk != '\0'; walk++) {
44         if (*walk != '%') {
45             *(outwalk++) = *walk;
46             continue;
47         }
48
49         bool matched = false;
50         for (int i = 0; i < num; i++) {
51             if (!STARTS_WITH(walk, placeholders[i].name)) {
52                 continue;
53             }
54
55             matched = true;
56             outwalk += sprintf(outwalk, "%s", placeholders[i].value);
57             walk += strlen(placeholders[i].name) - 1;
58             break;
59         }
60
61         if (!matched)
62             *(outwalk++) = *walk;
63     }
64
65     *outwalk = '\0';
66     return sstrdup(buffer);
67 }