home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / clipper / bitflags.c < prev    next >
C/C++ Source or Header  |  1993-10-14  |  10KB  |  327 lines

  1. /*
  2.  * File......: BITFLAGS.C
  3.  * Author....: Dave Pearson
  4.  * BBS.......: The Dark Knight Returns
  5.  * Net/Node..: 050/069
  6.  * User Name.: Dave Pearson
  7.  * Date......: 31/03/93
  8.  * Revision..: 1.0
  9.  *
  10.  * This is an original work by Dave Pearson and is placed in the public
  11.  * domain.
  12.  *
  13.  * Modification history:
  14.  * ---------------------
  15.  *
  16.  * $Log$
  17.  *
  18.  */
  19.  
  20. // NOTE: This code has been written for and compiled with Borland C++
  21. //       Version 3.1
  22. //
  23.  
  24. #include <extend.h>
  25.  
  26. #define _GT_MAX(x,y)    (x > y ? x : y)
  27.  
  28. /*  $DOC$
  29.  *  $FUNCNAME$
  30.  *      GT_NEWFLAG()
  31.  *  $CATEGORY$
  32.  *      General
  33.  *  $ONELINER$
  34.  *      Create a new bit flag string.
  35.  *  $SYNTAX$
  36.  *      GT_NewFlag(<nFlagCount>) --> cFlagString
  37.  *  $ARGUMENTS$
  38.  *      <nFlagCount> is the number of flags you wish to store.
  39.  *  $RETURNS$
  40.  *      A string to hold the bit flags. All flags are set to FALSE.
  41.  *  $DESCRIPTION$
  42.  *      GT_NewFlag() is used to construct a bit flag string. The bit flag
  43.  *      functions can be used for storing a large number of logical values
  44.  *      is a small space.
  45.  *
  46.  *      To create a bit flag string you need to pass GT_NewFlag() a value
  47.  *      that is equal to or greater than the number of flags required (you
  48.  *      may want to allow for future expansion). Each character in the
  49.  *      string returned from GT_NewFlag() will hold 8 logical values.
  50.  *  $EXAMPLES$
  51.  *      cFlags := GT_NewFlag(20)   // Create a bit flag string for 20
  52.  *                                 // logical values.
  53.  *  $SEEALSO$
  54.  *      GT_SETFLAG() GT_CLRFLAG() GT_ISFLAG()
  55.  *  $END$
  56.  */
  57.  
  58. CLIPPER GT_NewFlag(void)
  59. {
  60.         char     *FlagString = NULL;
  61.         unsigned ByteCount   = 0;
  62.         unsigned FlagCount   = 1;
  63.         int      Byte;
  64.  
  65.         if (PCOUNT)
  66.         {
  67.                 if (ISNUM(1))
  68.                 {
  69.                         FlagCount = (unsigned) _parni(1);
  70.                 }
  71.         }
  72.         if (FlagCount > 0)
  73.         {
  74.                 ByteCount = (unsigned)((FlagCount / 8) + 1);
  75.                 if (!(FlagCount % 8))
  76.                 {
  77.                         --ByteCount;
  78.                 }
  79.                 FlagString = _xgrab(ByteCount);
  80.                 for (Byte = 0; Byte < ByteCount; Byte++)
  81.                 {
  82.                         FlagString[Byte] = 0;
  83.                 }
  84.                 _retclen(FlagString,ByteCount);
  85.                 _xfree(FlagString);
  86.                 _xunlock();
  87.         }
  88.         else
  89.         {
  90.                 _retc("");
  91.         }
  92. }
  93.  
  94. /*  $DOC$
  95.  *  $FUNCNAME$
  96.  *      GT_SETFLAG()
  97.  *  $CATEGORY$
  98.  *      General
  99.  *  $ONELINER$
  100.  *      Set a number of flags to TRUE in a bit flag string.
  101.  *  $SYNTAX$
  102.  *      GT_SetFlag(<cFlagString>,[<nStart>],[<nEnd>]) --> cFlagString
  103.  *  $ARGUMENTS$
  104.  *      <cFlagString> is a bit flag string created with GT_NewFlag()
  105.  *
  106.  *      <nStart> is the starting flag. This is an optional numeric value.
  107.  *      If not supplied it defaults to 1.
  108.  *
  109.  *      <nEnd> is the ending flag. This is an optional numeric value. If
  110.  *      not supplied it defaults to <nStart>.
  111.  *  $RETURNS$
  112.  *      The bit map string with the new flag settings.
  113.  *  $DESCRIPTION$
  114.  *      GT_SetFlag() is used to turn flags within the flag string on.
  115.  *  $EXAMPLES$
  116.  *      cFlags := GT_NewFlag(20)   // Create a bit flag string for 20
  117.  *                                 // logical values.
  118.  *
  119.  *      // Now set flags 10 to 15 to true.
  120.  *
  121.  *      cFlags := GT_SetFlag(cFlags,10,15)
  122.  *
  123.  *      // And set flag 18 to true.
  124.  *
  125.  *      cFlags := GT_SetFlag(cFlags,18)
  126.  *
  127.  *      // And set flag 1 to true.
  128.  *
  129.  *      cFlags := GT_SetFlag(cFlags)
  130.  *  $SEEALSO$
  131.  *      GT_NEWFLAG() GT_CLRFLAG() GT_ISFLAG()
  132.  *  $END$
  133.  */
  134.  
  135. CLIPPER GT_SetFlag(void)
  136. {
  137.         char     *FlagString = NULL;
  138.         unsigned StartBit    = 1;
  139.         unsigned EndBit      = 1;
  140.         unsigned BitCount;
  141.         unsigned BitPointer;
  142.         unsigned BytePointer;
  143.  
  144.         if (PCOUNT && ISCHAR(1))
  145.         {
  146.                 FlagString = _parc(1);
  147.                 if (PCOUNT >= 2 && ISNUM(2))
  148.                 {
  149.                         StartBit = _parni(2);
  150.                 }
  151.                 if (PCOUNT >= 3 && ISNUM(3))
  152.                 {
  153.                         EndBit = _parni(3);
  154.                 }
  155.                 EndBit = _GT_MAX(StartBit,EndBit);
  156.                 if (StartBit > 0 && EndBit <= (_parclen(1) * 8))
  157.                 {
  158.                         for (BitCount = StartBit; BitCount <= EndBit; BitCount++)
  159.                         {
  160.                                 BitPointer  = BitCount % 8;
  161.                                 BytePointer = (unsigned) (BitCount / 8);
  162.                                 if (!BitPointer)
  163.                                 {
  164.                                         BitPointer = 8;
  165.                                         --BytePointer;
  166.                                 }
  167.                                 FlagString[BytePointer] |= 1 << (BitPointer - 1);
  168.                         }
  169.                 }
  170.                 _retclen(FlagString,_parclen(1));
  171.                 _xunlock();
  172.         }
  173.         else
  174.         {
  175.                 _retc("");
  176.         }
  177. }
  178.  
  179. /*  $DOC$
  180.  *  $FUNCNAME$
  181.  *      GT_CLRFLAG()
  182.  *  $CATEGORY$
  183.  *      General
  184.  *  $ONELINER$
  185.  *      Set a number of flags to FALSE in a bit flag string.
  186.  *  $SYNTAX$
  187.  *      GT_ClrFlag(<cFlagString>,[<nStart>],[<nEnd>]) --> cFlagString
  188.  *  $ARGUMENTS$
  189.  *      <cFlagString> is a bit flag string created with GT_NewFlag()
  190.  *
  191.  *      <nStart> is the starting flag. This is an optional numeric value.
  192.  *      If not supplied it defaults to 1.
  193.  *
  194.  *      <nEnd> is the ending flag. This is an optional numeric value. If
  195.  *      not supplied it defaults to <nStart>.
  196.  *  $RETURNS$
  197.  *      The bit map string with the new flag settings.
  198.  *  $DESCRIPTION$
  199.  *      GT_ClrFlag() is used to turn flags within the flag string off.
  200.  *  $EXAMPLES$
  201.  *      cFlags := GT_NewFlag(20)   // Create a bit flag string for 20
  202.  *                                 // logical values.
  203.  *
  204.  *      // Now, turn them all on.
  205.  *
  206.  *      cFlags := GT_SetFlag(cFlags,1,20)
  207.  *
  208.  *      // Now set flags 10 to 15 to false.
  209.  *
  210.  *      cFlags := GT_ClrFlag(cFlags,10,15)
  211.  *
  212.  *      // And set flag 18 to false.
  213.  *
  214.  *      cFlags := GT_ClrFlag(cFlags,18)
  215.  *
  216.  *      // And set flag 1 to false.
  217.  *
  218.  *      cFlags := GT_ClrFlag(cFlags)
  219.  *  $SEEALSO$
  220.  *      GT_NEWFLAG() GT_SETFLAG() GT_ISFLAG()
  221.  *  $END$
  222.  */
  223.  
  224. CLIPPER GT_ClrFlag(void)
  225. {
  226.         char     *FlagString = NULL;
  227.         unsigned StartBit    = 1;
  228.         unsigned EndBit      = 1;
  229.         unsigned BitCount;
  230.         unsigned BitPointer;
  231.         unsigned BytePointer;
  232.  
  233.         if (PCOUNT && ISCHAR(1))
  234.         {
  235.                 FlagString = _parc(1);
  236.                 if (PCOUNT >= 2 && ISNUM(2))
  237.                 {
  238.                         StartBit = _parni(2);
  239.                 }
  240.                 if (PCOUNT >= 3 && ISNUM(3))
  241.                 {
  242.                         EndBit = _parni(3);
  243.                 }
  244.                 EndBit = _GT_MAX(StartBit,EndBit);
  245.                 if (StartBit > 0 && EndBit <= (_parclen(1) * 8))
  246.                 {
  247.                         for (BitCount = StartBit; BitCount <= EndBit; BitCount++)
  248.                         {
  249.                                 BitPointer  = BitCount % 8;
  250.                                 BytePointer = (unsigned) (BitCount / 8);
  251.                                 if (!BitPointer)
  252.                                 {
  253.                                         BitPointer = 8;
  254.                                         --BytePointer;
  255.                                 }
  256.                                 FlagString[BytePointer] &= 0xff - (1 << (BitPointer - 1));
  257.                         }
  258.                 }
  259.                 _retclen(FlagString,_parclen(1));
  260.                 _xunlock();
  261.         }
  262.         else
  263.         {
  264.                 _retc("");
  265.         }
  266. }
  267.  
  268. /*  $DOC$
  269.  *  $FUNCNAME$
  270.  *      GT_ISFLAG()
  271.  *  $CATEGORY$
  272.  *      General
  273.  *  $ONELINER$
  274.  *      Test the setting of a flag in a bit flag string.
  275.  *  $SYNTAX$
  276.  *      GT_IsFlag(<cFlagString>,[<nFlag>]) --> lSetting
  277.  *  $ARGUMENTS$
  278.  *      <cFlagString> is a bit flag string created with GT_NewFlag()
  279.  *
  280.  *      <nFlag> is the flag to be tested.
  281.  *  $RETURNS$
  282.  *      A boolean value, TRUE if the flag is on, FALSE if it's off.
  283.  *  $DESCRIPTION$
  284.  *      GT_IsFlag() is used to test the state of a flag with a bit flag
  285.  *      string.
  286.  *  $EXAMPLES$
  287.  *
  288.  *      // Print the setting of the flags in a flag string called ``cDave''
  289.  *
  290.  *      for nFlag := 1 to (len(cDave)*8)
  291.  *         ? "Flag number ",nFlag," == ",GT_IsFlag(cDave,nFlag)
  292.  *      next
  293.  *  $SEEALSO$
  294.  *      GT_NEWFLAG() GT_SETFLAG() GT_CLRFLAG()
  295.  *  $END$
  296.  */
  297.  
  298. CLIPPER GT_IsFlag(void)
  299. {
  300.         Boolean         FlagStatus = FALSE;
  301.         unsigned        Bit        = 1;
  302.         unsigned        BitPointer;
  303.         unsigned        BytePointer;
  304.         char            *FlagString;
  305.  
  306.         if (PCOUNT && ISCHAR(1))
  307.         {
  308.                 FlagString = _parc(1);
  309.                 if (PCOUNT >= 2 && ISNUM(2))
  310.                 {
  311.                         Bit = _parni(2);
  312.                 }
  313.                 if (Bit > 0 && Bit <= (_parclen(1) * 8))
  314.                 {
  315.                         BitPointer  = Bit % 8;
  316.                         BytePointer = (unsigned) (Bit / 8);
  317.                         if (!BitPointer)
  318.                         {
  319.                                 BitPointer = 8;
  320.                                 --BytePointer;
  321.                         }
  322.                         FlagStatus = FlagString[BytePointer] & (1 << (BitPointer - 1));
  323.                 }
  324.         }
  325.         _retl(FlagStatus);
  326. }
  327.