]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - error2.c
build: Replace error2.pl by error2.c.
[paraslash.git] / error2.c
diff --git a/error2.c b/error2.c
new file mode 100644 (file)
index 0000000..630d4c7
--- /dev/null
+++ b/error2.c
@@ -0,0 +1,151 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <ctype.h>
+
+// #define DEBUG
+#ifdef DEBUG
+       #define log(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)
+#else
+       #define log(...) do {;} while (0)
+#endif /* DEBUG*/
+
+#define HASH_TABLE_BITS 8
+#define HASH_TABLE_SIZE (1 << HASH_TABLE_BITS)
+
+/* number of executables seen so far */
+static int num_exe;
+
+struct hash_table_entry {
+       char *key;
+       /* only used for objecs, not for executables */
+       unsigned exe_bitmask;
+};
+
+static struct hash_table_entry exe_table[HASH_TABLE_SIZE];
+static struct hash_table_entry obj_table[HASH_TABLE_SIZE];
+
+/* no need for anything sophisticated here */
+static int hash_token(const char *tok)
+{
+       uint32_t tmp = 31415927;
+       const uint8_t *src = (typeof(src))tok;
+
+       for (; *src; src++) {
+               tmp *= 27182817;
+               tmp += *tok;
+       }
+       return tmp % HASH_TABLE_SIZE;
+}
+
+static inline bool slot_empty(int idx, struct hash_table_entry *table)
+{
+       return table[idx].key == NULL;
+}
+
+static char *safe_strdup(const char *str)
+{
+       char *result = strdup(str);
+       if (result)
+               return result;
+       errno = ENOMEM;
+       perror("strdup");
+       exit(EXIT_FAILURE);
+}
+
+static bool lookup(const char *tok, struct hash_table_entry *table, int *idx)
+{
+       int i, h = hash_token(tok);
+
+       for (i = 0; i < HASH_TABLE_SIZE; i++) {
+               *idx = (h + i) % HASH_TABLE_SIZE;
+               if (slot_empty(*idx, table))
+                       return false;
+               if (!strcmp(table[*idx].key, tok))
+                       return true;
+       }
+       log ("hash table full !?\n");
+       exit(EXIT_FAILURE);
+}
+
+static bool insert(const char *tok, struct hash_table_entry *table, int *idx)
+{
+       if (lookup(tok, table, idx))
+               return false; /* not inserted */
+       table[*idx].key = safe_strdup(tok);
+       return true;
+}
+
+static void process_token(char *tok)
+{
+       int idx;
+       size_t len = strlen(tok);
+
+       assert(len > 0);
+       if (tok[len - 1] == ':') {
+               tok[len - 1] = '\0';
+               if (insert(tok, exe_table, &idx)) { /* new exe */
+                       log("exe #%d: '%s', idx: %d\n", num_exe, tok, idx);
+                       num_exe++;
+               }
+       } else {
+               if (num_exe == 0) {
+                       log("invalid input\n");
+                       exit(EXIT_FAILURE);
+               }
+               insert(tok, obj_table, &idx);
+               obj_table[idx].exe_bitmask |= (1 << (num_exe - 1));
+       }
+}
+
+static void print_ss_enum(int idx)
+{
+       char *s = obj_table[idx].key;
+
+       printf("SS_ENUM(");
+       for (; *s; s++)
+               printf("%c", toupper(*s));
+       printf(");\n");
+}
+
+static void dump_bipolar(void)
+{
+       int i, j;
+
+       for (i = 0; i < HASH_TABLE_SIZE; i++) {
+               if (slot_empty(i, obj_table))
+                       continue;
+               printf("#ifdef MAIN_INPUT_FILE_IS_%s\n", obj_table[i].key);
+               for (j = 0; j < HASH_TABLE_SIZE; j++) {
+                       unsigned mi, mj;
+                       if (slot_empty(j, obj_table))
+                               continue;
+                       mi = obj_table[i].exe_bitmask;
+                       mj = obj_table[j].exe_bitmask;
+                       if ((mi & mj) == mi)
+                               print_ss_enum(j);
+               }
+               printf("#endif\n");
+       }
+}
+
+int main(void)
+{
+       int ret;
+
+       for (;;) {
+               char tok[100];
+               ret = scanf("%96s", tok);
+               if (ret != 1)
+                       break;
+               process_token(tok);
+       }
+       dump_bipolar();
+       return 0;
+}