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

📄 triostr.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************
 *
 * $Id: triostr.c,v 1.3 2003/04/03 15:28:28 veillard Exp $
 *
 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
 *
 ************************************************************************/

/*************************************************************************
 * Include files
 */

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "triodef.h"
#include "triostr.h"

/*************************************************************************
 * Definitions
 */

#if !defined(TRIO_STRING_PUBLIC)
# define TRIO_STRING_PUBLIC TRIO_PUBLIC
#endif
#if !defined(TRIO_STRING_PRIVATE)
# define TRIO_STRING_PRIVATE TRIO_PRIVATE
#endif

#if !defined(NULL)
# define NULL 0
#endif
#if !defined(NIL)
# define NIL ((char)0)
#endif
#if !defined(FALSE)
# define FALSE (1 == 0)
# define TRUE (! FALSE)
#endif
#if !defined(BOOLEAN_T)
# define BOOLEAN_T int
#endif

#if defined(TRIO_COMPILER_SUPPORTS_C99)
# define USE_STRTOD
# define USE_STRTOF
#elif defined(TRIO_COMPILER_MSVC)
# define USE_STRTOD
#endif

#if defined(TRIO_PLATFORM_UNIX)
# define USE_STRCASECMP
# define USE_STRNCASECMP
# if defined(TRIO_PLATFORM_SUNOS)
#  define USE_SYS_ERRLIST
# else
#  define USE_STRERROR
# endif
# if defined(TRIO_PLATFORM_QNX)
#  define strcasecmp(x,y) stricmp(x,y)
#  define strncasecmp(x,y,n) strnicmp(x,y,n)
# endif
#elif defined(TRIO_PLATFORM_WIN32)
# define USE_STRCASECMP
# define strcasecmp(x,y) strcmpi(x,y)
#endif

#if !(defined(TRIO_PLATFORM_SUNOS))
# define USE_TOLOWER
# define USE_TOUPPER
#endif

/*************************************************************************
 * Structures
 */

struct _trio_string_t
{
  char *content;
  size_t length;
  size_t allocated;
};

/*************************************************************************
 * Constants
 */

#if !defined(TRIO_MINIMAL)
static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.3 2003/04/03 15:28:28 veillard Exp $";
#endif

/*************************************************************************
 * Static String Functions
 */

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

/**
   Create new string.

   @param size Size of new string.
   @return Pointer to string, or NULL if allocation failed.
*/
TRIO_STRING_PUBLIC char *
trio_create
TRIO_ARGS1((size),
	   size_t size)
{
  return (char *)TRIO_MALLOC(size);
}


/**
   Destroy string.

   @param string String to be freed.
*/
TRIO_STRING_PUBLIC void
trio_destroy
TRIO_ARGS1((string),
	   char *string)
{
  if (string)
    {
      TRIO_FREE(string);
    }
}


/**
   Count the number of characters in a string.

   @param string String to measure.
   @return Number of characters in @string.
*/
TRIO_STRING_PUBLIC size_t
trio_length
TRIO_ARGS1((string),
	   TRIO_CONST char *string)
{
  return strlen(string);
}


#if !defined(TRIO_MINIMAL)
/**
   Append @p source at the end of @p target.
   
   @param target Target string.
   @param source Source string.
   @return Boolean value indicating success or failure.
   
   @pre @p target must point to a memory chunk with sufficient room to
   contain the @p target string and @p source string.
   @pre No boundary checking is performed, so insufficient memory will
   result in a buffer overrun.
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC int
trio_append
TRIO_ARGS2((target, source),
	   char *target,
	   TRIO_CONST char *source)
{
  assert(target);
  assert(source);
  
  return (strcat(target, source) != NULL);
}
#endif /* !defined(TRIO_MINIMAL) */

