Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: 85 en 26 Marzo 2013, 16:21 pm



Título: CRT personalizada
Publicado por: 85 en 26 Marzo 2013, 16:21 pm
Hola, estaba leyendo este texto:
Citar
5) make your own CRT

   MUCH easier than you might think... what do you need from a runtime? to allocate/deallocate
   mem? to print to the console?

   look up the functions required to allocate memory from windows...

   now just have some functions that set needed globals:

   HANDLE g_hHeap = 0;

   extern "C" BOOL crt_initialize() { return (g_hHeap = HeapCreate(0, 0, 0))); }
   extern "C" BOOL crt_uninitialize() { return HeapDestroy(g_hHeap)); }

   you can now, if you choose, override the default CRT entry's name:

   extern "C" int mainCRTStartup()
   {
      crt_initialize();
      // maybe get the arguments here with GetCommandLine()
      main();//maybe send args here
      return 0;
   }

   so how do you do malloc()/free() ? how do you do new/delete? it's as simple as passing the
   requested sizes to the OS functions along with the heap handle made during the initialization

   extern "C" void * malloc(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); }
   extern "C" void free(void * p) { HeapFree(g_hHeap, 0, p); }

   void * __cdecl operator new(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); }
   void __cdecl operator delete(void *p) { HeapFree(g_hHeap, 0, p); }

   hopefully you can figure out the rest... especially how your crt entry should acquire and
   supply needed parameters to your main() or winmain()

6) bypass the normal CRT

   if you don't want to write a CRT, but also don't want the cruft that comes with the normal CRT,
   just specify that the linker should jump to your code first, NOT the crt

   /ENTRY:yourfunction

Y buscando información encontré algunas cosas interesantes, por ejemplo 2 proyectos de CRT propias, más que el otro estuve mirando el más reciente del 2010, que se llama 'minicrt'.
Me parece que les puede interesar a algunos, porque en el proyecto se puede encontrar el código de muchas implementaciones de funciones de C.
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e6f222d7-8e20-4d4a-8a6f-b72ade3661ac/
http://www.benshoof.org/blog/minicrt/
http://www.wheaty.net/
http://www.benshoof.org/blog/archive/
http://www.wheaty.net/downloads.htm

Se pueden encontrar versiones de las funciones originales que cumplen con los standards de C, hay implementaciones de algunas funciones que a mi por ejemplo me interesaban crear implementaciones personalizadas de ellas, atoi, strtok, y muchas otras

por ejemplo atoi
Código:
//==========================================
// minicrt - Chris Benshoof 2009
// atoi(), modified from
// http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/atoi.c.htm
//==========================================
#include "libctiny.h"
 
extern "C" int __cdecl atoi(const char *String)
{
    int Value = 0, Digit;
    int c;
 
    while ((c = *String++) != '\0') {
 
        if (c >= '0' && c <= '9')
            Digit = (c - '0');
        else
            break;
 
        Value = (Value * 10) + Digit;
    }
 
    return Value;
}

aparte es un proyecto no tan antiguo, dice que es del 2010.
El otro si es del 2000.

saludos


Título: Re: CRT personalizada
Publicado por: rir3760 en 27 Marzo 2013, 19:30 pm
Se pueden encontrar versiones de las funciones originales que cumplen con los standards de C, hay implementaciones de algunas funciones que a mi por ejemplo me interesaban crear implementaciones personalizadas de ellas, atoi, strtok, y muchas otras
La especificación de strtok según la referencia sobre C90 de P. J. Plauger (un poco mas estricta que la estándar) es:
Citar
strtok

char *strtok(char *s1, const char *s2);

If s1 is not a null pointer, the function begins a search of the string s1. Otherwise, it begins a search of the string whose address was last stored in an internal static-duration object on an earlier call to the function, as described below. The search proceeds as follows:

1. The function searches the string for begin, the address of the first element that equals none of the elements of the string s2 (a set of token separators). It considers the terminating null character as part of the search string only.

2. If the search does not find an element, the function stores the address of the terminating null character in the internal static-duration object (so that a subsequent search beginning with that address will fail) and returns a null pointer. Otherwise, the function searches from begin for end, the address of the first element that equals any one of the elements of the string s2. It again considers the terminating null character as part of the search string only.

3. If the search does not find an element, the function stores the address of the terminating null character in the internal static-duration object. Otherwise, it stores a null character in the element whose address is end. Then it stores the address of the next element after end in the internal static-duration object (so that a subsequent search beginning with that address will continue with the remaining elements of the string) and returns begin.

Esta se puede implementar utilizando las funciones strspn y strcspn (prototipos en <string.h>). Un programa de ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. char *fn_strtok(char *str, char const *set);
  6.  
  7. int main(void)
  8. {
  9.   char str[] = "?a???b,,,#c";
  10.  
  11.   printf("\"%s\"\n", strtok(str, "?"));
  12.   printf("\"%s\"\n", strtok(NULL, ","));
  13.   printf("\"%s\"\n", strtok(NULL, "#,"));
  14.   printf("%p\n", (void *) strtok(NULL, "?"));
  15.  
  16.   strcpy(str, "?a???b,,,#c");
  17.  
  18.   printf("\"%s\"\n", fn_strtok(str, "?"));
  19.   printf("\"%s\"\n", fn_strtok(NULL, ","));
  20.   printf("\"%s\"\n", fn_strtok(NULL, "#,"));
  21.   printf("%p\n", (void *) fn_strtok(NULL, "?"));
  22.  
  23.   return EXIT_SUCCESS;
  24. }
  25.  
  26. char *fn_strtok(char *str, char const *set)
  27. {
  28.   static char *p;
  29.  
  30.   if (str == NULL)
  31.      str = p;
  32.  
  33.   p = str += strspn(str, set);
  34.   if (*str == '\0')
  35.      str = NULL;
  36.   else {
  37.      p += strcspn(p, set);
  38.  
  39.      if (*p != '\0')
  40.         *p++ = '\0';
  41.   }
  42.  
  43.   return str;
  44. }

Y su salida es:
Código:
"a"
"??b"
"c"
(null)
"a"
"??b"
"c"
(null)

Un saludo


Título: Re: CRT personalizada
Publicado por: 85 en 28 Marzo 2013, 15:27 pm
Yo tenía estas pero esa que postiaste está mucho mejor  ;-)
Código:
char* mi_strtok(char* str, const char* delimiters){

printf("mi_strtok\n");
system("pause");
static char* last;
char* tok;

/* pick up from previous stopping point, if told to do so */
if (str == NULL && (str = last) == NULL) return NULL;

/* skip initial delimiters to find start of token */
tok = str + strspn(str, delimiters);

/* skip over non-delimiters to find end of token */
str = tok + strcspn(tok, delimiters);

/*
* Save state for next call, and return token. If there
* is no token, both *tok and *s will be '\0'. If there
* is one token that is ended with '\0', *s will be '\0'.
* (If there are trailing delimiters, we will skip them
* later.)
*/
last=*str=='\0' ?NULL:str+1;
return *tok=='\0' ?NULL:tok;
}

Código:
char* mi_strtok2(char* input, const char* tokenizer)
{
printf("mi_strtok2\n");
system("pause");
static char* memorizeInput;
bool tokenFound = false;
if(input != NULL)
memorizeInput = input;
else
input = memorizeInput;
if(!(*memorizeInput))
return NULL;
while(*memorizeInput)
{
for(int i=0; i<(int)(strlen(tokenizer)&&!tokenFound);i++){
 
if(*memorizeInput == tokenizer[i])
{
*memorizeInput = 0;
tokenFound = true;
}
}
if(tokenFound)
{
memorizeInput++;
break;
}
memorizeInput++;
}

return input;
}

Código:
char* lastPos = 0;
char token[100];

char* mi_strtok3(char* str, const char* delim)
{
printf("mi_strtok3\n");
system("pause");
if(!str && !lastPos) return 0;
if(!delim) return 0;
if(str)
lastPos = str;
int delim_len = strlen(delim);
char* strt_ptr = lastPos;
int count = 0;
while(*lastPos != '\0')
{
bool is_found = false;
for(int y=0; y<delim_len; y++)
{
if(*(delim + y) == *lastPos)
is_found = true;
}
lastPos++;
if(is_found) break;
count++;
}

if(*lastPos == '\0')
lastPos = 0;

//added to remove empty ones
if(!count)
return mi_strtok3(0, delim);
//
for(int x=0; x<count; x++)
token[x] = *(strt_ptr + x);
token[count] = '\0';
return token;
}

habría que probar con el ejemplo de aquí:
http://www.cplusplus.com/reference/cstring/strtok/
 :rolleyes:



Título: Re: CRT personalizada
Publicado por: BloodSharp en 28 Marzo 2013, 18:00 pm
Si les sirve, encontré un par de funciones de manejo de strings unicode...

Código
  1. /***
  2. *wcscat.c - contains wcscat() and wcscpy()
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       wcscat() appends one wchar_t string onto another.
  8. *       wcscpy() copies one wchar_t string into another.
  9. *
  10. *       wcscat() concatenates (appends) a copy of the source string to the
  11. *       end of the destination string, returning the destination string.
  12. *       Strings are wide-character strings.
  13. *
  14. *       wcscpy() copies the source string to the spot pointed to be
  15. *       the destination string, returning the destination string.
  16. *       Strings are wide-character strings.
  17. *
  18. *******************************************************************************/
  19.  
  20.  
  21. #include <string.h>
  22.  
  23. /***
  24. *wchar_t *wcscat(dst, src) - concatenate (append) one wchar_t string to another
  25. *
  26. *Purpose:
  27. *       Concatenates src onto the end of dest.  Assumes enough
  28. *       space in dest.
  29. *
  30. *Entry:
  31. *       wchar_t *dst - wchar_t string to which "src" is to be appended
  32. *       const wchar_t *src - wchar_t string to be appended to the end of "dst"
  33. *
  34. *Exit:
  35. *       The address of "dst"
  36. *
  37. *Exceptions:
  38. *
  39. *******************************************************************************/
  40.  
  41. wchar_t * __cdecl wcscat (
  42.        wchar_t * dst,
  43.        const wchar_t * src
  44.        )
  45. {
  46.        wchar_t * cp = dst;
  47.  
  48.        while( *cp )
  49.                cp++;                   /* find end of dst */
  50.  
  51.        while( *cp++ = *src++ ) ;       /* Copy src to end of dst */
  52.  
  53.        return( dst );                  /* return dst */
  54.  
  55. }
  56.  
  57.  
  58. /***
  59. *wchar_t *wcscpy(dst, src) - copy one wchar_t string over another
  60. *
  61. *Purpose:
  62. *       Copies the wchar_t string src into the spot specified by
  63. *       dest; assumes enough room.
  64. *
  65. *Entry:
  66. *       wchar_t * dst - wchar_t string over which "src" is to be copied
  67. *       const wchar_t * src - wchar_t string to be copied over "dst"
  68. *
  69. *Exit:
  70. *       The address of "dst"
  71. *
  72. *Exceptions:
  73. *******************************************************************************/
  74.  
  75. wchar_t * __cdecl wcscpy(wchar_t * dst, const wchar_t * src)
  76. {
  77.        wchar_t * cp = dst;
  78.  
  79.        while( *cp++ = *src++ )
  80.                ;               /* Copy src over dst */
  81.  
  82.        return( dst );
  83. }
  84.  
  85.  

Código
  1. /***
  2. *wcschr.c - search a wchar_t string for a given wchar_t character
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcschr() - search a wchar_t string for a wchar_t character
  8. *
  9. *******************************************************************************/
  10.  
  11.  
  12. #include <string.h>
  13.  
  14. /***
  15. *wchar_t *wcschr(string, c) - search a string for a wchar_t character
  16. *
  17. *Purpose:
  18. *       Searches a wchar_t string for a given wchar_t character,
  19. *       which may be the null character L'\0'.
  20. *
  21. *Entry:
  22. *       wchar_t *string - wchar_t string to search in
  23. *       wchar_t c - wchar_t character to search for
  24. *
  25. *Exit:
  26. *       returns pointer to the first occurence of c in string
  27. *       returns NULL if c does not occur in string
  28. *
  29. *Exceptions:
  30. *
  31. *******************************************************************************/
  32.  
  33. wchar_t * __cdecl wcschr (
  34.        const wchar_t * string,
  35.        wchar_t ch
  36.        )
  37. {
  38.        while (*string && *string != (wchar_t)ch)
  39.                string++;
  40.  
  41.        if (*string == (wchar_t)ch)
  42.                return((wchar_t *)string);
  43.        return(NULL);
  44. }
  45.  
  46.  

Código
  1. /***
  2. *wcscmp.c - routine to compare two wchar_t strings (for equal, less, or greater)
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Compares two wide-character strings, determining their lexical order.
  8. *
  9. *******************************************************************************/
  10.  
  11.  
  12. #include <string.h>
  13.  
  14. /***
  15. *wcscmp - compare two wchar_t strings,
  16. *        returning less than, equal to, or greater than
  17. *
  18. *Purpose:
  19. *       wcscmp compares two wide-character strings and returns an integer
  20. *       to indicate whether the first is less than the second, the two are
  21. *       equal, or whether the first is greater than the second.
  22. *
  23. *       Comparison is done wchar_t by wchar_t on an UNSIGNED basis, which is to
  24. *       say that Null wchar_t(0) is less than any other character.
  25. *
  26. *Entry:
  27. *       const wchar_t * src - string for left-hand side of comparison
  28. *       const wchar_t * dst - string for right-hand side of comparison
  29. *
  30. *Exit:
  31. *       returns -1 if src <  dst
  32. *       returns  0 if src == dst
  33. *       returns +1 if src >  dst
  34. *
  35. *Exceptions:
  36. *
  37. *******************************************************************************/
  38.  
  39. int __cdecl wcscmp (
  40.        const wchar_t * src,
  41.        const wchar_t * dst
  42.        )
  43. {
  44.        int ret = 0 ;
  45.  
  46.        while( ! (ret = (int)(*src - *dst)) && *dst)
  47.                ++src, ++dst;
  48.  
  49.        if ( ret < 0 )
  50.                ret = -1 ;
  51.        else if ( ret > 0 )
  52.                ret = 1 ;
  53.  
  54.        return( ret );
  55. }
  56.  
  57.  

Código
  1. /***
  2. *wcslen.c - contains wcslen() routine
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       wcslen returns the length of a null-terminated wide-character string,
  8. *       not including the null wchar_t itself.
  9. *
  10. *******************************************************************************/
  11.  
  12.  
  13. #include <string.h>
  14.  
  15. /***
  16. *wcslen - return the length of a null-terminated wide-character string
  17. *
  18. *Purpose:
  19. *       Finds the length in wchar_t's of the given string, not including
  20. *       the final null wchar_t (wide-characters).
  21. *
  22. *Entry:
  23. *       const wchar_t * wcs - string whose length is to be computed
  24. *
  25. *Exit:
  26. *       length of the string "wcs", exclusive of the final null wchar_t
  27. *
  28. *Exceptions:
  29. *
  30. *******************************************************************************/
  31.  
  32. size_t __cdecl wcslen (
  33.        const wchar_t * wcs
  34.        )
  35. {
  36.        const wchar_t *eos = wcs;
  37.  
  38.        while( *eos++ ) ;
  39.  
  40.        return( (size_t)(eos - wcs - 1) );
  41. }
  42.  
  43.  

Código
  1. /***
  2. *wcsncpy.c - copy at most n characters of wide-character string
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcsncpy() - copy at most n characters of wchar_t string
  8. *
  9. *******************************************************************************/
  10.  
  11.  
  12. #include <string.h>
  13.  
  14. /***
  15. *wchar_t *wcsncpy(dest, source, count) - copy at most n wide characters
  16. *
  17. *Purpose:
  18. *       Copies count characters from the source string to the
  19. *       destination.  If count is less than the length of source,
  20. *       NO NULL CHARACTER is put onto the end of the copied string.
  21. *       If count is greater than the length of sources, dest is padded
  22. *       with null characters to length count (wide-characters).
  23. *
  24. *
  25. *Entry:
  26. *       wchar_t *dest - pointer to destination
  27. *       wchar_t *source - source string for copy
  28. *       size_t count - max number of characters to copy
  29. *
  30. *Exit:
  31. *       returns dest
  32. *
  33. *Exceptions:
  34. *
  35. *******************************************************************************/
  36.  
  37. wchar_t * __cdecl wcsncpy (
  38.        wchar_t * dest,
  39.        const wchar_t * source,
  40.        size_t count
  41.        )
  42. {
  43.        wchar_t *start = dest;
  44.  
  45.        while (count && (*dest++ = *source++))    /* copy string */
  46.                count--;
  47.  
  48.        if (count)                              /* pad out with zeroes */
  49.                while (--count)
  50.                        *dest++ = L'\0';
  51.  
  52.        return(start);
  53. }
  54.  
  55.  

Código
  1. /***
  2. *wcspbrk.c - scans wide character string for a character from control string
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcspbrk()- returns pointer to the first wide-character in
  8. *       a wide-character string in the control string.
  9. *
  10. *******************************************************************************/
  11.  
  12.  
  13. #include <string.h>
  14.  
  15. /***
  16. *wchar_t *wcspbrk(string, control) - scans string for a character from control
  17. *
  18. *Purpose:
  19. *       Returns pointer to the first wide-character in
  20. *       a wide-character string in the control string.
  21. *
  22. *Entry:
  23. *       wchar_t *string - string to search in
  24. *       wchar_t *control - string containing characters to search for
  25. *
  26. *Exit:
  27. *       returns a pointer to the first character from control found
  28. *       in string.
  29. *       returns NULL if string and control have no characters in common.
  30. *
  31. *Exceptions:
  32. *
  33. *******************************************************************************/
  34.  
  35. wchar_t * __cdecl wcspbrk (
  36.        const wchar_t * string,
  37.        const wchar_t * control
  38.        )
  39. {
  40.        wchar_t *wcset;
  41.  
  42.        /* 1st char in control string stops search */
  43.        while (*string) {
  44.            for (wcset = (wchar_t *) control; *wcset; wcset++) {
  45.                if (*wcset == *string) {
  46.                    return (wchar_t *) string;
  47.                }
  48.            }
  49.            string++;
  50.        }
  51.        return NULL;
  52. }
  53.  
  54.  

Código
  1. /***
  2. *wcsrchr.c - find last occurrence of wchar_t character in wide string
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcsrchr() - find the last occurrence of a given character
  8. *       in a string (wide-characters).
  9. *
  10. *******************************************************************************/
  11.  
  12.  
  13. #include <string.h>
  14.  
  15. /***
  16. *wchar_t *wcsrchr(string, ch) - find last occurrence of ch in wide string
  17. *
  18. *Purpose:
  19. *       Finds the last occurrence of ch in string.  The terminating
  20. *       null character is used as part of the search (wide-characters).
  21. *
  22. *Entry:
  23. *       wchar_t *string - string to search in
  24. *       wchar_t ch - character to search for
  25. *
  26. *Exit:
  27. *       returns a pointer to the last occurrence of ch in the given
  28. *       string
  29. *       returns NULL if ch does not occurr in the string
  30. *
  31. *Exceptions:
  32. *
  33. *******************************************************************************/
  34.  
  35. wchar_t * __cdecl wcsrchr (
  36.        const wchar_t * string,
  37.        wchar_t ch
  38.        )
  39. {
  40.        wchar_t *start = (wchar_t *)string;
  41.  
  42.        while (*string++)                       /* find end of string */
  43.                ;
  44.                                                /* search towards front */
  45.        while (--string != start && *string != (wchar_t)ch)
  46.                ;
  47.  
  48.        if (*string == (wchar_t)ch)             /* wchar_t found ? */
  49.                return( (wchar_t *)string );
  50.  
  51.        return(NULL);
  52. }
  53.  
  54.  

Código
  1. /***
  2. *wcsrev.c - reverse a wide-character string in place
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _wcsrev() - reverse a wchar_t string in place (not including
  8. *       L'\0' character)
  9. *
  10. *******************************************************************************/
  11.  
  12.  
  13. #include <string.h>
  14.  
  15. /***
  16. *wchar_t *_wcsrev(string) - reverse a wide-character string in place
  17. *
  18. *Purpose:
  19. *       Reverses the order of characters in the string.  The terminating
  20. *       null character remains in place (wide-characters).
  21. *
  22. *Entry:
  23. *       wchar_t *string - string to reverse
  24. *
  25. *Exit:
  26. *       returns string - now with reversed characters
  27. *
  28. *Exceptions:
  29. *
  30. *******************************************************************************/
  31.  
  32. wchar_t * __cdecl _wcsrev (
  33.        wchar_t * string
  34.        )
  35. {
  36.        wchar_t *start = string;
  37.        wchar_t *left = string;
  38.        wchar_t ch;
  39.  
  40.        while (*string++)                 /* find end of string */
  41.                ;
  42.        string -= 2;
  43.  
  44.        while (left < string)
  45.        {
  46.                ch = *left;
  47.                *left++ = *string;
  48.                *string-- = ch;
  49.        }
  50.  
  51.        return(start);
  52. }
  53.  
  54.  

Código
  1. /***
  2. *wcsspn.c - find length of initial substring of chars from a control string
  3. *       (wide-character strings)
  4. *
  5. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  6. *
  7. *Purpose:
  8. *       defines wcsspn() - finds the length of the initial substring of
  9. *       a string consisting entirely of characters from a control string
  10. *       (wide-character strings).
  11. *
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <string.h>
  16.  
  17. /***
  18. *int wcsspn(string, control) - find init substring of control chars
  19. *
  20. *Purpose:
  21. *       Finds the index of the first character in string that does belong
  22. *       to the set of characters specified by control.  This is
  23. *       equivalent to the length of the initial substring of string that
  24. *       consists entirely of characters from control.  The L'\0' character
  25. *       that terminates control is not considered in the matching process
  26. *       (wide-character strings).
  27. *
  28. *Entry:
  29. *       wchar_t *string - string to search
  30. *       wchar_t *control - string containing characters not to search for
  31. *
  32. *Exit:
  33. *       returns index of first wchar_t in string not in control
  34. *
  35. *Exceptions:
  36. *
  37. *******************************************************************************/
  38.  
  39. size_t __cdecl wcsspn (
  40.        const wchar_t * string,
  41.        const wchar_t * control
  42.        )
  43. {
  44.        wchar_t *str = (wchar_t *) string;
  45.        wchar_t *ctl;
  46.  
  47.        /* 1st char not in control string stops search */
  48.        while (*str) {
  49.            for (ctl = (wchar_t *)control; *ctl != *str; ctl++) {
  50.                if (*ctl == (wchar_t)0) {
  51.                    /*
  52.                      * reached end of control string without finding a match
  53.                      */
  54.                    return str - string;
  55.                }
  56.            }
  57.            str++;
  58.        }
  59.        /*
  60.          * The whole string consisted of characters from control
  61.          */
  62.        return str - string;
  63. }
  64.  
  65.  

Código
  1. /***
  2. *wcsstr.c - search for one wide-character string inside another
  3. *
  4. *       Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcsstr() - search for one wchar_t string inside another
  8. *
  9. *******************************************************************************/
  10.  
  11.  
  12. #include <string.h>
  13.  
  14. /***
  15. *wchar_t *wcsstr(string1, string2) - search for string2 in string1
  16. *       (wide strings)
  17. *
  18. *Purpose:
  19. *       finds the first occurrence of string2 in string1 (wide strings)
  20. *
  21. *Entry:
  22. *       wchar_t *string1 - string to search in
  23. *       wchar_t *string2 - string to search for
  24. *
  25. *Exit:
  26. *       returns a pointer to the first occurrence of string2 in
  27. *       string1, or NULL if string2 does not occur in string1
  28. *
  29. *Uses:
  30. *
  31. *Exceptions:
  32. *
  33. *******************************************************************************/
  34.  
  35. wchar_t * __cdecl wcsstr (
  36.        const wchar_t * wcs1,
  37.        const wchar_t * wcs2
  38.        )
  39. {
  40.        wchar_t *cp = (wchar_t *) wcs1;
  41.        wchar_t *s1, *s2;
  42.  
  43.        while (*cp)
  44.        {
  45.                s1 = cp;
  46.                s2 = (wchar_t *) wcs2;
  47.  
  48.                while ( *s1 && *s2 && !(*s1-*s2) )
  49.                        s1++, s2++;
  50.  
  51.                if (!*s2)
  52.                        return(cp);
  53.  
  54.                cp++;
  55.        }
  56.  
  57.        return(NULL);
  58. }
  59.  
  60.  

Código
  1. /***
  2. *wcstok.c - tokenize a wide-character string with given delimiters
  3. *
  4. *       Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines wcstok() - breaks wide-character string into series of token
  8. *       via repeated calls.
  9. *
  10. *******************************************************************************/
  11.  
  12.  
  13. #include "headers.hxx"
  14.  
  15. #ifndef X_STRING_H_
  16. #define X_STRING_H_
  17. #include <string.h>
  18. #endif
  19.  
  20. /***
  21. *wchar_t *wcstok(string, control) - tokenize string with delimiter in control
  22. *       (wide-characters)
  23. *
  24. *Purpose:
  25. *       wcstok considers the string to consist of a sequence of zero or more
  26. *       text tokens separated by spans of one or more control chars. the first
  27. *       call, with string specified, returns a pointer to the first wchar_t of
  28. *       the first token, and will write a null wchar_t into string immediately
  29. *       following the returned token. subsequent calls with zero for the first
  30. *       argument (string) will work thru the string until no tokens remain. the
  31. *       control string may be different from call to call. when no tokens remain
  32. *       in string a NULL pointer is returned. remember the control chars with a
  33. *       bit map, one bit per wchar_t. the null wchar_t is always a control char
  34. *       (wide-characters).
  35. *
  36. *Entry:
  37. *       wchar_t *string - wchar_t string to tokenize, or NULL to get next token
  38. *       wchar_t *control - wchar_t string of characters to use as delimiters
  39. *
  40. *Exit:
  41. *       returns pointer to first token in string, or if string
  42. *       was NULL, to next token
  43. *       returns NULL when no more tokens remain.
  44. *
  45. *Uses:
  46. *
  47. *Exceptions:
  48. *
  49. *******************************************************************************/
  50.  
  51. wchar_t * __cdecl wcstok (
  52.        wchar_t * string,
  53.        const wchar_t * control
  54.        )
  55. {
  56.    wchar_t *token;
  57.    const wchar_t *ctl;
  58.  
  59.    THREADSTATE *pts = GetThreadState();
  60.  
  61.    /* If string==NULL, continue with previous string */
  62.    if (!string)
  63.        string = pts->wtoken;
  64.  
  65.    /* Find beginning of token (skip over leading delimiters). Note that
  66.      * there is no token iff this loop sets string to point to the terminal
  67.      * null (*string == '\0') */
  68.  
  69.    while (*string) {
  70.            for (ctl=control; *ctl && *ctl != *string; ctl++)
  71.                    ;
  72.            if (!*ctl) break;
  73.            string++;
  74.    }
  75.  
  76.    token = string;
  77.  
  78.    /* Find the end of the token. If it is not the end of the string,
  79.      * put a null there. */
  80.    for ( ; *string ; string++ ) {
  81.            for (ctl=control; *ctl && *ctl != *string; ctl++)
  82.                    ;
  83.            if (*ctl) {
  84.                    *string++ = '\0';
  85.                    break;
  86.            }
  87.    }
  88.  
  89.    /* Update nextoken (or the corresponding field in the per-thread data
  90.      * structure */
  91.    pts->wtoken = string;
  92.  
  93.    /* Determine if a token has been found. */
  94.    if ( token == string )
  95.            return NULL;
  96.    else
  97.            return token;
  98. }
  99.  
  100.  

Código
  1. /***
  2. *wcstol.c - Contains C runtimes wcstol and wcstoul
  3. *
  4. *       Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       wcstol - convert wchar_t string to long signed integer
  8. *       wcstoul - convert wchar_t string to long unsigned integer
  9. *
  10. *******************************************************************************/
  11.  
  12. #include "headers.hxx"
  13.  
  14. #ifndef X_STDLIB_H_
  15. #define X_STDLIB_H_
  16. #include <stdlib.h>
  17. #endif
  18.  
  19. #ifndef X_LIMITS_H_
  20. #define X_LIMITS_H_
  21. #include <limits.h>
  22. #endif
  23.  
  24. #ifndef X_CTYPE_H_
  25. #define X_CTYPE_H_
  26. #include <ctype.h>
  27. #endif
  28.  
  29. /***
  30. *wcstol, wcstoul(nptr,endptr,ibase) - Convert ascii string to long un/signed
  31. *       int.
  32. *
  33. *Purpose:
  34. *       Convert an ascii string to a long 32-bit value.  The base
  35. *       used for the caculations is supplied by the caller.  The base
  36. *       must be in the range 0, 2-36.  If a base of 0 is supplied, the
  37. *       ascii string must be examined to determine the base of the
  38. *       number:
  39. *               (a) First char = '0', second char = 'x' or 'X',
  40. *                   use base 16.
  41. *               (b) First char = '0', use base 8
  42. *               (c) First char in range '1' - '9', use base 10.
  43. *
  44. *       If the 'endptr' value is non-NULL, then wcstol/wcstoul places
  45. *       a pointer to the terminating character in this value.
  46. *       See ANSI standard for details
  47. *
  48. *Entry:
  49. *       nptr == NEAR/FAR pointer to the start of string.
  50. *       endptr == NEAR/FAR pointer to the end of the string.
  51. *       ibase == integer base to use for the calculations.
  52. *
  53. *       string format: [whitespace] [sign] [0] [x] [digits/letters]
  54. *
  55. *Exit:
  56. *       Good return:
  57. *               result
  58. *
  59. *       Overflow return:
  60. *               wcstol -- LONG_MAX or LONG_MIN
  61. *               wcstoul -- ULONG_MAX
  62. *               wcstol/wcstoul -- errno == ERANGE
  63. *
  64. *       No digits or bad base return:
  65. *               0
  66. *               endptr = nptr*
  67. *
  68. *Exceptions:
  69. *       None.
  70. *******************************************************************************/
  71.  
  72. /* flag values */
  73. #define FL_UNSIGNED   1       /* wcstoul called */
  74. #define FL_NEG        2       /* negative sign found */
  75. #define FL_OVERFLOW   4       /* overflow occured */
  76. #define FL_READDIGIT  8       /* we've read at least one correct digit */
  77.  
  78. #pragma warning (disable: 4305)
  79. #pragma warning (disable: 4306)
  80.  
  81. static unsigned long __cdecl wcstoxl (
  82.        const wchar_t *nptr,
  83.        wchar_t **endptr,
  84.        int ibase,
  85.        int flags
  86.        )
  87. {
  88.        const wchar_t *p;
  89.        wchar_t c;
  90.        unsigned long number;
  91.        unsigned digval;
  92.        unsigned long maxval;
  93.  
  94.        p = nptr;                       /* p is our scanning pointer */
  95.        number = 0;                     /* start with zero */
  96.  
  97.        c = *p++;                       /* read char */
  98.        while (_istspace(c))
  99.                c = *p++;               /* skip whitespace */
  100.  
  101.        if (c == '-') {
  102.                flags |= FL_NEG;        /* remember minus sign */
  103.                c = *p++;
  104.        }
  105.        else if (c == '+')
  106.                c = *p++;               /* skip sign */
  107.  
  108.        if (ibase < 0 || ibase == 1 || ibase > 36) {
  109.                /* bad base! */
  110.                if (endptr)
  111.                        /* store beginning of string in endptr */
  112.                        *endptr = (wchar_t *)nptr;
  113.                return 0L;              /* return 0 */
  114.        }
  115.        else if (ibase == 0) {
  116.                /* determine base free-lance, based on first two chars of
  117.                    string */
  118.                if (c != L'0')
  119.                        ibase = 10;
  120.                else if (*p == L'x' || *p == L'X')
  121.                        ibase = 16;
  122.                else
  123.                        ibase = 8;
  124.        }
  125.  
  126.        if (ibase == 16) {
  127.                /* we might have 0x in front of number; remove if there */
  128.                if (c == L'0' && (*p == L'x' || *p == L'X')) {
  129.                        ++p;
  130.                        c = *p++;       /* advance past prefix */
  131.                }
  132.        }
  133.  
  134.        /* if our number exceeds this, we will overflow on multiply */
  135.        maxval = ULONG_MAX / ibase;
  136.  
  137.  
  138.        for (;;) {      /* exit in middle of loop */
  139.                /* convert c to value */
  140.                if (_istdigit(c))
  141.                        digval = c - L'0';
  142.                else if (_istalpha(c))
  143.                        digval = (TCHAR)CharUpper((LPTSTR)c) - L'A' + 10;
  144.                else
  145.                        break;
  146.                if (digval >= (unsigned)ibase)
  147.                        break;          /* exit loop if bad digit found */
  148.  
  149.                /* record the fact we have read one digit */
  150.                flags |= FL_READDIGIT;
  151.  
  152.                /* we now need to compute number = number * base + digval,
  153.                    but we need to know if overflow occured.  This requires
  154.                    a tricky pre-check. */
  155.  
  156.                if (number < maxval || (number == maxval &&
  157.                (unsigned long)digval <= ULONG_MAX % ibase)) {
  158.                        /* we won't overflow, go ahead and multiply */
  159.                        number = number * ibase + digval;
  160.                }
  161.                else {
  162.                        /* we would have overflowed -- set the overflow flag */
  163.                        flags |= FL_OVERFLOW;
  164.                }
  165.  
  166.                c = *p++;               /* read next digit */
  167.        }
  168.  
  169.        --p;                            /* point to place that stopped scan */
  170.  
  171.        if (!(flags & FL_READDIGIT)) {
  172.                /* no number there; return 0 and point to beginning of
  173.                    string */
  174.                if (endptr)
  175.                        /* store beginning of string in endptr later on */
  176.                        p = nptr;
  177.                number = 0L;            /* return 0 */
  178.        }
  179.        else if ( (flags & FL_OVERFLOW) ||
  180.                  ( !(flags & FL_UNSIGNED) &&
  181.                    ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) ||
  182.                      ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) )
  183.        {
  184.                /* overflow or signed overflow occurred */
  185.                //errno = ERANGE;
  186.                if ( flags & FL_UNSIGNED )
  187.                        number = ULONG_MAX;
  188.                else if ( flags & FL_NEG )
  189.                        number = (unsigned long)(-LONG_MIN);
  190.                else
  191.                        number = LONG_MAX;
  192.        }
  193.  
  194.        if (endptr != NULL)
  195.                /* store pointer to char that stopped the scan */
  196.                *endptr = (wchar_t *)p;
  197.  
  198.        if (flags & FL_NEG)
  199.                /* negate result if there was a neg sign */
  200.                number = (unsigned long)(-(long)number);
  201.  
  202.        return number;                  /* done. */
  203. }
  204.  
  205. #pragma warning (default: 4305)
  206. #pragma warning (default: 4306)
  207.  
  208. long __cdecl wcstol (
  209.        const wchar_t *nptr,
  210.        wchar_t **endptr,
  211.        int ibase
  212.        )
  213. {
  214.        return (long) wcstoxl(nptr, endptr, ibase, 0);
  215. }
  216.  
  217. unsigned long __cdecl wcstoul (
  218.        const wchar_t *nptr,
  219.        wchar_t **endptr,
  220.        int ibase
  221.        )
  222. {
  223.        return wcstoxl(nptr, endptr, ibase, FL_UNSIGNED);
  224. }
  225.  
  226.  


B#