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.

309 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. mcutil.c
  5. Abstract:
  6. This file contains utility functions for the Win32 Message Compiler (MC)
  7. Author:
  8. Steve Wood (stevewo) 22-Aug-1991
  9. Revision History:
  10. --*/
  11. #include "mc.h"
  12. typedef BOOL (*PISTEXTUNICODE_ROUTINE)(
  13. CONST LPVOID lpBuffer,
  14. size_t cb,
  15. LPINT lpi
  16. );
  17. PISTEXTUNICODE_ROUTINE OptionalIsTextUnicode = NULL;
  18. BOOL
  19. DefaultIsTextUnicode(
  20. CONST LPVOID lpBuffer,
  21. size_t cb,
  22. LPINT lpi
  23. )
  24. {
  25. return FALSE;
  26. }
  27. PNAME_INFO
  28. McAddName(
  29. PNAME_INFO *NameListHead,
  30. WCHAR *Name,
  31. ULONG Id,
  32. PVOID Value
  33. )
  34. {
  35. PNAME_INFO p;
  36. int n;
  37. while (p = *NameListHead) {
  38. if (!(n = _wcsicmp( p->Name, Name ))) {
  39. if (p->Id != Id) {
  40. McInputErrorW( L"Redefining value of %s", FALSE, Name );
  41. }
  42. p->Id = Id;
  43. p->Value = Value;
  44. p->Used = FALSE;
  45. return( p );
  46. } else if (n < 0) {
  47. break;
  48. }
  49. NameListHead = &p->Next;
  50. }
  51. p = malloc( sizeof( *p ) + ( wcslen( Name ) + 1 ) * sizeof( WCHAR ) );
  52. if (!p) {
  53. McInputErrorA( "Out of memory capturing name.", TRUE, NULL );
  54. return( NULL );
  55. }
  56. p->LastId = 0;
  57. p->Id = Id;
  58. p->Value = Value;
  59. p->Used = FALSE;
  60. p->CodePage = GetOEMCP();
  61. wcscpy( p->Name, Name );
  62. p->Next = *NameListHead;
  63. *NameListHead = p;
  64. return( p );
  65. }
  66. PNAME_INFO
  67. McFindName(
  68. PNAME_INFO NameListHead,
  69. WCHAR *Name
  70. )
  71. {
  72. PNAME_INFO p;
  73. p = NameListHead;
  74. while (p) {
  75. if (!_wcsicmp( p->Name, Name )) {
  76. p->Used = TRUE;
  77. break;
  78. }
  79. p = p->Next;
  80. }
  81. return( p );
  82. }
  83. BOOL
  84. McCharToInteger(
  85. WCHAR *String,
  86. int Base,
  87. PULONG Value
  88. )
  89. {
  90. WCHAR c;
  91. ULONG Result, Digit, Shift;
  92. c = *String++;
  93. if (!Base) {
  94. Base = 10;
  95. Shift = 0;
  96. if (c == L'0') {
  97. c = *String++;
  98. if (c == L'x') {
  99. Base = 16;
  100. Shift = 4;
  101. } else if (c == L'o') {
  102. Base = 8;
  103. Shift = 3;
  104. } else if (c == L'b') {
  105. Base = 2;
  106. Shift = 1;
  107. } else {
  108. String--;
  109. }
  110. c = *String++;
  111. }
  112. } else {
  113. switch( Base ) {
  114. case 16: Shift = 4; break;
  115. case 8: Shift = 3; break;
  116. case 2: Shift = 1; break;
  117. case 10: Shift = 0; break;
  118. default: return( FALSE );
  119. }
  120. }
  121. Result = 0;
  122. while (c) {
  123. if (c >= L'0' && c <= L'9') {
  124. Digit = c - L'0';
  125. }
  126. else if (c >= L'A' && c <= L'F') {
  127. Digit = c - L'A' + 10;
  128. }
  129. else if (c >= L'a' && c <= L'f') {
  130. Digit = c - L'a' + 10;
  131. } else {
  132. break;
  133. }
  134. if ((int)Digit >= Base) {
  135. break;
  136. }
  137. if (Shift == 0) {
  138. Result = (Base * Result) + Digit;
  139. } else {
  140. Result = (Result << Shift) | Digit;
  141. }
  142. c = *String++;
  143. }
  144. *Value = Result;
  145. return( TRUE );
  146. }
  147. WCHAR *
  148. McMakeString(
  149. WCHAR *String
  150. )
  151. {
  152. WCHAR *s;
  153. s = malloc( ( wcslen( String ) + 1 ) * sizeof( WCHAR ) );
  154. if (!s) {
  155. McInputErrorA( "Out of memory copying string.", TRUE, String );
  156. return NULL;
  157. }
  158. wcscpy( s, String );
  159. return( s );
  160. }
  161. BOOL
  162. IsFileUnicode (char * fName)
  163. {
  164. #define CCH_READ_MAX 200
  165. size_t cbRead;
  166. INT value = 0xFFFFFFFF;
  167. FILE *fp;
  168. LPVOID lpBuf;
  169. BOOL result;
  170. if (OptionalIsTextUnicode == NULL) {
  171. OptionalIsTextUnicode = (PISTEXTUNICODE_ROUTINE)GetProcAddress( LoadLibrary( "ADVAPI32.DLL" ), "IsTextUnicode" );
  172. if (OptionalIsTextUnicode == NULL) {
  173. OptionalIsTextUnicode = DefaultIsTextUnicode;
  174. }
  175. }
  176. if ( ( fp = fopen( fName, "rb" ) ) == NULL )
  177. return (FALSE);
  178. lpBuf = malloc( CCH_READ_MAX + 10 );
  179. if (!lpBuf) {
  180. fclose( fp );
  181. return( FALSE );
  182. }
  183. cbRead = fread( lpBuf, 1, CCH_READ_MAX, fp );
  184. result = (*OptionalIsTextUnicode)( lpBuf, cbRead, &value );
  185. fclose( fp );
  186. free( lpBuf );
  187. return( result );
  188. }
  189. BOOL
  190. MyIsDBCSLeadByte(UCHAR c)
  191. {
  192. int i;
  193. CPINFO* PCPInfo = &CPInfo;
  194. if (PCPInfo == NULL) {
  195. return FALSE;
  196. }
  197. if (!PCPInfo->MaxCharSize) {
  198. return(IsDBCSLeadByte(c));
  199. }
  200. if (PCPInfo->MaxCharSize == 1) {
  201. return FALSE;
  202. }
  203. for (i=0 ; i<MAX_LEADBYTES ; i+=2) {
  204. if (PCPInfo->LeadByte[i] == 0 && PCPInfo->LeadByte[i+1] == 0)
  205. return FALSE;
  206. if (c >= PCPInfo->LeadByte[i] && c <= PCPInfo->LeadByte[i+1])
  207. return TRUE;
  208. }
  209. return FALSE;
  210. }
  211. WCHAR *
  212. fgetsW (WCHAR * string, long count, FILE * fp)
  213. {
  214. UCHAR ch[2];
  215. WCHAR *pch = string;
  216. DWORD nBytesRead;
  217. assert (string != NULL);
  218. assert (fp != NULL);
  219. if (count <= 0)
  220. return (NULL);
  221. while (--count) {
  222. if (UnicodeInput) {
  223. nBytesRead = fread (ch, 1, sizeof(WCHAR), fp);
  224. } else {
  225. nBytesRead = fread (ch, 1, 1, fp);
  226. ch[1] = '\0';
  227. }
  228. //
  229. // if there are no more characters, end the line
  230. //
  231. if (feof (fp)) {
  232. if (pch == string)
  233. return (NULL);
  234. break;
  235. }
  236. if (ch[0] < 128 || UnicodeInput) {
  237. *pch = *(WCHAR*)&ch[0];
  238. } else if (MyIsDBCSLeadByte(ch[0])) {
  239. nBytesRead = fread (&ch[1], 1, 1, fp);
  240. MultiByteToWideChar(CurrentLanguageName->CodePage, 0, ch, 2, pch, 1);
  241. } else {
  242. MultiByteToWideChar(CurrentLanguageName->CodePage, 0, ch, 1, pch, 1);
  243. }
  244. pch++;
  245. if (*(pch-1) == L'\n') {
  246. break;
  247. }
  248. }
  249. *pch = L'\0';
  250. return (string);
  251. }