-/*
- * Copyright (C) 2013 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file error2.c Simple program to create error2.h. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <inttypes.h>
-#include <string.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");
- }
-}
-
-/**
- * The main function of error2.c.
- *
- * The purpose of this program is to create the error2.h file which defines the
- * enumerations of all error codes which may be used by any given .c file. This
- * header is included by most .c files of the paraslash suite.
- *
- * Since this program is executed on the build system, it must be compiled with
- * the host compiler.
- *
- * \return \p EXIT_SUCCESS or \p EXIT_FAILURE.
- */
-int main(void)
-{
- int ret;
-
- for (;;) {
- char tok[100];
- ret = scanf("%96s", tok);
- if (ret != 1)
- break;
- process_token(tok);
- }
- dump_bipolar();
- return 0;
-}