/*=========================================================================
 *
 * GENUTIL.CPP - 29 November 1998, Dave Humphrey
 *
 * Some general functions/procedures which I use often.  Module is used
 * in all my programs.
 *
 *=======================================================================*/

	/* Required Include Files */
#include "genutil.h"

 
/*=========================================================================
 *
 * Begin Variable Definition
 *
 *=======================================================================*/

	/* Private array used by the function GetMonthAbbr() */
  char *pMonthAbbreviations[12] = {
    "Jan", "Feb", "Mar", "Apr", "May", "June",
    "July", "Aug", "Sept", "Oct", "Nov", "Dec"
   };

	/* Private array used by the function GetMonthName() */
  char *pMonthNames[12] = {
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
   };

	/* Turn on debugging options if in Windows in a debug build */
#if defined(_DEBUG) && defined(_WIN32)
  //static int DebugResult = _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF |
					  //_CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF);
  static int DebugResult = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
#endif 

/*=========================================================================
 *		End of Variable Definitions
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "GetMonthAbbr()"
/*===========================================================================
 *
 * Function - char *GetMonthAbbr (MonthIndex);
 *
 * Returns a pointer to the abbreviated month name referenced by the zero
 * indexed value given (0 is Jan, 11 is Dec).  Returns NULL if the given
 * index is invalid.
 *
 *=========================================================================*/
char *GetMonthAbbr (const int MonthIndex) {

	/* Ensure the given month index is valid */
  if (MonthIndex < 0 || MonthIndex > 11) return (NULL);

	/* Return pointer to month name */
  return (pMonthAbbreviations[MonthIndex]);
 }
/*===========================================================================
 *		End of Function GetMonthAbbr()
 *=========================================================================*/ 


#undef  __FUNC__
#define __FUNC__ "GetMonthName()"
/*===========================================================================
 *
 * Function - char *GetMonthName (MonthIndex);
 *
 * Returns a pointer to the full name of the month referenced by the zero
 * indexed value given (0 is January, 11 is December).  Returns NULL if the
 * given index is invalid.
 *
 *=========================================================================*/
char *GetMonthName (const int MonthIndex) {

	/* Ensure the given month index is valid */
  if (MonthIndex < 0 || MonthIndex > 11) return (NULL);

	/* Return pointer to month name */
  return (pMonthNames[MonthIndex]);
 }
/*===========================================================================
 *		End of Function GetMonthName()
 *=========================================================================*/  


#undef  __FUNC__
#define __FUNC__ "IsComment()"
/*=========================================================================
 *
 * Function - boolean IsComment (ch);
 *
 * Returns TRUE if the character is a comment (; or #) character.  Used
 * for parsing input INI and config files among other things.
 *
 *=======================================================================*/
boolean IsComment (const char ch) {
  return ((ch == ';' || ch == '#') ? TRUE : FALSE); 
 }
/*=========================================================================
 *		End of Function IsComment()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "IsPunctuation()"
/*=========================================================================
 *
 * Function - boolean IsPunctuation (char);
 *
 * Returns TRUE if the given character belongs to a set of common
 * punctuating characters.
 *
 *=======================================================================*/
boolean IsPunctuation(const unsigned char ch) {

	/* Compare with the 'normal' punctuation marks */
  if (ch == ' ' || ch == '-' || ch == '/' || ch == '\\')  return(TRUE);
  return(FALSE);
 }
/*=========================================================================
 *		End of Function IsPunctuation()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "IsExtPunct()"
/*=========================================================================
 *
 * Function - boolean IsExtPunct (char);
 *
 * Returns TRUE if the given character is in a set of extended punctuation
 * characters.
 *
 *=======================================================================*/
boolean IsExtPunct (const unsigned char ch) {

	/* Is the character a punctuation type character? */
  if (ch == '.' || ch == ',' || ch == ';' || ch == ':' || ch == ' '  ||
      ch == '?' || ch == '!' || ch == '!' || ch >= 0xFC || ch == ')' ||
      ch == '(' || ch == '[' || ch == ']' || ch == '-' || ch == '\'' ||
      ch == '`' || ch == '"') {
    return(TRUE);
   }

  return(FALSE);
 }
