/* File: flag.c * Author: Richard Durbin (rd@sanger.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1997 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * SCCS: $Id: flag.c,v 1.4 1999/09/01 11:28:49 fw Exp $ * Description: * Exported functions: * HISTORY: * Last edited: Apr 3 14:36 1997 (rd) * Created: Mon Jan 20 23:53:24 1997 (rd) *------------------------------------------------------------------- */ #include "acedb.h" #include "array.h" #include "flag.h" #include "lex.h" static DICT *masterDict = 0 ; static FLAGSET flagValue[32] ; static Array dictList ; static BOOL charOK[256] ; /************************************************************/ DICT* flagSetDict (char *set) { int i = -1 ; /* general initialisation if necessary */ if (!masterDict) { STORE_HANDLE h = handleCreate() ; masterDict = dictCreate (16) ; dictList = arrayCreate (16, DICT*) ; for (i = 0 ; i < MAXFLAG ; ++i) flagValue[i] = 1 << i ; /* build charOK[] character set */ for (i = 0 ; i < 26 ; ++i) { charOK['a'+i] = TRUE ; charOK['A'+i] = TRUE ; } for (i = 0 ; i < 10 ; ++i) charOK['0'+i] = TRUE ; charOK['_'] = TRUE ; for (i = 0 ; i < MAXFLAG-1 ; ++i) flag ("Default", strnew (messprintf ("bit%d", i+1), h)) ; handleDestroy (h) ; } if (dictAdd (masterDict, set, &i)) { DICT *d = dictCreate (32) ; int len = strlen (set) ; KEY key ; array(dictList, i, DICT*) = d ; for (key = 0 ; key < lexMax(0) ; ++key) if (!strncmp (name(key), "Flag", 4) && !strncmp (name(key)+4, set, len) && name(key)[4+len] == '#') dictAdd (d, name(key)+5+len, 0) ; } if (i == -1) return 0 ; return arr(dictList, i, DICT*) ; } /************************************************************/ /* s has form "flagstring1|flagstring2|...|flagstringN" */ FLAGSET flag (char *set, char *s) { FLAGSET res = 0 ; int i ; char *t ; static char *lastSet = 0 ; static DICT *dict ; if (set != lastSet) /* efficiency */ { dict = flagSetDict (set) ; lastSet = set ; } if (!dict || !s) messcrash ("bad arguments to flag()") ; if (dictFind (dict, s, &i)) /* shortcut attempt for simple cases */ return flagValue[i] ; while (*s) { for (t = s ; *t && *t != '|' ; ++t) /* look for separator */ if (!charOK[(int)*t]) { messerror ("Bad character %c (0x%x) in flag", *t, *t) ; return 0 ; } if (*t) *t = 0 ; else t = 0 ; if (dictAdd (dict, s, &i)) /* process this string */ { KEY dummy ; lexaddkey (messprintf ("Flag%s#%s", set, s), &dummy, 0) ; if (i >= MAXFLAG - 1) messcrash ("flag set %s has overflowed, with %s", set, s) ; } res |= flagValue[i] ; if (t) /* restore and cycle if necessary */ { *t = '|' ; s = t+1 ; } else break ; } return res ; } /************************************************************/ char *flagNameFromDict (DICT *dict, FLAGSET flag) { int i ; static Stack s = 0 ; if (!dict) return 0 ; s = stackReCreate (s, 128) ; for (i = 0 ; i < dictMax(dict) ; ++i) if (flag & flagValue[i]) { if (!stackEmpty(s)) catText (s, "|") ; catText (s, dictName (dict, i)) ; } return stackText (s, 0) ; } /************************************************************/ char *flagName (char *set, FLAGSET flag) { DICT *dict = flagSetDict (set) ; return flagNameFromDict (dict, flag) ; } /************************************************************/