⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 triostr.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
  assert(target);

  return trio_span_function(target, target, trio_to_lower);
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Compare two strings using wildcards.

   @param string String to be searched.
   @param pattern Pattern, including wildcards, to search for.
   @return Boolean value indicating success or failure.

   Case-insensitive comparison.
   
   The following wildcards can be used
   @li @c * Match any number of characters.
   @li @c ? Match a single character.
*/
TRIO_STRING_PUBLIC int
trio_match
TRIO_ARGS2((string, pattern),
	   TRIO_CONST char *string,
	   TRIO_CONST char *pattern)
{
  assert(string);
  assert(pattern);
  
  for (; ('*' != *pattern); ++pattern, ++string)
    {
      if (NIL == *string)
	{
	  return (NIL == *pattern);
	}
      if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
	  && ('?' != *pattern))
	{
	  return FALSE;
	}
    }
  /* two-line patch to prevent *too* much recursiveness: */
  while ('*' == pattern[1])
    pattern++;

  do
    {
      if ( trio_match(string, &pattern[1]) )
	{
	  return TRUE;
	}
    }
  while (*string++);
  
  return FALSE;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Compare two strings using wildcards.

   @param string String to be searched.
   @param pattern Pattern, including wildcards, to search for.
   @return Boolean value indicating success or failure.

   Case-sensitive comparison.
   
   The following wildcards can be used
   @li @c * Match any number of characters.
   @li @c ? Match a single character.
