/* returns flag entry or 0 on not found */ inline static struct flag_entry* get_flag_entry(char* name, int len) { int h; /* get hash */ h=get_hash1_raw(name, len) & (FLAGS_NAME_HASH_ENTRIES-1); return flag_search(&name2flags[h], name, len); }
/* resgiter a new flag name and associates it with pos * pos== -1 => any position will do * returns flag pos on success (>=0) * -1 flag is an alias for an already existing flag * -2 flag already registered * -3 mem. alloc. failure * -4 invalid pos * -5 no free flags */ int register_flag(char* name, int pos) { struct flag_entry* e; int len; unsigned int r; static unsigned int crt_flag=0; unsigned int last_flag; unsigned int h; len=strlen(name); h=get_hash1_raw(name, len) & (FLAGS_NAME_HASH_ENTRIES-1); /* check if the name already exists */ e=flag_search(&name2flags[h], name, len); if (e){ LOG(L_ERR, "ERROR: register_flag: flag %.*s already registered\n", len, name); return -2; } /* check if there is already another flag registered at pos */ if (pos!=-1){ if ((pos<0) || (pos>MAX_FLAG)){ LOG(L_ERR, "ERROR: register_flag: invalid flag %.*s " "position(%d)\n", len, name, pos); return -4; } if (registered_flags[pos]!=0){ LOG(L_WARN, "WARNING: register_flag: %.*s: flag %d already in " "use under another name\n", len, name, pos); /* continue */ } }else{ /* alloc an empty flag */ last_flag=crt_flag+(MAX_FLAG+1); for (; crt_flag!=last_flag; crt_flag++){ r=crt_flag%(MAX_FLAG+1); if (registered_flags[r]==0){ pos=r; break; } } if (pos==-1){ LOG(L_ERR, "ERROR: register_flag: could not register %.*s" " - too many flags\n", len, name); return -5; } } registered_flags[pos]++; e=pkg_malloc(sizeof(struct flag_entry)); if (e==0){ LOG(L_ERR, "ERROR: register_flag: memory allocation failure\n"); return -3; } e->name.s=name; e->name.len=len; e->no=pos; clist_insert(&name2flags[h], e, next, prev); return pos; }