Windows NT 4.0 source code leak
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.

365 lines
11 KiB

4 years ago
  1. /****************************************************************************/
  2. /* */
  3. /* RCSTRING.C - */
  4. /* */
  5. /* StringTable and Accelerators Parsing Code */
  6. /* */
  7. /****************************************************************************/
  8. #include "rc.h"
  9. PRESINFO pResString = NULL; /* Used to add a stringtable */
  10. /* at the end of processing if a stringtable */
  11. /* was found. */
  12. static PRCSTRING pSTHeader;
  13. /* Ptr to the start of the parsed STRINGTABLE. */
  14. /*--------------------------------------------------------------------------*/
  15. /* */
  16. /* MyFAlloc() - */
  17. /* */
  18. /*--------------------------------------------------------------------------*/
  19. PCHAR MyFAlloc(UINT cb, PCHAR pb)
  20. {
  21. PCHAR pbT;
  22. pbT = (PCHAR)MyAlloc(cb);
  23. if (!pbT)
  24. quit("RC : fatal error RW1025: Out of heap memory");
  25. if (pb) {
  26. PCHAR pbTT = pbT;
  27. while (cb--)
  28. *pbTT++ = *pb++;
  29. }
  30. else {
  31. PCHAR pbTT = pbT;
  32. while (cb--)
  33. *pbTT++ = 0;
  34. }
  35. return pbT;
  36. }
  37. /*--------------------------------------------------------------------------*/
  38. /* */
  39. /* GetTable() - */
  40. /* */
  41. /*--------------------------------------------------------------------------*/
  42. PRESINFO GetTable(PRESINFO pResTemp)
  43. {
  44. PRCSTRING pCurrent;
  45. PRCSTRING pTrailer;
  46. CHAR bDone = FALSE;
  47. USHORT nStringID;
  48. PWCHAR p;
  49. PSYMINFO pCurrentSymbol;
  50. PreBeginParse(pResTemp, 2105);
  51. /* Does a string table already exist? */
  52. if (pResString == NULL) {
  53. /* No, start at the beginning - otherwise append. */
  54. pTrailer = (PRCSTRING)NULL;
  55. pSTHeader = (PRCSTRING)NULL;
  56. }
  57. do {
  58. pCurrent = pSTHeader;
  59. bDone = FALSE;
  60. if (token.type != NUMLIT)
  61. ParseError1(2149); //"Expected numeric constant in string table "
  62. nStringID = token.val;
  63. pCurrentSymbol = (SYMINFO*)MyFAlloc(sizeof(token.sym), (char*)&token.sym);
  64. if (!GetFullExpression(&nStringID, GFE_ZEROINIT | GFE_SHORT))
  65. ParseError1(2110); //"Expected numeric constant in v table "
  66. if (token.type == COMMA)
  67. GetToken(TOKEN_NOEXPRESSION);
  68. if (token.type != LSTRLIT)
  69. ParseError1(2150);
  70. tokenbuf[token.val + 1] = 0;
  71. while (!bDone && pCurrent) {
  72. if (pCurrent->language == pResTemp->language) {
  73. if (pCurrent->hibits == (USHORT)(nStringID / BLOCKSIZE)) {
  74. bDone = TRUE;
  75. if (!(pCurrent->rgsz[nStringID % BLOCKSIZE])) {
  76. p = (WCHAR*)MyFAlloc(
  77. sizeof(WCHAR) * (token.val + 2),
  78. (PCHAR)tokenbuf);
  79. pCurrent->rgsz[nStringID % BLOCKSIZE] = p;
  80. pCurrent->rgsym[nStringID % BLOCKSIZE] = pCurrentSymbol;
  81. }
  82. else
  83. ParseError1(2151);
  84. }
  85. }
  86. pTrailer = pCurrent;
  87. pCurrent = pCurrent->next;
  88. }
  89. if (!bDone) { /* and thus pCurrent == (PCHAR)NULL */
  90. pCurrent = (PRCSTRING)MyFAlloc(
  91. sizeof(RCSTRING), (PCHAR)NULL);
  92. pCurrent->hibits = (short)(nStringID / BLOCKSIZE);
  93. pCurrent->flags = pResTemp->flags;
  94. pCurrent->language = pResTemp->language;
  95. pCurrent->version = pResTemp->version;
  96. pCurrent->characteristics = pResTemp->characteristics;
  97. p = pCurrent->rgsz[nStringID%BLOCKSIZE] =
  98. (WCHAR * )MyFAlloc(sizeof(WCHAR) * (token.val + 2),
  99. (PCHAR)tokenbuf);
  100. pCurrent->rgsym[nStringID%BLOCKSIZE] = pCurrentSymbol;
  101. if (pTrailer)
  102. pTrailer->next = pCurrent;
  103. if (!pSTHeader)
  104. pSTHeader = pCurrent; /* First time only */
  105. }
  106. GetToken(TRUE);
  107. } while (token.type != END);
  108. pResString = pResTemp;
  109. return pResString;
  110. }
  111. /*--------------------------------------------------------------------------*/
  112. /* */
  113. /* WriteTable() - */
  114. /* */
  115. /*--------------------------------------------------------------------------*/
  116. VOID WriteTable(PRESINFO pResOld)
  117. {
  118. PRCSTRING p;
  119. int i;
  120. PRESINFO pRes;
  121. PTYPEINFO pType;
  122. int n;
  123. PWCHAR s;
  124. UINT nBytesWritten;
  125. /* Start at the start of the proper table. */
  126. p = pSTHeader;
  127. while (p) {
  128. nBytesWritten = 0;
  129. CtlInit();
  130. // 'STR#' resource starts with a count of strings
  131. if (fMacRsrcs)
  132. WriteWord(BLOCKSIZE);
  133. /* Write out the next block. */
  134. for (i = 0; i < BLOCKSIZE; i++) {
  135. n = 0;
  136. s = p->rgsz[i];
  137. if (fMacRsrcs) {
  138. WriteMacString(s, TRUE, TRUE);
  139. continue;
  140. }
  141. if (s) {
  142. while (s[n] || s[n + 1])
  143. n++; // szsz terminated
  144. if (fAppendNull)
  145. n++;
  146. }
  147. nBytesWritten += sizeof(WCHAR) * (n + 1);
  148. WriteWord((WORD)n);
  149. while (n--)
  150. WriteWord(*s++);
  151. }
  152. pRes = (RESINFO * )MyAlloc(sizeof(RESINFO));
  153. pRes->language = p->language;
  154. pRes->version = p->version;
  155. pRes->characteristics = p->characteristics;
  156. pType = AddResType(NULL, RT_STRING);
  157. pRes->size = nBytesWritten;
  158. /* Mark the resource as Moveable and Discardable. */
  159. pRes->flags = p->flags;
  160. /*We're in an origin 1 world here*/
  161. pRes->nameord = (short)(p->hibits + 1);
  162. SaveResFile(pType, pRes);
  163. {
  164. SYMINFO s;
  165. memset(&s, 0, sizeof(s));
  166. WriteResInfo(pRes, pType, FALSE);
  167. for (i=0; i < BLOCKSIZE; i++)
  168. {
  169. WriteSymbolUse(p->rgsym[i] != NULL && p->rgsz[i][0] != '\0' ? p->rgsym[i] : &s);
  170. }
  171. WriteResInfo(NULL, NULL, FALSE);
  172. }
  173. /* Move on to the next block. */
  174. p = p->next;
  175. }
  176. }
  177. /*--------------------------------------------------------------------------*/
  178. /* */
  179. /* GetAccelerators() _ */
  180. /* */
  181. /*--------------------------------------------------------------------------*/
  182. int GetAccelerators(PRESINFO pRes)
  183. {
  184. int count = 0;
  185. int ntype;
  186. WCHAR c;
  187. int bTypeSpecified;
  188. RCACCEL Accel;
  189. PreBeginParse(pRes, 2106);
  190. do {
  191. if (token.type == END)
  192. continue;
  193. bTypeSpecified = FALSE;
  194. ntype = token.type;
  195. if (token.type == END) {
  196. MarkAccelFlagsByte();
  197. WriteWord(0);
  198. WriteWord(0);
  199. WriteWord(0);
  200. WriteWord(0);
  201. count++;
  202. continue;
  203. }
  204. else if (token.type == NUMLIT)
  205. Accel.ascii = token.val;
  206. else if (token.type == LSTRLIT) {
  207. if (tokenbuf[0] == L'^') {
  208. if (wcslen(tokenbuf) != 2)
  209. ParseError1(2152);
  210. /* GetAccelerators() and support "^^" to put ^ */
  211. if (tokenbuf[1] == L'^')
  212. Accel.ascii = L'^';
  213. else {
  214. if (!iswalpha(c=towupper(tokenbuf[1])))
  215. ParseError1(2154);
  216. Accel.ascii = c - L'A' + 1;
  217. }
  218. }
  219. else if (wcslen(tokenbuf) == 2)
  220. Accel.ascii = (WCHAR)((tokenbuf[0] << 8) + tokenbuf[1]);
  221. else if (wcslen(tokenbuf) == 1)
  222. Accel.ascii = tokenbuf[0];
  223. else
  224. ParseError1(2155);
  225. }
  226. else
  227. ParseError1(2156);
  228. /* Get the trailing comma. */
  229. GetToken(TRUE);
  230. if (token.type != COMMA)
  231. ParseError1(2157);
  232. /* Get the next number. */
  233. GetToken(TRUE);
  234. if (token.type != NUMLIT)
  235. ParseError1(2107);
  236. Accel.id = token.val;
  237. WriteSymbolUse(&token.sym);
  238. if (!GetFullExpression(&Accel.id, GFE_ZEROINIT | GFE_SHORT))
  239. ParseError1(2107); //"Expected numeric command value"
  240. Accel.flags = 0;
  241. if (token.type == COMMA)
  242. do {
  243. GetToken(TRUE);
  244. switch (token.type) {
  245. case TKVIRTKEY:
  246. Accel.flags |= fVIRTKEY;
  247. bTypeSpecified = TRUE;
  248. break;
  249. case TKASCII:
  250. bTypeSpecified = TRUE;
  251. break; /* don't set the flag */
  252. case TKNOINVERT:
  253. Accel.flags |= fNOINVERT;
  254. break;
  255. case TKSHIFT:
  256. Accel.flags |= fSHIFT;
  257. break;
  258. case TKCONTROL:
  259. Accel.flags |= fCONTROL;
  260. break;
  261. case TKALT:
  262. Accel.flags |= fALT;
  263. break;
  264. default:
  265. ParseError1(2159);
  266. }
  267. GetToken(TRUE);
  268. } while (token.type == COMMA);
  269. if (ntype == NUMLIT && !bTypeSpecified)
  270. ParseError1(2163);
  271. if (!(Accel.flags & fVIRTKEY) && (Accel.flags & (fSHIFT | fCONTROL))) {
  272. SET_MSG(Msg_Text, sizeof(Msg_Text), GET_MSG(4203), curFile, token.row);
  273. SendError(Msg_Text);
  274. }
  275. if (Accel.flags & fVIRTKEY && ntype == LSTRLIT)
  276. if (!iswalnum(Accel.ascii = (WCHAR)towupper(Accel.ascii))) {
  277. SET_MSG(Msg_Text, sizeof(Msg_Text), GET_MSG(4204), curFile, token.row);
  278. SendError(Msg_Text);
  279. }
  280. MarkAccelFlagsByte();
  281. WriteWord(Accel.flags);
  282. WriteWord(Accel.ascii);
  283. if (fMacRsrcs)
  284. WriteLong(Accel.id);
  285. else
  286. {
  287. WriteWord(Accel.id);
  288. WriteWord(0);
  289. }
  290. count++;
  291. } while (token.type != END);
  292. PatchAccelEnd();
  293. return(5 * count);
  294. }