/* $Id: modtbl.c,v 1.4 2004/03/25 00:06:14 jmuelmen Exp $ */ /* Helper functions for maintining the mapping of module names onto board/channel */ #include #include #include #include #include "mod_tbl.h" #include "log.h" char board_name[BOARD_NAME_LEN]; #define N_MOD 1000 #define SURF_MOD_LOCK \ do { \ if (pthread_mutex_lock(&_surf_mod_mut)) \ perror("Locking module table"); \ } while (0) #define SURF_MOD_UNLOCK \ do { \ if (pthread_mutex_unlock(&_surf_mod_mut)) \ perror("Unlocking module table"); \ } while (0) static pthread_mutex_t _surf_mod_mut; int surf_mod_init () { pthread_mutex_init(&_surf_mod_mut, NULL); return 0; } static int _n = 0; static struct mod_tbl_ent _mods[N_MOD]; void mod_tbl_set_input (FILE *f); int mod_yyparse(); /* This routine compares a string (k) to a module serial number board (m is a struct mod_tbl_ent *); it's only used by bsearch to find modules in the list. */ static int mod_compar_search (const void *k, const void *m) { const char *key = (const char *)k; const struct mod_tbl_ent *mod = (const struct mod_tbl_ent *)m; return strncmp(key, mod_tbl_get_name(mod), MOD_NAME_LEN); } /* This routine compares two struct mod_tbl_ent *s; it does so by comparing the modules names of each struct mod_tbl_ent *. It's only used by qsort to tidy up the list of modules. */ static int mod_compar_sort (const void *a, const void *b) { const struct mod_tbl_ent *mod1 = (const struct mod_tbl_ent *)a; const struct mod_tbl_ent *mod2 = (const struct mod_tbl_ent *)b; return strncmp(mod_tbl_get_name(mod1), mod_tbl_get_name(mod2), MOD_NAME_LEN); } /* search the module list for the module with the serial number given by key */ static struct mod_tbl_ent *mod_tbl_search (const char *key) { /* this function is called by locking functions */ struct mod_tbl_ent *ret; ret = bsearch(key, _mods, _n, sizeof(struct mod_tbl_ent), mod_compar_search); return ret; } struct mod_tbl_ent *mod_tbl_find (const char *key) { /* this function needs to be locking */ struct mod_tbl_ent *ret; SURF_MOD_LOCK; ret = mod_tbl_search(key); SURF_MOD_UNLOCK; return ret; } /* sort the module list by serial number */ static void mod_tbl_sort () { qsort(_mods, _n, sizeof(struct mod_tbl_ent), mod_compar_sort); } static struct mod_tbl_ent *mod_tbl_create () { if (_n == N_MOD) return NULL; return &_mods[_n++]; } void mod_tbl_set_name (struct mod_tbl_ent *m, const char *name) { strncpy(m->mod_name, name, MOD_NAME_LEN); m->mod_name[MOD_NAME_LEN - 1] = 0; } struct mod_tbl_ent *mod_tbl_add (const char *name) { struct mod_tbl_ent *m; if (!(m = mod_tbl_search(name))) { m = mod_tbl_create(); mod_tbl_set_name(m, name); /* printf("Made new module, sorting.\n"); */ mod_tbl_sort(); m = mod_tbl_search(name); } return m; } void mod_tbl_set_board (struct mod_tbl_ent *m, const char *name) { strncpy(m->board_name, name, BOARD_NAME_LEN); m->board_name[BOARD_NAME_LEN - 1] = 0; /* printf("Set board of %s to %s\n", m->mod_name, m->board_name); */ } void mod_tbl_set_chan (struct mod_tbl_ent *m, int i) { m->chan = i; /* printf("Set channel of %s to %d\n", m->mod_name, m->chan); */ } const char *mod_tbl_get_name (const struct mod_tbl_ent *m) { return m->mod_name; } const char *mod_tbl_get_board (const struct mod_tbl_ent *m) { return m->board_name; } int mod_tbl_get_chan (const struct mod_tbl_ent *m) { return m->chan; } int surf_load_mod_tbl (const char *file) { FILE *f = fopen(file, "r"); SURF_MOD_LOCK; if (!f) { perror(file); SURF_MOD_UNLOCK; return -1; } mod_tbl_set_input(f); mod_yyparse(); SURF_MOD_UNLOCK; /* snatch the log files before someone else does */ return log_sync(); } void surf_print_mods () { int i; SURF_MOD_LOCK; for (i = 0; i < _n; ++i) { struct mod_tbl_ent *m = &_mods[i]; printf("%s\t%d\t%s\n", m->board_name, m->chan, m->mod_name); }; SURF_MOD_UNLOCK; } int surf_mod_tbl_get_mod (char *name, int i) { SURF_MOD_LOCK; if (i >= _n) { *name = 0; SURF_MOD_UNLOCK; return 1; } strcpy(name, _mods[i].mod_name); SURF_MOD_UNLOCK; return 0; }