From: Andre Noll Date: Fri, 13 Sep 2013 01:41:15 +0000 (+0000) Subject: build: Replace error2.pl by error2.c. X-Git-Tag: v0.5.1~1^2~50 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=e8f3104cc1c1f243f4b7c8b1eabdc24c93a6ad35 build: Replace error2.pl by error2.c. The C code is much faster than the old perl script. Since the resulting executable runs on the build system, the compiler for this system must be called to compile error2.c. The new HOSTCC variable takes care of this. With this patch applied, the only remaining dependencies on perl are help2man and autoconf. --- diff --git a/Makefile.in b/Makefile.in index c500fb9e..4160d257 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,8 +9,11 @@ PACKAGE_VERSION := @PACKAGE_VERSION@ PACKAGE_STRING := @PACKAGE_STRING@ INSTALL := @install@ STRIP := $(CROSS_COMPILE)strip +HOSTCC ?= cc executables := $(addprefix para_, @executables@) ggo_descriptions_declared := @ggo_descriptions_declared@ +object_executable_matrix := @object_executable_matrix@ + GENGETOPT := @gengetopt@ HELP2MAN := @help2man@ @@ -37,6 +40,7 @@ man_dir := $(build_dir)/man/man1 cmdline_dir := $(build_dir)/cmdline m4depdir := $(build_dir)/m4deps help2man_dir := $(build_dir)/help2man +hostbin_dir := $(build_dir)/host/bin DEBUG_CPPFLAGS += -g -Wunused -Wundef -W DEBUG_CPPFLAGS += -Wredundant-decls @@ -106,7 +110,7 @@ man: $(man_pages) tarball: $(tarball) $(object_dir) $(man_dir) $(ggo_dir) $(cmdline_dir) $(dep_dir) $(m4depdir) \ - $(help2man_dir): + $(help2man_dir) $(hostbin_dir): $(Q) $(MKDIR_P) $@ -include $(m4_ggo_dir)/makefile @@ -153,6 +157,12 @@ $(man_dir)/%.1: $(help2man_dir)/% | $(man_dir) @[ -z "$(Q)" ] || echo 'MAN $<' $(Q) $(HELP2MAN) -N ./$< > $@ +$(hostbin_dir)/error2: error2.c | $(hostbin_dir) + @[ -z "$(Q)" ] || echo 'HCC $<' + $(Q) $(HOSTCC) -o $@ $< +error2.h: $(hostbin_dir)/error2 + @[ -z "$(Q)" ] || echo 'ER2 $<' + @echo "$(object_executable_matrix)" | $< > $@ $(object_dir)/crypt.o: crypt.c | $(object_dir) @[ -z "$(Q)" ] || echo 'CC $<' $(Q) $(CC) -c -o $@ $(CPPFLAGS) $(DEBUG_CPPFLAGS) @openssl_cppflags@ $< diff --git a/configure.ac b/configure.ac index 9927c60d..dec0636f 100644 --- a/configure.ac +++ b/configure.ac @@ -1332,8 +1332,6 @@ else AC_MSG_WARN([no curses lib, cannot build para_gui]) fi ############################################################# error2.h -AC_MSG_NOTICE(creating error2.h) - # these are always built all_errlist_objs=" $recv_errlist_objs @@ -1363,10 +1361,14 @@ fi all_errlist_objs="$(echo $all_errlist_objs | tr ' ' '\n' | sort | uniq)" +object_executable_matrix= for i in $executables; do - echo "$i: " - eval echo \$${i}_errlist_objs -done | ./error2.pl > error2.h + eval objs=\$${i}_errlist_objs + object_executable_matrix="$object_executable_matrix $i: $objs" +done +# use echo to replace newlines by space +AC_SUBST(object_executable_matrix, $(echo $object_executable_matrix)) + for obj in $all_errlist_objs; do SS="$SS SS_$(echo $obj | tr 'a-z' 'A-Z')," done @@ -1374,7 +1376,6 @@ AC_DEFINE_UNQUOTED(DEFINE_ERRLIST_OBJECT_ENUM, [enum {$SS NUM_SS}], [list of all objects that use the paraslash error facility] ) - ################################################################## status items status_items="basename status num_played mtime bitrate frequency file_size diff --git a/error2.c b/error2.c new file mode 100644 index 00000000..630d4c71 --- /dev/null +++ b/error2.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #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; +} diff --git a/error2.pl b/error2.pl deleted file mode 100755 index 78ff2c56..00000000 --- a/error2.pl +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env perl - -use warnings; -use strict; - -my %matrix; -my @executables; -my %objects; - -sub make_matrix -{ - my ($line, $e, @fields, $field); - - while (defined($line = <>)) { - chomp($line); - if ($line =~ "^ *\$") { - next; - } - @fields = split(" ", $line); - while (defined(($field = shift(@fields)))) { - if ($field =~ ":\$") { - $field =~ s/://; - $e = $field; - push(@executables, $e); - next; - } - $matrix{$e . ">" . $field} = 1; - $objects{$field} = 1; - } - } -} - -sub print_safe_objects -{ - my @objs = keys(%objects); - my ($o1, $o2, $e); - - foreach $o1 (@objs) { - print("#ifdef MAIN_INPUT_FILE_IS_$o1\n"); - O2: foreach $o2 (@objs) { - foreach $e (@executables) { - if (!defined($matrix{$e . ">" . $o1})) { - next; - } - if (defined($matrix{$e . ">" . $o2})) { - next; - } - next O2; - } - $_ = $o2; - tr/a-z/A-Z/; - printf("SS_ENUM(%s);\n", $_); - } - print("#endif\n"); - } -} -make_matrix; -print_safe_objects;