#if !defined(TRIO_MINIMAL)
/**
   Append at most @p max characters from @p source to @p target.
   
   @param target Target string.
   @param max Maximum number of characters to append.
   @param source Source string.
   @return Boolean value indicating success or failure.
   
   @pre @p target must point to a memory chuck with sufficient room to
   contain the @p target string and the @p source string (at most @p max
   characters).
   @pre No boundary checking is performed, so insufficient memory will
   result in a buffer overrun.
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC int
trio_append_max
TRIO_ARGS3((target, max, source),
	   char *target,
	   size_t max,
	   TRIO_CONST char *source)
{
  size_t length;
  
  assert(target);
  assert(source);

  length = trio_length(target);
  
  if (max > length)
    {
      strncat(target, source, max - length - 1);
    }
  return TRUE;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Determine if a string contains a substring.

   @param string String to be searched.
   @param substring String to be found.
   @return Boolean value indicating success or failure.
*/
TRIO_STRING_PUBLIC int
trio_contains
TRIO_ARGS2((string, substring),
	   TRIO_CONST char *string,
	   TRIO_CONST char *substring)
{
  assert(string);
  assert(substring);
  
  return (0 != strstr(string, substring));
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Copy @p source to @p target.
   
   @param target Target string.
   @param source Source string.
   @return Boolean value indicating success or failure.
   
   @pre @p target must point to a memory chunk with sufficient room to
   contain the @p source string.
   @pre No boundary checking is performed, so insufficient memory will
   result in a buffer overrun.
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC int
trio_copy
TRIO_ARGS2((target, source),
	   char *target,
	   TRIO_CONST char *source)
{
  assert(target);
  assert(source);
     
  (void)strcpy(target, source);
  return TRUE;
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Copy at most @p max characters from @p source to @p target.
   
   @param target Target string.
   @param max Maximum number of characters to append.
   @param source Source string.
   @return Boolean value indicating success or failure.
   
   @pre @p target must point to a memory chunk with sufficient room to
   contain the @p source string (at most @p max characters).
   @pre No boundary checking is performed, so insufficient memory will
   result in a buffer overrun.
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC int
trio_copy_max
TRIO_ARGS3((target, max, source),
	   char *target,
	   size_t max,
	   TRIO_CONST char *source)
{
  assert(target);
  assert(source);
  assert(max > 0); /* Includes != 0 */

  (void)strncpy(target, source, max - 1);
  target[max - 1] = (char)0;
  return TRUE;
}


/*
 * TrioDuplicateMax
 */
TRIO_STRING_PRIVATE char *
TrioDuplicateMax
TRIO_ARGS2((source, size),
	   TRIO_CONST char *source,
	   size_t size)
{
  char *target;

  assert(source);

  /* Make room for string plus a terminating zero */
  size++;
  target = trio_create(size);
  if (target)
    {
      trio_copy_max(target, size, source);
    }
  return target;
}


/**
   Duplicate @p source.
   
   @param source Source string.
   @return A copy of the @p source string.
   
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC char *
trio_duplicate
TRIO_ARGS1((source),
	   TRIO_CONST char *source)
{
  return TrioDuplicateMax(source, trio_length(source));
}


#if !defined(TRIO_MINIMAL)
/**
   Duplicate at most @p max characters of @p source.
   
   @param source Source string.
   @param max Maximum number of characters to duplicate.
   @return A copy of the @p source string.
   
   @post @p target will be zero terminated.
*/
TRIO_STRING_PUBLIC char *
trio_duplicate_max TRIO_ARGS2((source, max),
			      TRIO_CONST char *source,
			      size_t max)
{
  size_t length;

  assert(source);
  assert(max > 0);

  length = trio_length(source);
  if (length > max)
    {
      length = max;
    }
  return TrioDuplicateMax(source, length);
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Compare if two strings are equal.
   
   @param first First string.
   @param second Second string.
   @return Boolean indicating whether the two strings are equal or not.
   
   Case-insensitive comparison.
*/
TRIO_STRING_PUBLIC int
trio_equal
TRIO_ARGS2((first, second),
	   TRIO_CONST char *first,
	   TRIO_CONST char *second)
{
  assert(first);
  assert(second);

  if ((first != NULL) && (second != NULL))
    {
#if defined(USE_STRCASECMP)
      return (0 == strcasecmp(first, second));
#else
      while ((*first != NIL) && (*second != NIL))
	{
	  if (trio_to_upper(*first) != trio_to_upper(*second))
	    {
	      break;
	    }
	  first++;
	  second++;
	}
      return ((*first == NIL) && (*second == NIL));
#endif
    }
  return FALSE;
}


/**
   Compare if two strings are equal.
   
   @param first First string.
   @param second Second string.
   @return Boolean indicating whether the two strings are equal or not.
   
   Case-sensitive comparison.
*/
TRIO_STRING_PUBLIC int
trio_equal_case
TRIO_ARGS2((first, second),
	   TRIO_CONST char *first,
	   TRIO_CONST char *second)
{
  assert(first);
  assert(second);

  if ((first != NULL) && (second != NULL))
    {
      return (0 == strcmp(first, second));
    }
  return FALSE;
}


#if !defined(TRIO_MINIMAL)
/**
   Compare if two strings up until the first @p max characters are equal.
   
   @param first First string.
   @param max Maximum number of characters to compare.
   @param second Second string.
   @return Boolean indicating whether the two strings are equal or not.
   
   Case-sensitive comparison.
*/
TRIO_STRING_PUBLIC int
trio_equal_case_max
TRIO_ARGS3((first, max, second),
	   TRIO_CONST char *first,
	   size_t max,
	   TRIO_CONST char *second)
{
  assert(first);
  assert(second);

  if ((first != NULL) && (second != NULL))
    {
      return (0 == strncmp(first, second, max));
    }
  return FALSE;
}
#endif /* !defined(TRIO_MINIMAL) */


/**
   Compare if two strings are equal.
   
   @param first First string.
   @param second Second string.
   @return Boolean indicating whether the two strings are equal or not.

   Collating characters are considered equal.
*/
TRIO_STRING_PUBLIC int
trio_equal_locale
TRIO_ARGS2((first, second),
	   TRIO_CONST char *first,
	   TRIO_CONST char *second)
{
  assert(first);
  assert(second);

#if defined(LC_COLLATE)
  return (strcoll(first, second) == 0);
#else
  return trio_equal(first, second);
#endif
}


/**
   Compare if two strings up until the first @p max characters are equal.
   
   @param first First string.
   @param max Maximum number of characters to compare.
   @param second Second string.
   @return Boolean indicating whether the two strings are equal or not.
   
   Case-insensitive comparison.
*/
TRIO_STRING_PUBLIC int
trio_equal_max
TRIO_ARGS3((first, max, second),
	   TRIO_CONST char *first,
	   size_t max,
	   TRIO_CONST char *second)
{
  assert(first);
  assert(second);

  if ((first != NULL) && (second != NULL))
    {
#if defined(USE_STRNCASECMP)
      return (0 == strncasecmp(first, second, max));
#else
      /* Not adequately tested yet */
      size_t cnt = 0;
      while ((*first != NIL) && (*second != NIL) && (cnt <= max))
	{
	  if (trio_to_upper(*first) != trio_to_upper(*second))
	    {
	      break;
	    }
	  first++;
	  second++;
	  cnt++;
	}
      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
#endif
    }
  return FALSE;
}


/**
   Provide a textual description of an error code (errno).

   @param error_number Error number.
   @return Textual description of @p error_number.
*/
TRIO_STRING_PUBLIC TRIO_CONST char *
trio_error
TRIO_ARGS1((error_number),
	   int error_number)
{
#if defined(USE_STRERROR)
  
  return strerror(error_number);

#elif defined(USE_SYS_ERRLIST)

  extern char *sys_errlist[];
  extern int sys_nerr;

  return ((error_number < 0) || (error_number >= sys_nerr))
    ? "unknown"
    : sys_errlist[error_number];
 
#else
  
  return "unknown";
  
#endif
}


#if !defined(TRIO_MINIMAL)
/**
   Format the date/time according to @p format.

   @param target Target string.
   @param max Maximum number of characters to format.
   @param format Formatting string.
   @param datetime Date/time structure.
   @return Number of formatted characters.

   The formatting string accepts the same specifiers as the standard C
   function strftime.
*/
TRIO_STRING_PUBLIC size_t
trio_format_date_max
TRIO_ARGS4((target, max, format, datetime),
	   char *target,
	   size_t max,
	   TRIO_CONST char *format,
	   TRIO_CONST struct tm *datetime)
{
  assert(target);
  assert(format);
  assert(datetime);
  assert(max > 0);
  
  return strftime(target, max, format, datetime);
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Calculate a hash value for a string.

   @param string String to be calculated on.
   @param type Hash function.
   @return Calculated hash value.

   @p type can be one of the following
   @li @c TRIO_HASH_PLAIN Plain hash function.
*/
TRIO_STRING_PUBLIC unsigned long
trio_hash
TRIO_ARGS2((string, type),
	   TRIO_CONST char *string,
	   int type)
{
  unsigned long value = 0L;
  char ch;

  assert(string);
  
  switch (type)
    {
    case TRIO_HASH_PLAIN:
      while ( (ch = *string++) != NIL )
	{
	  value *= 31;
	  value += (unsigned long)ch;
	}
      break;
    default:
      assert(FALSE);
      break;
    }
  return value;
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Find first occurrence of a character in a string.

   @param string String to be searched.
   @param character Character to be found.
   @param A pointer to the found character, or NULL if character was not found.
 */
TRIO_STRING_PUBLIC char *
trio_index
TRIO_ARGS2((string, character),
	   TRIO_CONST char *string,
	   int character)
{
  assert(string);

  return strchr(string, character);
}
#endif /* !defined(TRIO_MINIMAL) */


#if !defined(TRIO_MINIMAL)
/**
   Find last occurrence of a character in a string.

   @param string String to be searched.
   @param character Character to be found.
   @param A pointer to the found character, or NULL if character was not found.
 */
TRIO_STRING_PUBLIC char *
trio_index_last
TRIO_ARGS2((string, character),
	   TRIO_CONST char *string,
	   int character)
{
  assert(string);

  return strchr(string, character);
}
#endif /* !defined(TRIO_MINIMAL) */


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

   @param target String to be converted.
   @return Number of processed characters (converted or not).
*/
TRIO_STRING_PUBLIC int
trio_lower
TRIO_ARGS1((target),
	   char *target)
{

⌨️ 快捷键说明

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