gui: Simplify display command execution.
[paraslash.git] / error2.c
1 /*
2 * Copyright (C) 2013-2014 Andre Noll <maan@systemlinux.org>
3 *
4 * Licensed under the GPL v2. For licencing details see COPYING.
5 */
6
7 /** \file error2.c Simple program to create error2.h. */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <assert.h>
12 #include <assert.h>
13 #include <inttypes.h>
14 #include <string.h>
15 #include <stdbool.h>
16 #include <stdbool.h>
17 #include <errno.h>
18 #include <ctype.h>
19
20 // #define DEBUG
21 #ifdef DEBUG
22 #define log(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)
23 #else
24 #define log(...) do {;} while (0)
25 #endif /* DEBUG*/
26
27 #define HASH_TABLE_BITS 8
28 #define HASH_TABLE_SIZE (1 << HASH_TABLE_BITS)
29
30 /* number of executables seen so far */
31 static int num_exe;
32
33 struct hash_table_entry {
34 char *key;
35 /* only used for objecs, not for executables */
36 unsigned exe_bitmask;
37 };
38
39 static struct hash_table_entry exe_table[HASH_TABLE_SIZE];
40 static struct hash_table_entry obj_table[HASH_TABLE_SIZE];
41
42 /* no need for anything sophisticated here */
43 static int hash_token(const char *tok)
44 {
45 uint32_t tmp = 31415927;
46 const uint8_t *src = (typeof(src))tok;
47
48 for (; *src; src++) {
49 tmp *= 27182817;
50 tmp += *tok;
51 }
52 return tmp % HASH_TABLE_SIZE;
53 }
54
55 static inline bool slot_empty(int idx, struct hash_table_entry *table)
56 {
57 return table[idx].key == NULL;
58 }
59
60 static char *safe_strdup(const char *str)
61 {
62 char *result = strdup(str);
63 if (result)
64 return result;
65 errno = ENOMEM;
66 perror("strdup");
67 exit(EXIT_FAILURE);
68 }
69
70 static bool lookup(const char *tok, struct hash_table_entry *table, int *idx)
71 {
72 int i, h = hash_token(tok);
73
74 for (i = 0; i < HASH_TABLE_SIZE; i++) {
75 *idx = (h + i) % HASH_TABLE_SIZE;
76 if (slot_empty(*idx, table))
77 return false;
78 if (!strcmp(table[*idx].key, tok))
79 return true;
80 }
81 log ("hash table full !?\n");
82 exit(EXIT_FAILURE);
83 }
84
85 static bool insert(const char *tok, struct hash_table_entry *table, int *idx)
86 {
87 if (lookup(tok, table, idx))
88 return false; /* not inserted */
89 table[*idx].key = safe_strdup(tok);
90 return true;
91 }
92
93 static void process_token(char *tok)
94 {
95 int idx;
96 size_t len = strlen(tok);
97
98 assert(len > 0);
99 if (tok[len - 1] == ':') {
100 tok[len - 1] = '\0';
101 if (insert(tok, exe_table, &idx)) { /* new exe */
102 log("exe #%d: '%s', idx: %d\n", num_exe, tok, idx);
103 num_exe++;
104 }
105 } else {
106 if (num_exe == 0) {
107 log("invalid input\n");
108 exit(EXIT_FAILURE);
109 }
110 insert(tok, obj_table, &idx);
111 obj_table[idx].exe_bitmask |= (1 << (num_exe - 1));
112 }
113 }
114
115 static void print_ss_enum(int idx)
116 {
117 char *s = obj_table[idx].key;
118
119 printf("SS_ENUM(");
120 for (; *s; s++)
121 printf("%c", toupper(*s));
122 printf(");\n");
123 }
124
125 static void dump_bipolar(void)
126 {
127 int i, j;
128
129 for (i = 0; i < HASH_TABLE_SIZE; i++) {
130 if (slot_empty(i, obj_table))
131 continue;
132 printf("#ifdef MAIN_INPUT_FILE_IS_%s\n", obj_table[i].key);
133 for (j = 0; j < HASH_TABLE_SIZE; j++) {
134 unsigned mi, mj;
135 if (slot_empty(j, obj_table))
136 continue;
137 mi = obj_table[i].exe_bitmask;
138 mj = obj_table[j].exe_bitmask;
139 if ((mi & mj) == mi)
140 print_ss_enum(j);
141 }
142 printf("#endif\n");
143 }
144 }
145
146 /**
147 * The main function of error2.c.
148 *
149 * The purpose of this program is to create the error2.h file which defines the
150 * enumerations of all error codes which may be used by any given .c file. This
151 * header is included by most .c files of the paraslash suite.
152 *
153 * Since this program is executed on the build system, it must be compiled with
154 * the host compiler.
155 *
156 * \return \p EXIT_SUCCESS or \p EXIT_FAILURE.
157 */
158 int main(void)
159 {
160 int ret;
161
162 for (;;) {
163 char tok[100];
164 ret = scanf("%96s", tok);
165 if (ret != 1)
166 break;
167 process_token(tok);
168 }
169 dump_bipolar();
170 return 0;
171 }