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.

356 lines
7.1 KiB

  1. #define LINT_ARGS
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <search.h>
  5. #include <sys\types.h>
  6. #include <sys\stat.h>
  7. #include "mbrmake.h"
  8. #define LONGESTPATH 128
  9. #define SLASH "\\"
  10. #define SLASHCHAR '\\'
  11. #define XSLASHCHAR '/'
  12. WORD near cAtomsMac; // total number of atoms
  13. WORD near cModulesMac; // total number of modules
  14. WORD near cSymbolsMac; // total number of symbols
  15. static char *tmpl = "XXXXXX";
  16. extern WORD HashAtomStr (char *);
  17. // rjsa LPCH GetAtomStr (VA vaSym);
  18. void
  19. SeekError (char *pfilenm)
  20. // couldn't seek to position ... emit error message
  21. //
  22. {
  23. Error(ERR_SEEK_FAILED, pfilenm);
  24. }
  25. void
  26. ReadError (char *pfilenm)
  27. // couldn't read from file... emit error message
  28. //
  29. {
  30. Error(ERR_READ_FAILED, pfilenm);
  31. }
  32. void
  33. WriteError (char *pfilenm)
  34. // couldn't write to file ... emit error message
  35. //
  36. {
  37. Error(ERR_WRITE_FAILED, pfilenm);
  38. }
  39. void
  40. FindTmp (char *pbuf) /* copy TMP path to pbuf if exists */
  41. //
  42. //
  43. {
  44. char ebuf[LONGESTPATH];
  45. char *env = ebuf;
  46. *pbuf = '\0';
  47. *env = '\0';
  48. // if (!(env = getenv("TMP")))
  49. if (!(env = getenvOem("TMP")))
  50. return; /* no path, return */
  51. // env = strncpy(ebuf, env, LONGESTPATH-1);
  52. strncpy(ebuf, env, LONGESTPATH-1);
  53. free( env );
  54. env = ebuf;
  55. ebuf[LONGESTPATH-1] = '\0';
  56. if (!( env = ebuf ) )
  57. return;
  58. env = ebuf + strcspn(ebuf, ";");
  59. if (*env == ';')
  60. *env = '\0';
  61. if (env != ebuf) {
  62. env--;
  63. if (*env != SLASHCHAR
  64. && *env != XSLASHCHAR)
  65. strcat(ebuf, SLASH);
  66. }
  67. strcpy (pbuf, ebuf);
  68. }
  69. char *
  70. MakTmpFileName (char *pext)
  71. // Create a temporary file with the extension supplied.
  72. // returns a pointer to the file name on the heap.
  73. //
  74. {
  75. char ptmpnam[96];
  76. char btmpl[7];
  77. char *p;
  78. strcpy (btmpl, tmpl);
  79. p = mktemp(btmpl);
  80. FindTmp (ptmpnam);
  81. strcat (ptmpnam, p);
  82. free (p);
  83. strcat (ptmpnam, pext); /* /tmp/xxxxxx.ext file */
  84. return (LszDup(ptmpnam));
  85. }
  86. LSZ
  87. LszBaseName (LSZ lsz)
  88. // return the base name part of a path
  89. //
  90. {
  91. LPCH lpch;
  92. lpch = strrchr(lsz, '\\');
  93. if (lpch) return lpch+1;
  94. if (lsz[1] == ':')
  95. return lsz+2;
  96. return lsz;
  97. }
  98. VA
  99. VaSearchModule (char *p)
  100. // search for the named module in the module list
  101. //
  102. {
  103. VA vaMod;
  104. LSZ lsz, lszBase;
  105. char buf[PATH_BUF];
  106. strcpy(buf, ToAbsPath(p, r_cwd));
  107. lszBase = LszBaseName(buf);
  108. SetVMClient(VM_SEARCH_MOD);
  109. vaMod = vaRootMod;
  110. while (vaMod) {
  111. gMOD(vaMod);
  112. lsz = GetAtomStr(cMOD.vaNameSym);
  113. if (strcmpi(LszBaseName(lsz), lszBase) == 0 &&
  114. strcmpi(buf,ToAbsPath(lsz, c_cwd)) == 0) {
  115. SetVMClient(VM_MISC);
  116. return (vaMod);
  117. }
  118. vaMod = cMOD.vaNextMod;
  119. }
  120. SetVMClient(VM_MISC);
  121. return vaNil;
  122. }
  123. VA
  124. VaSearchModuleExact (char *p)
  125. // search for the named module in the module list -- EXACT match only
  126. //
  127. {
  128. VA vaMod;
  129. SetVMClient(VM_SEARCH_MOD);
  130. vaMod = vaRootMod;
  131. while (vaMod) {
  132. gMOD(vaMod);
  133. if (strcmp(p,GetAtomStr(cMOD.vaNameSym)) == 0) {
  134. SetVMClient(VM_MISC);
  135. return (vaMod);
  136. }
  137. vaMod = cMOD.vaNextMod;
  138. }
  139. SetVMClient(VM_MISC);
  140. return vaNil;
  141. }
  142. VA
  143. VaSearchSymbol (char *pStr)
  144. // search for the named symbol (not a module!)
  145. //
  146. {
  147. WORD hashid;
  148. VA vaRootSym, vaSym;
  149. LSZ lszAtom;
  150. SetVMClient(VM_SEARCH_SYM);
  151. vaRootSym = rgVaSym[hashid = HashAtomStr (pStr)];
  152. if (vaRootSym) {
  153. vaSym = vaRootSym;
  154. while (vaSym) {
  155. gSYM(vaSym);
  156. lszAtom = gTEXT(cSYM.vaNameText);
  157. if (strcmp (pStr, lszAtom) == 0) {
  158. SetVMClient(VM_MISC);
  159. return (vaSym); // Duplicate entry
  160. }
  161. vaSym = cSYM.vaNextSym; // current = next
  162. }
  163. }
  164. SetVMClient(VM_MISC);
  165. return vaNil;
  166. }
  167. LPCH
  168. GetAtomStr (VA vaSym)
  169. // Swap in the Atom page for the symbol chain entry pSym
  170. // Return the atom's address in the page.
  171. //
  172. {
  173. gSYM(vaSym);
  174. return gTEXT(cSYM.vaNameText);
  175. }
  176. VA
  177. MbrAddAtom (char *pStr, char fFILENM)
  178. // create a new symbol with the given name
  179. //
  180. {
  181. WORD hashid;
  182. VA vaSym, vaSymRoot, vaText;
  183. if (!fFILENM)
  184. vaSymRoot = rgVaSym[hashid = HashAtomStr (pStr)];
  185. else
  186. vaSymRoot = rgVaSym[hashid = MAXSYMPTRTBLSIZ - 1];
  187. SetVMClient(VM_SEARCH_SYM);
  188. if (vaSymRoot) {
  189. vaSym = vaSymRoot;
  190. while (vaSym) {
  191. gSYM(vaSym);
  192. if (!strcmp (pStr, GetAtomStr(vaSym))) {
  193. #if defined (DEBUG)
  194. if (OptD & 2)
  195. printf("MbrAddAtom: duplicate (%s)\n", pStr);
  196. #endif
  197. SetVMClient(VM_SEARCH_SYM);
  198. return (vaSym); // Duplicate entry
  199. }
  200. vaSym = cSYM.vaNextSym; // current = next
  201. }
  202. }
  203. // we are now going to have to add the symbol
  204. if (fFILENM) {
  205. SetVMClient(VM_ADD_MOD);
  206. cModulesMac++;
  207. }
  208. else {
  209. SetVMClient(VM_ADD_SYM);
  210. cSymbolsMac++;
  211. }
  212. cAtomsMac++;
  213. vaSym = VaAllocGrpCb(grpSym, sizeof(SYM));
  214. vaText = VaAllocGrpCb(grpText, strlen(pStr) + 1);
  215. gSYM(vaSym);
  216. cSYM.vaNameText = vaText;
  217. cSYM.vaNextSym = rgVaSym[hashid];
  218. pSYM(vaSym);
  219. rgVaSym[hashid] = vaSym;
  220. strcpy(gTEXT(vaText), pStr);
  221. pTEXT(vaText);
  222. SetVMClient(VM_MISC);
  223. return (vaSym);
  224. }
  225. VA FAR * near rgvaSymSorted;
  226. // rjsa int CmpSym(VA FAR *lhsym1, VA FAR *lhsym2);
  227. void
  228. SortAtoms ()
  229. // create the "subscript sort" array pointers rgvaSymSorted
  230. //
  231. {
  232. VA vaSym;
  233. char buf[PATH_BUF];
  234. WORD i, iSym;
  235. SetVMClient(VM_SORT_ATOMS);
  236. rgvaSymSorted = (VA FAR *)LpvAllocCb(cAtomsMac * sizeof(VA));
  237. iSym = 0;
  238. for (i=0; i < MAXSYMPTRTBLSIZ; i++) {
  239. vaSym = rgVaSym[i];
  240. while (vaSym) {
  241. gSYM(vaSym);
  242. rgvaSymSorted[iSym] = cSYM.vaNameText;
  243. vaSym = cSYM.vaNextSym;
  244. iSym++;
  245. }
  246. }
  247. // sort symbols
  248. qsort(rgvaSymSorted, cSymbolsMac, sizeof(VA), CmpSym);
  249. // the files are in the last hash bucket so they went to the
  250. // end of this array we just made -- we sort them separately
  251. // sort files
  252. qsort(rgvaSymSorted + cSymbolsMac, cModulesMac, sizeof(VA), CmpSym);
  253. // convert the Page/Atom values back to virtual symbol addresses
  254. for (i=0; i < cSymbolsMac; i++) {
  255. strcpy(buf, gTEXT(rgvaSymSorted[i]));
  256. rgvaSymSorted[i] = VaSearchSymbol(buf);
  257. }
  258. for (; i < cAtomsMac; i++) {
  259. strcpy(buf, gTEXT(rgvaSymSorted[i]));
  260. #ifdef DEBUG
  261. if (OptD & 64) printf("Module: %s\n", buf);
  262. #endif
  263. rgvaSymSorted[i] = (VaSearchModuleExact(buf), cMOD.vaNameSym);
  264. }
  265. }
  266. int __cdecl
  267. CmpSym (VA FAR *sym1, VA FAR *sym2)
  268. // compare two symbols given their pointers
  269. //
  270. {
  271. register char far *lpch1, *lpch2;
  272. register int cmp;
  273. lpch1 = gTEXT(*sym1); // LRU will not page out lpch1
  274. lpch2 = gTEXT(*sym2);
  275. cmp = strcmpi(lpch1, lpch2);
  276. if (cmp) return cmp;
  277. return strcmp(lpch1, lpch2);
  278. }