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.

326 lines
8.1 KiB

  1. /********************************************************************
  2. TITLE: UTILIB.CPP
  3. OWNER: johnrush (John C. Rush)
  4. DATE CREATED: January 29, 1997
  5. DESCRIPTION:
  6. This is the source file for the utility library; its
  7. associated header is utilib.h. This module will contain
  8. all sorts of general purpose utility functions.
  9. *********************************************************************/
  10. #include <mvopsys.h>
  11. #ifdef _DEBUG
  12. static char * s_aszModule = __FILE__; /* For error report */
  13. #endif
  14. #include <orkin.h>
  15. #include <iterror.h>
  16. #include <_mvutil.h> // BlockCopy
  17. #include "cmdint.h"
  18. #include "cierror.h"
  19. #include "..\svutil.h"
  20. extern HINSTANCE _hInstITCC;
  21. /**************************************************
  22. DESCRIPTION:
  23. This routine strips the trailing blanks from
  24. a null-terminated string. It then returns
  25. the string so that this routine will have the
  26. side effect of actually altering its parameter.
  27. The rationale for the approach used here -- begin
  28. at the front of the string and count through,
  29. rather than start at the end and count down until
  30. a non-blank character is hit, and then back up --
  31. is that in order to start at the end of the string,
  32. strlen() must already have counted through it
  33. once. This way, we only have to look at the
  34. characters in the string once.
  35. MATTSMI 5/21/92 -- ENHANCED TO ALSO STRIP TABS.
  36. ***************************************************/
  37. LPWSTR WINAPI StripTrailingBlanks(LPWSTR sz)
  38. {
  39. LPWSTR pChar;
  40. LPWSTR pSpace=NULL;
  41. pChar=sz;
  42. while (*pChar) {
  43. if ( *pChar == L' ' || *pChar == L'\t' || *pChar == 0x1A /*CTL_Z*/)
  44. {
  45. if (!pSpace)
  46. pSpace=pChar;
  47. }
  48. else
  49. pSpace=NULL;
  50. ++pChar;
  51. }
  52. if (pSpace)
  53. *pSpace = L'\0';
  54. return(sz);
  55. } /* StripTrailingBlanks */
  56. /**************************************************
  57. DATE DOCUMENTED: April 3, 1992
  58. @doc INTERNAL
  59. @api LPWSTR | SkipWhitespace | incrementes the
  60. passed-in pointer past all leading blanks.
  61. @parm LPWSTR | pch | pointer to be incremented.
  62. @comm
  63. MATTSMI 5/21/92 enhanced to also increment past tabs.
  64. ***************************************************/
  65. LPWSTR WINAPI SkipWhitespace(LPWSTR lpwstrIn)
  66. {
  67. while (*lpwstrIn == L' ' || *lpwstrIn == L'\t')
  68. ++lpwstrIn;
  69. return lpwstrIn;
  70. } /* SkipWhitespace */
  71. /**************************************************
  72. DESCRIPTION:
  73. This routine strips all Leading blanks from
  74. a string and then scoots it over so that it
  75. begins at the original address.
  76. Note: obviously, a side effect of this routine
  77. is that the original string parameter is altered.
  78. ***************************************************/
  79. VOID WINAPI StripLeadingBlanks(LPWSTR pchSource)
  80. { /*** StripLeadingBlanks ***/
  81. LPWSTR pchSeeker;
  82. pchSeeker=pchSource;
  83. /****************************
  84. * FIND FIRST NON-BLANK CHAR
  85. ****************************/
  86. while (*pchSeeker == L' ' || *pchSeeker == L'\t')
  87. ++pchSeeker;
  88. /************************
  89. IF THE FIRST NON-BLANK IS
  90. NOT THE FIRST CHARACTER . . .
  91. *************************/
  92. if (pchSeeker != pchSource) {
  93. /********************
  94. SCOOT ALL BYTES DOWN
  95. ********************/
  96. for (;;) {
  97. if ((*pchSource=*pchSeeker) == 0)
  98. break;
  99. ++pchSource;
  100. ++pchSeeker;
  101. }
  102. }
  103. } /* StripLeadingBlanks */
  104. /**************************************************
  105. AUTHOR: Matthew Warren Smith.
  106. January 17, 1992
  107. DESCRIPTION:
  108. This routine scans a null-terminated string
  109. attempting to determine if it consists entirely
  110. of digits -- ie it will be able to be converted
  111. into a number by atol without error.
  112. ***************************************************/
  113. BOOL WINAPI IsStringOfDigits(char *szNumericString)
  114. {
  115. int i=0;
  116. while (szNumericString[i])
  117. {
  118. if (!isdigit( (int)(szNumericString[i])))
  119. return(FALSE);
  120. else
  121. i++;
  122. }
  123. return(TRUE);
  124. } /* IsStringOfDigits */
  125. /*--------------------------------------------------------------------------*/
  126. LONG WINAPI StrToLong (LPWSTR lszBuf)
  127. {
  128. register LONG Result; // Returned result
  129. register int i; // Scratch variable
  130. char fGetSign = 1;
  131. /* Skip all blanks, tabs, <CR> */
  132. if (*lszBuf == '-') {
  133. fGetSign = -1;
  134. lszBuf++;
  135. }
  136. else if (*lszBuf == '+')
  137. lszBuf++;
  138. Result = 0;
  139. /* The credit of this piece of code goes to Leon */
  140. while (i = *lszBuf - '0', i >= 0 && i <= 9) {
  141. Result = Result * 10 + i;
  142. lszBuf++;
  143. }
  144. return (Result * fGetSign);
  145. }
  146. #if 0
  147. BOOL WINAPI IgnoreWarning (int errCode, PWARNIGNORE pWarnIgnore)
  148. {
  149. int fRet = FALSE;
  150. WORD i;
  151. LPWORD pwWarnings;
  152. if (NULL == pWarnIgnore || NULL == pWarnIgnore->hMem)
  153. return FALSE;
  154. if (NULL == (pwWarnings = (LPWORD)_GLOBALLOCK (pWarnIgnore->hMem)))
  155. return FALSE;
  156. for (i = 0; i < pWarnIgnore->cbWarning && fRet == FALSE; i++)
  157. if (*(pwWarnings + i) == (WORD)errCode)
  158. fRet = TRUE;
  159. _GLOBALUNLOCK (pWarnIgnore->hMem);
  160. return fRet;
  161. }
  162. #endif
  163. int WINAPI ReportError (IStream *piistm, ERRC &errc)
  164. {
  165. if (NULL == piistm)
  166. return S_OK;
  167. int errCode = errc.errCode, iLevel;
  168. ULONG ulCount;
  169. char rgchLocalBuf[1024];
  170. /***************************
  171. MODULO THE ERROR NUMBER WITH
  172. 5 TO GET THE WARNING LEVEL,
  173. BUT SET FATAL ERRORS TO -1
  174. SO THAT THEY ALWAYS APPEAR.
  175. ****************************/
  176. if (errCode > 30000)
  177. iLevel = -2; // Status message
  178. else
  179. {
  180. iLevel = (errCode % 5);
  181. if (iLevel == 4 || (errCode % 1000 == 0))
  182. iLevel = -1; // Error message
  183. }
  184. switch (iLevel)
  185. {
  186. case -2:
  187. STRCPY (rgchLocalBuf, "\n");
  188. break;
  189. case -1:
  190. wsprintf (rgchLocalBuf, "\nError %d: ", errCode);
  191. break;
  192. default:
  193. wsprintf (rgchLocalBuf, "\nWarning %d: ", errCode);
  194. break;
  195. }
  196. piistm->Write
  197. (rgchLocalBuf, (DWORD) STRLEN (rgchLocalBuf), &ulCount);
  198. if (LoadString (_hInstITCC, errCode, rgchLocalBuf, 1024 * sizeof (char)))
  199. wsprintf (rgchLocalBuf, rgchLocalBuf, errc.var1, errc.var2, errc.var3);
  200. else
  201. STRCPY (rgchLocalBuf,
  202. "Error string could not be loaded from resource file.");
  203. piistm->Write (rgchLocalBuf, (DWORD) STRLEN (rgchLocalBuf), &ulCount);
  204. piistm->Write (".\r\n", (DWORD) STRLEN (".\r\n"), &ulCount);
  205. return (errCode);
  206. } /* ReportError */
  207. LPWSTR GetNextDelimiter(LPWSTR pwstrStart, WCHAR wcDelimiter)
  208. {
  209. for (; *pwstrStart; pwstrStart++)
  210. {
  211. if(*pwstrStart == wcDelimiter)
  212. return pwstrStart;
  213. }
  214. return NULL;
  215. } /* GetNextDelimiter */
  216. HRESULT ParseKeyAndValue(LPVOID pBlockMgr, LPWSTR pwstrLine, KEYVAL **ppkvOut)
  217. {
  218. ITASSERT(pwstrLine);
  219. // Extract key
  220. LPWSTR pwstrKey = SkipWhitespace(pwstrLine);
  221. LPWSTR pwstrValue = GetNextDelimiter(pwstrKey, TOKEN_EQUAL);
  222. if (NULL == pwstrValue)
  223. // No delimiter!
  224. return E_FAIL;
  225. if (NULL == (*ppkvOut = (KEYVAL *)
  226. BlockCopy(pBlockMgr, NULL, sizeof(KEYVAL), 0)))
  227. return E_OUTOFMEMORY;
  228. KEYVAL *pkvOut = *ppkvOut;
  229. if (NULL == (pkvOut->pwstrKey = (LPWSTR)BlockCopy(pBlockMgr,
  230. (LPB)pwstrKey, sizeof (WCHAR) * (DWORD)(pwstrValue - pwstrKey + 1), 0)))
  231. return SetErrReturn(E_OUTOFMEMORY);
  232. pkvOut->pwstrKey[pwstrValue - pwstrKey] = TOKEN_NULL;
  233. StripTrailingBlanks(pkvOut->pwstrKey);
  234. LPWSTR pwstrNextValue;
  235. LPWSTR *plpv = (LPWSTR *)pkvOut->vaValue.Argv;
  236. for (DWORD dwArgCount = 1; ;
  237. dwArgCount++, pwstrValue = pwstrNextValue, plpv++)
  238. {
  239. pwstrValue = SkipWhitespace(pwstrValue + 1);
  240. pwstrNextValue = GetNextDelimiter(pwstrValue, TOKEN_DELIM);
  241. if (NULL == pwstrNextValue)
  242. break;
  243. if (NULL == (*plpv =
  244. (LPWSTR)BlockCopy(pBlockMgr, (LPB)pwstrValue,
  245. sizeof (WCHAR) * (DWORD)(pwstrNextValue - pwstrValue + 1), 0)))
  246. return SetErrReturn(E_OUTOFMEMORY);
  247. (*plpv)[pwstrNextValue - pwstrValue] = TOKEN_NULL;
  248. StripTrailingBlanks(*plpv);
  249. }
  250. if (NULL == (*plpv = (LPWSTR)BlockCopy
  251. (pBlockMgr, (LPB)pwstrValue, (DWORD) WSTRCB(pwstrValue), 0)))
  252. return SetErrReturn(E_OUTOFMEMORY);
  253. StripTrailingBlanks(*plpv);
  254. pkvOut->vaValue.dwArgc = dwArgCount;
  255. return S_OK;
  256. } /* ParseKeyAndValue */