/*=========================================================================
 *		End of Function IsExtPunct()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "ParseVarValue()"
/*========================================================================
 *
 * Function - boolean ParseVarValue (pString, ppVar, ppValue);
 *
 * Parses a "Var = Value" type string.  Returns pointers to the variable
 * and value parts of the string.  The original string will be modified.
 * Returns FALSE if the given string does not have a var-value pair.
 *
 *======================================================================*/
boolean ParseVarValue (char* pString, char** ppVar, char** ppValue) {

	/* Ensure valid input */
  if (pString == NULL || ppVar == NULL || ppValue == NULL) {
    SET_EXT_ERROR(ERR_NULL);
    return (FALSE);
   }

	/* Remove leading whitespace from string and find */
  *ppVar = lstrip(pString);
  *ppValue = strchr(*ppVar, '=');

	/* Does the line contain a 'variable = value' expression? */
  if (*ppValue == NULL) return (FALSE);

	/* Strip variable and value expressions of remaining whitespace */
  **ppValue = NULL_CHAR;
  *ppValue = trim(*ppValue + 1);
  *ppVar = rstrip(*ppVar);

  return (TRUE);
 }
/*========================================================================
 *		End of Function ParseVarValue()
 *======================================================================*/


#undef  __FUNC__
#define __FUNC__ "powl2()"
/*=========================================================================
 *
 * Function - unsigned long powl2 (p);
 *
 * Returns 2 to the power of p.  On error returns 0 and sets the error code
 * to ERR_OVERFLOW.
 *
 *=======================================================================*/
unsigned long powl2 (const int p) {

	/* Make sure no overflows occur */
  if (p < 0 || p > 32) {
    SET_EXT_ERROR(ERR_OVERFLOW);
    return (0);
   }

  return ((unsigned long) ((1ul)<<p));
 }
/*=========================================================================
 *		End of Function powl2()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "pow2()"
/*=========================================================================
 *
 * Function - unsigned int pow2 (p);
 *
 * Returns 2 to the power of p.  On error returns 0 and sets the error code
 * to ERR_OVERFLOW.
 *
 *=======================================================================*/
unsigned int pow2 (const int p) {

	/* Make sure no overflows occur */
  if (p < 0 || p > 16) {
    SET_EXT_ERROR(ERR_OVERFLOW);
    return (0);
   }

  return ((unsigned int)((1u)<<p));
 }
/*=========================================================================
 *		End of Function pow2()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "RemoveComments()"
/*========================================================================
 *
 * Function - char* RemoveComments (pString, CommentChar);
 *
 * Removes any simple comments from the given string.  Simple comments
 * are defines as anything after the given comment character on a line.
 * The given string is returned.
 *
 *======================================================================*/
char* RemoveComments (char* pString, const char CommentChar) {
  char* pComment;

	/* Ensure valid input */
  if (pString == NULL) {
    SET_EXT_ERROR(ERR_NULL);
    return (NULL);
   }

	/* Look for the comment character in the string */
  pComment = strchr (pString, CommentChar);
  if (pComment == NULL) return (pString);

	/* Remove the comment */
  *pComment = NULL_CHAR;
  return (pString);
 }
/*========================================================================
 *		End of Function RemoveComments()
 *======================================================================*/


#undef  __FUNC__
#define __FUNC__ "sign()"
/*=========================================================================
 *
 * Function - int sign (i);
 *
 * Returns the sign of the expression (-1/0/1).
 *
 *=======================================================================*/
int sign (const int i) {
  return ( (i > 0) ? 1 : ((i == 0) ? 0 : -1) );
 }
/*=========================================================================
 *		End of Function sign()
 *=======================================================================*/


#undef  __FUNC__
#define __FUNC__ "swap()"
/*=========================================================================
 *
 * Procedure - void swap (x, y);
 *
 * Swaps x and y using the XOR technique (no temp variable needed).
 *
 *=======================================================================*/
void swap (int &x, int &y) {
  x ^= y;
  y ^= x;
  x ^= y;
 }
/*=========================================================================
 *		End of Procedure swap()
 *=======================================================================*/