home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / Var / Flags.c next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  4.9 KB  |  222 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     flags.c
  5.  
  6.     DESCRIPTION
  7.     lowlevel flags-support for DME/XDME
  8.  
  9.     NOTES
  10.     is used by vars.c
  11.  
  12.     BUGS
  13.     <none known>
  14.  
  15.     TODO
  16.     -/-
  17.  
  18.     EXAMPLES
  19.     -/-
  20.  
  21.     SEE ALSO
  22.     vars.c
  23.  
  24.     INDEX
  25.  
  26.     HISTORY
  27.     09-11-92 b_noll created
  28.     15-08-93 b_noll updated
  29.  
  30. ******************************************************************************/
  31.  
  32. /*
  33. **  (C)Copyright 1992 by Bernd Noll for null/zero-soft
  34. **  All Rights Reserved
  35. **
  36. **  RCS Header: $Id: flags.c,v 1.65 92/11/09 12:47:21 b_noll Exp $
  37. **
  38. **  Basic Functions to work with (arrays of) DME-Flags
  39. **  (both Local and Global Flags use these functions)
  40. **
  41. **  Put together to start a little bit of modularisation
  42. **  in the sources.
  43. */
  44.  
  45. /**************************************
  46.         Includes
  47. **************************************/
  48. #include "defs.h"
  49.  
  50.  
  51. /**************************************
  52.         Globale Exports
  53. **************************************/
  54. Prototype int     test_arg  (char*, int);
  55. Prototype char * GetFlag   (char*, char*, int, char*);
  56. Prototype char     SetFlag   (char*, char*, char*, int, char*);
  57. Prototype int     IsFlagSet (char*, int, int);
  58.  
  59.  
  60. /**************************************
  61.       Interne Defines & Strukturen
  62. **************************************/
  63. static const UBYTE bit[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  64.  
  65.  
  66. /*
  67.  *  test_arg  (previous toggler)
  68.  *
  69.  *  simple hack do be used if you wanna implement
  70.  *  a function which can regognize on/off/toggle for
  71.  *  a BOOL (boolean) variable
  72.  *  args: 1 == TRUE == set == on | 0 == FALSE == reset == off | toggle == switch
  73.  */
  74.  
  75. #define TA_HSH(x,y) ((x & 223) | ((y & 223) << 8))
  76.  
  77. int test_arg (char * str, int bool)
  78. {
  79.  
  80.     if (!str)
  81.     abort (bool);
  82.  
  83.     switch (TA_HSH(str[0], str[1]))
  84.     {
  85.     case TA_HSH('r','e'): /* reset */
  86.     case TA_HSH('0', 0 ): /* 0 */
  87.     case TA_HSH('f','a'): /* false */
  88.     case TA_HSH('o','f'): /* off */
  89.     return (0);
  90.     case TA_HSH('s','e'): /* set */
  91.     case TA_HSH('1', 0 ): /* 1 */
  92.     case TA_HSH('t','r'): /* true */
  93.     case TA_HSH('o','n'): /* on */
  94.     return (1);
  95.     case TA_HSH('t','o'): /* toggle */
  96.     case TA_HSH('s','w'): /* switch  */
  97.     return (!bool);
  98.     default:
  99.     /* error ("test_arg:\n'%s' is not a valid\nvalue for flags!", str); */
  100.     abort (bool);
  101.     } /* switch */
  102. } /* test_arg */
  103.  
  104.  
  105.  
  106. int IsFlagSet (char * toggles, int number, int max)
  107. {
  108.     if (number < 0 || number >= max)
  109.     {
  110.     /* error ("IsFlagSet:\n'%ld' is not in range\nof [0 ..%ld] !", number, 0, max-1); */
  111.     abort(0);
  112.     }
  113.  
  114.     return((toggles[number/8] & bit[number&7]) ? 1 : 0);
  115. } /* IsFlagSet */
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /* short : get a number for our Get-/Set-Flag */
  122. /* -1 -> super range */
  123. /* -2 -> no number   */
  124. /* -3 -> wrong start */
  125. /* >= 0 -> use it    */
  126.  
  127. static int checknum (char* name, char* identifier, int max)
  128. {
  129.     int num = 0;
  130.  
  131.     num = strlen (identifier);
  132.  
  133.     /* ---- check for a valid name */
  134.  
  135.     if (strncmp (name, identifier, num))
  136.     return (-3);
  137.  
  138.     name += num;
  139.     if (!is_number (name))
  140.     return (-2);
  141.  
  142.     /* ---- check for a valid range */
  143.  
  144.     num = atoi (name);
  145.     if (num >= max || num < 0)
  146.     return (-1);
  147.  
  148.     return (num);
  149. } /* checknum */
  150.  
  151. /*
  152.  * if the string in name matches the format <xy><num>
  153.  *  <xy>  eq identifier
  154.  *  <num> /N in [0..max]
  155.  * then the flag <num> in toggles is set according to value
  156.  */
  157.  
  158. char SetFlag (char * toggles, char * name, char * value, int max, char * identifier)
  159. {
  160.     int num;  /* total bit number -> BYTE number */
  161.     int bn;   /* bit number in BYTE ... */
  162.     int res;  /* set or not */
  163.  
  164.     switch (num = checknum(name, identifier, max))
  165.     {
  166.     case -3:        /* no header-match */
  167.     case -2:        /* header not followed by number */
  168.     return (0);
  169.     case -1:        /* range error */
  170.     /* error ("SetFlag:\nrange error!"); */
  171.     abort (1);
  172.     default:        /* ok */
  173.     bn  = num & 7;
  174.     num = num / 8;
  175.     res = test_arg(value, toggles[num] & bit[bn]);
  176.     toggles[num] = (toggles[num] & ~bit[bn]) | (res ? bit[bn] : 0);  /* shorter: (res * bit[bn]) */
  177.     return(1);
  178.     } /* switch */
  179. } /* SetFlag */
  180.  
  181.  
  182.  
  183. /*
  184.  * if the string in name matches the format <xy><num>
  185.  *  <xy>  eq identifier
  186.  *  <num> /N in [0..max]
  187.  * then a string is allocated and filled according to flag <num> in toggles
  188.  */
  189.  
  190. char * GetFlag (char * toggles, char * name, int max, char * identifier)
  191. {
  192.     int num;
  193.     char* str;
  194.  
  195.     switch (num = checknum(name, identifier, max))
  196.     {
  197.     case -3:        /* no header-match */
  198.     case -2:        /* header not followed by number */
  199.     return (NULL);
  200.     case -1:        /* range error */
  201.     /* error ("GetFlag:\nrange error!"); */
  202.     abort (NULL);
  203.     default:        /* ok */
  204.     if (!(str = malloc(2)))
  205.     {
  206.         nomemory();
  207.         abort(NULL);
  208.     } /* if */
  209.  
  210.     str[0] = '0' + IsFlagSet(toggles, num, max);
  211.     str[1] =  0;
  212.  
  213.     return(str);
  214.     } /* switch */
  215. } /* GetFlag */
  216.  
  217.  
  218. /******************************************************************************
  219. *****  ENDE flags.c
  220. ******************************************************************************/
  221.  
  222.