*/
TRIO_STRING_PUBLIC int
trio_match_case
TRIO_ARGS2((string, pattern),
	   TRIO_CONST char *string,
	   TRIO_CONST char *pattern)
{
  assert(string);
  assert(pattern);
  
  for (; ('*' != *pattern); ++pattern, ++string)
    {
      if (NIL == *string)
	{
	  return (NIL == *pattern);
	}
      if ((*string != *pattern)
	  && ('?' != *pattern))
	{
	  return FALSE;
	}
    }
  /* two-line patch to prevent *too* much recursiveness: */
  while ('*' == pattern[1])
    pattern++;

  do
    {
      if ( trio_match_case(string, &pattern[1]) )
	{
	  return TRUE;
	}
    }
  while (*string++);
  
  return FALSE;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Execute a function on each character in string.

   @param target Target string.
   @param source Source string.
   @param Function Function to be executed.
   @return Number of processed characters.
*/
TRIO_STRING_PUBLIC size_t
trio_span_function
TRIO_ARGS3((target, source, Function),
	   char *target,
	   TRIO_CONST char *source,
	   int (*Function) TRIO_PROTO((int)))
{
  size_t count = 0;

  assert(target);
  assert(source);
  assert(Function);
  
  while (*source != NIL)
    {
      *target++ = Function(*source++);
      count++;
    }
  return count;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Search for a substring in a string.

   @param string String to be searched.
   @param substring String to be found.
   @return Pointer to first occurrence of @p substring in @p string, or NULL
   if no match was found.
*/
TRIO_STRING_PUBLIC char *
trio_substring
TRIO_ARGS2((string, substring),
	   TRIO_CONST char *string,
	   TRIO_CONST char *substring)
{
  assert(string);
  assert(substring);

  return strstr(string, substring);
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Search for a substring in the first @p max characters of a string.

   @param string String to be searched.
   @param max Maximum characters to be searched.
   @param substring String to be found.
   @return Pointer to first occurrence of @p substring in @p string, or NULL
   if no match was found.
*/
TRIO_STRING_PUBLIC char *
trio_substring_max
TRIO_ARGS3((string, max, substring),
	   TRIO_CONST char *string,
	   size_t max,
	   TRIO_CONST char *substring)
{
  size_t count;
  size_t size;
  char *result = NULL;

  assert(string);
  assert(substring);
  
  size = trio_length(substring);
  if (size <= max)
    {
      for (count = 0; count <= max - size; count++)
	{
	  if (trio_equal_max(substring, size, &string[count]))
	    {
	      result = (char *)&string[count];
	      break;
	    }
	}
    }
  return result;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Tokenize string.

   @param string String to be tokenized.
   @param tokens String containing list of delimiting characters.
   @return Start of new token.

   @warning @p string will be destroyed.
*/
TRIO_STRING_PUBLIC char *
trio_tokenize
TRIO_ARGS2((string, delimiters),
	   char *string,
	   TRIO_CONST char *delimiters)
{
  assert(delimiters);
  
  return strtok(string, delimiters);
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Convert string to floating-point number.

   @param source String to be converted.
   @param endp Pointer to end of the converted string.
   @return A floating-point number.

   The following Extended Backus-Naur form is used
   @verbatim
   double        ::= [ <sign> ]
                     ( <number> |
                       <number> <decimal_point> <number> |
                       <decimal_point> <number> )
                     [ <exponential> [ <sign> ] <number> ]
   number        ::= 1*( <digit> )
   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
   exponential   ::= ( 'e' | 'E' )
   sign          ::= ( '-' | '+' )
   decimal_point ::= '.'
   @endverbatim
*/
/* FIXME: Add EBNF for hex-floats */
TRIO_STRING_PUBLIC trio_long_double_t
trio_to_long_double
TRIO_ARGS2((source, endp),
	   TRIO_CONST char *source,
	   char **endp)
{
#if defined(USE_STRTOLD)
  return strtold(source, endp);
#else
  int isNegative = FALSE;
  int isExponentNegative = FALSE;
  trio_long_double_t integer = 0.0;
  trio_long_double_t fraction = 0.0;
  unsigned long exponent = 0;
  trio_long_double_t base;
  trio_long_double_t fracdiv = 1.0;
  trio_long_double_t value = 0.0;

  /* First try hex-floats */
  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
    {
      base = 16.0;
      source += 2;
      while (isxdigit((int)*source))
	{
	  integer *= base;
	  integer += (isdigit((int)*source)
		      ? (*source - '0')
		      : 10 + (trio_to_upper((int)*source) - 'A'));
	  source++;
	}
      if (*source == '.')
	{
	  source++;
	  while (isxdigit((int)*source))
	    {
	      fracdiv /= base;
	      fraction += fracdiv * (isdigit((int)*source)
				     ? (*source - '0')
				     : 10 + (trio_to_upper((int)*source) - 'A'));
	      source++;
	    }
	  if ((*source == 'p') || (*source == 'P'))
	    {
	      source++;
	      if ((*source == '+') || (*source == '-'))
		{
		  isExponentNegative = (*source == '-');
		  source++;
		}
	      while (isdigit((int)*source))
		{
		  exponent *= 10;
		  exponent += (*source - '0');
		  source++;
		}
	    }
	}
      /* For later use with exponent */
      base = 2.0;
    }
  else /* Then try normal decimal floats */
    {
      base = 10.0;
      isNegative = (*source == '-');
      /* Skip sign */
      if ((*source == '+') || (*source == '-'))
	source++;

      /* Integer part */
      while (isdigit((int)*source))
	{
	  integer *= base;
	  integer += (*source - '0');
	  source++;
	}

      if (*source == '.')
	{
	  source++; /* skip decimal point */
	  while (isdigit((int)*source))
	    {
	      fracdiv /= base;
	      fraction += (*source - '0') * fracdiv;
	      source++;
	    }
	}
      if ((*source == 'e')
	  || (*source == 'E')
#if TRIO_MICROSOFT
	  || (*source == 'd')
	  || (*source == 'D')
#endif
	  )
	{
	  source++; /* Skip exponential indicator */
	  isExponentNegative = (*source == '-');
	  if ((*source == '+') || (*source == '-'))
	    source++;
	  while (isdigit((int)*source))
	    {
	      exponent *= (int)base;
	      exponent += (*source - '0');
	      source++;
	    }
	}
    }
  
  value = integer + fraction;
  if (exponent != 0)
    {
      if (isExponentNegative)
	value /= pow(base, (double)exponent);
      else
	value *= pow(base, (double)exponent);
    }
  if (isNegative)
    value = -value;

  if (endp)
    *endp = (char *)source;
  return value;
#endif
}


/**
   Convert string to floating-point number.

   @param source String to be converted.
   @param endp Pointer to end of the converted string.
   @return A floating-point number.

   See @ref trio_to_long_double.
*/
TRIO_STRING_PUBLIC double
trio_to_double
TRIO_ARGS2((source, endp),
	   TRIO_CONST char *source,
	   char **endp)
{
#if defined(USE_STRTOD)
  return strtod(source, endp);
#else
  return (double)trio_to_long_double(source, endp);
#endif
}

#if !defined(TRIO_MINIMAL)
/**
   Convert string to floating-point number.

   @param source String to be converted.
   @param endp Pointer to end of the converted string.
   @return A floating-point number.

   See @ref trio_to_long_double.
*/
TRIO_STRING_PUBLIC float
trio_to_float
TRIO_ARGS2((source, endp),
	   TRIO_CONST char *source,
	   char **endp)
{
#if defined(USE_STRTOF)
  return strtof(source, endp);
#else
  return (float)trio_to_long_double(source, endp);
#endif
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Convert string to signed integer.

   @param string String to be converted.
   @param endp Pointer to end of converted string.
   @param base Radix number of number.
*/
TRIO_STRING_PUBLIC long
trio_to_long
TRIO_ARGS3((string, endp, base),
	   TRIO_CONST char *string,
	   char **endp,
	   int base)
{
  assert(string);
  assert((base >= 2) && (base <= 36));
  
  return strtol(string, endp, base);
}


#if !defined(TRIO_MINIMAL)
/**
   Convert one alphabetic letter to lower-case.

   @param source The letter to be converted.
   @return The converted letter.
*/
TRIO_STRING_PUBLIC int
trio_to_lower
TRIO_ARGS1((source),
	   int source)
{
#if defined(USE_TOLOWER)
  
  return tolower(source);
  
#else

  /* Does not handle locales or non-contiguous alphabetic characters */
  return ((source >= (int)'A') && (source <= (int)'Z'))
    ? source - 'A' + 'a'
    : source;
  
#endif
}
#endif /* !defined(TRIO_MINIMAL) */

#if !defined(TRIO_MINIMAL)
/**
   Convert string to unsigned integer.

   @param string String to be converted.
   @param endp Pointer to end of converted string.
   @param base Radix number of number.
*/
TRIO_STRING_PUBLIC unsigned long
trio_to_unsigned_long
TRIO_ARGS3((string, endp, base),
	   TRIO_CONST char *string,
	   char **endp,
	   int base)
{
  assert(string);
  assert((base >= 2) && (base <= 36));
  
  return strtoul(string, endp, base);
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Convert one alphabetic letter to upper-case.

   @param source The letter to be converted.
   @return The converted letter.
*/
TRIO_STRING_PUBLIC int
trio_to_upper
TRIO_ARGS1((source),
	   int source)
{
#if defined(USE_TOUPPER)
  
  return toupper(source);
  
#else

  /* Does not handle locales or non-contiguous alphabetic characters */
  return ((source >= (int)'a') && (source <= (int)'z'))
    ? source - 'a' + 'A'
    : source;
  
#endif
}

#if !defined(TRIO_MINIMAL)
/**
   Convert the alphabetic letters in the string to upper-case.

   @param target The string to be converted.
   @return The number of processed characters (converted or not).
*/
TRIO_STRING_PUBLIC int
trio_upper
TRIO_ARGS1((target),
	   char *target)
{
  assert(target);

  return trio_span_function(target, target, trio_to_upper);
}
#endif /* !defined(TRIO_MINIMAL) */


/** @} End of StaticStrings */


/*************************************************************************
 * Dynamic String Functions
 */

#if defined(TRIO_DOCUMENTATION)
# include "doc/doc_dynamic.h"
#endif
/** @addtogroup DynamicStrings
    @{
*/

/*
 * TrioStringAlloc
 */
TRIO_STRING_PRIVATE trio_string_t *
TrioStringAlloc(TRIO_NOARGS)
{
  trio_string_t *self;
  
  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
  if (self)
    {
      self->content = NULL;
      self->length = 0;
      self->allocated = 0;
    }
  return self;
}


/*
 * TrioStringGrow
 *
 * The size of the string will be increased by 'delta' characters. If
 * 'delta' is zero, the size will be doubled.
 */
TRIO_STRING_PRIVATE BOOLEAN_T
TrioStringGrow
TRIO_ARGS2((self, delta),
	   trio_string_t *self,
	   size_t delta)
{
  BOOLEAN_T status = FALSE;
  char *new_content;
  size_t new_size;

  new_size = (delta == 0)
    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
    : self->allocated + delta;
  
  new_content = (char *)TRIO_REALLOC(self->content, new_size);
  if (new_content)
    {
      self->content = new_content;
      self->allocated = new_size;
      status = TRUE;
    }
  return status;
}


#if !defined(TRIO_MINIMAL)
/*
 * TrioStringGrowTo
 *
 * The size of the string will be increased to 'length' plus one characters.
 * If 'length' is less than the original size, the original size will be
 * used (that is, the size of the string is never decreased).
 */
TRIO_STRING_PRIVATE BOOLEAN_T
TrioStringGrowTo
TRIO_ARGS2((self, length),
	   trio_string_t *self,
	   size_t length)
{
  length++; /* Room for terminating zero */
  return (self->allocated < length)
    ? TrioStringGrow(self, length - self->allocated)
    : TRUE;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Create a new dynamic string.
   
   @param initial_size Initial size of the buffer.
   @return Newly allocated dynamic string, or NULL if memory allocation failed.
*/
TRIO_STRING_PUBLIC trio_string_t *
trio_string_create
TRIO_ARGS1((initial_size),
	   int initial_size)
{
  trio_string_t *self;

  self = TrioStringAlloc();
  if (self)
    {
      if (TrioStringGrow(self,
			 (size_t)((initial_size > 0) ? initial_size : 1)))
	{
	  self->content[0] = (char)0;
	  self->allocated = initial_size;
	}
      else
	{
	  trio_string_destroy(self);
	  self = NULL;
	}
    }
  return self;
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Deallocate the dynamic string and its contents.
   
   @param self Dynamic string
*/
TRIO_STRING_PUBLIC void
trio_string_destroy
TRIO_ARGS1((self),
	   trio_string_t *self)
{
  assert(self);
  
  if (self)
    {
      trio_destroy(self->content);
      TRIO_FREE(self);
    }
}


#if !defined(TRIO_MINIMAL)
/**
   Get a pointer to the content.
   
   @param self Dynamic string.
   @param offset Offset into content.
   @return Pointer to the content.
   
   @p Offset can be zero, positive, or negative. If @p offset is zero,
   then the start of the content will be returned. If @p offset is positive,
   then a pointer to @p offset number of characters from the beginning of the
   content is returned. If @p offset is negative, then a pointer to @p offset
   number of characters from the ending of the string, starting at the
   terminating zero, is returned.
*/
TRIO_STRING_PUBLIC char *
trio_string_get
TRIO_ARGS2((self, offset),
	   trio_string_t *self,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -