Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.5 KiB

  1. /*
  2. ** dbcs.c - DBCS functions for DOS apps.
  3. **
  4. ** Written by RokaH and DavidDi.
  5. */
  6. /* Headers
  7. **********/
  8. #include <dos.h>
  9. #include <ctype.h>
  10. #include <dbcs.h>
  11. /*
  12. ** int IsDBCSLeadByte(unsigned char uch);
  13. **
  14. ** Check to see if a character is a DBCS lead byte.
  15. **
  16. ** Arguments: uch - charcter to examine
  17. **
  18. ** Returns: int - 1 if the character is a DBCS lead byte. 0 if not.
  19. **
  20. ** Globals: none
  21. */
  22. int IsDBCSLeadByte(unsigned char uch)
  23. {
  24. static unsigned char far *DBCSLeadByteTable = 0;
  25. union REGS inregs, outregs;
  26. struct SREGS segregs;
  27. unsigned char far *puch;
  28. if (DBCSLeadByteTable == 0)
  29. {
  30. /*
  31. ** Get DBCS lead byte table. This function has been supported since
  32. ** DBCS MS-DOS 2.21.
  33. */
  34. inregs.x.ax = 0x6300;
  35. intdosx(&inregs, &outregs, &segregs);
  36. FP_OFF(DBCSLeadByteTable) = outregs.x.si;
  37. FP_SEG(DBCSLeadByteTable) = segregs.ds;
  38. }
  39. /* See if the given byte is in any of the table's lead byte ranges. */
  40. for (puch = DBCSLeadByteTable; puch[0] || puch[1]; puch += 2)
  41. if (uch >= puch[0] && uch <= puch[1])
  42. return(1);
  43. return(0);
  44. }
  45. /*
  46. ** unsigned char *AnsiNext(unsigned char *puch);
  47. **
  48. ** Moves to the next character in a string.
  49. **
  50. ** Arguments: puch - pointer to current location in string
  51. **
  52. ** Returns: char * - Pointer to next character in string.
  53. **
  54. ** Globals: none
  55. **
  56. ** N.b., if puch points to a null character, AnsiNext() will return puch.
  57. */
  58. unsigned char far *AnsiNext(unsigned char far *puch)
  59. {
  60. if (*puch == '\0')
  61. return(puch);
  62. else if (IsDBCSLeadByte(*puch))
  63. puch++;
  64. puch++;
  65. return(puch);
  66. }
  67. /*
  68. ** unsigned char *AnsiPrev(unsigned char *psz, unsigned char *puch);
  69. **
  70. ** Moves back one character in a string.
  71. **
  72. ** Arguments: psz - pointer to start of string
  73. ** puch - pointer to current location in string
  74. **
  75. ** Returns: char * - Pointer to previous character in string.
  76. **
  77. ** Globals: none
  78. **
  79. ** N.b., if puch <= psz, AnsiPrev() will return psz.
  80. **
  81. ** This function is implemented in a very slow fashion because we do not wish
  82. ** to trust that the given string is necessarily DBCS "safe," i.e., contains
  83. ** only single-byte characters and valid DBCS characters. So we start from
  84. ** the beginning of the string and work our way forward.
  85. */
  86. unsigned char far *AnsiPrev(unsigned char far *psz, unsigned char far *puch)
  87. {
  88. unsigned char far *puchPrevious;
  89. do
  90. {
  91. puchPrevious = psz;
  92. psz = AnsiNext(psz);
  93. } while (*psz != '\0' && psz < puch);
  94. return(puchPrevious);
  95. }
  96.