1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* parser_util.c: utility functions for the config and commands parser
*
*/
#include "all.h"
#include "parser_util.h"
/*
* Pushes a string (identified by 'identifier') on the stack. We simply use a
* single array, since the number of entries we have to store is very small.
*
*/
void parser_push_string(struct stack *stack, const char *identifier, const char *str) {
for (int c = 0; c < 10; c++) {
if (stack->stack[c].identifier != NULL &&
strcmp(stack->stack[c].identifier, identifier) != 0) {
continue;
}
if (stack->stack[c].identifier == NULL) {
/* Found a free slot, let's store it here. */
stack->stack[c].identifier = identifier;
stack->stack[c].val.str = sstrdup(str);
stack->stack[c].type = STACK_STR;
} else {
/* Append the value. */
char *prev = stack->stack[c].val.str;
sasprintf(&stack->stack[c].val.str, "%s,%s", prev, str);
free(prev);
}
return;
}
/* When we arrive here, the stack is full. This should not happen and
* means there's either a bug in this parser or the specification
* contains a command with more than 10 identified tokens. */
fprintf(stderr, "BUG: parser stack full. This means either a bug "
"in the code, or a new command which contains more than "
"10 identified tokens.\n");
exit(EXIT_FAILURE);
}
void parser_push_long(struct stack *stack, const char *identifier, const long num) {
for (int c = 0; c < 10; c++) {
if (stack->stack[c].identifier != NULL) {
continue;
}
/* Found a free slot, let's store it here. */
stack->stack[c].identifier = identifier;
stack->stack[c].val.num = num;
stack->stack[c].type = STACK_LONG;
return;
}
/* When we arrive here, the stack is full. This should not happen and
* means there's either a bug in this parser or the specification
* contains a command with more than 10 identified tokens. */
fprintf(stderr, "BUG: parser stack full. This means either a bug "
"in the code, or a new command which contains more than "
"10 identified tokens.\n");
exit(EXIT_FAILURE);
}
const char *parser_get_string(const struct stack *stack, const char *identifier) {
for (int c = 0; c < 10; c++) {
if (stack->stack[c].identifier == NULL) {
break;
}
if (strcmp(identifier, stack->stack[c].identifier) == 0) {
return stack->stack[c].val.str;
}
}
return NULL;
}
long parser_get_long(const struct stack *stack, const char *identifier) {
for (int c = 0; c < 10; c++) {
if (stack->stack[c].identifier == NULL) {
break;
}
if (strcmp(identifier, stack->stack[c].identifier) == 0) {
return stack->stack[c].val.num;
}
}
return 0;
}
void parser_clear_stack(struct stack *stack) {
for (int c = 0; c < 10; c++) {
if (stack->stack[c].type == STACK_STR) {
free(stack->stack[c].val.str);
}
stack->stack[c].identifier = NULL;
stack->stack[c].val.str = NULL;
stack->stack[c].val.num = 0;
}
}
|