source: trunk/dll/strutil.c@ 1877

Last change on this file since 1877 was 1877, checked in by Gregg Young, 10 years ago

Remove debug code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
RevLine 
[333]1
2/***********************************************************************
3
4 $Id: strutil.c 1877 2015-10-11 21:43:27Z gyoung $
5
[1394]6 External strings support - stored in STRINGTABLE
[333]7
8 Copyright (c) 1993-98 M. Kimes
[1394]9 Copyright (c) 2006, 2009 Steven H. Levine
[333]10
11 22 Jul 06 SHL Comments
[793]12 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[907]13 05 Jan 08 SHL Rename from string.c to avoid string.h conflict
[1394]14 03 Feb 09 SHL Switch to STRINGTABLE and const return
[1460]15 19 Sep 09 GKY Make GetPString more SMP safe
[333]16
17***********************************************************************/
18
[2]19#include <stdio.h>
20#include <share.h>
[1394]21#include <string.h>
[333]22
[1394]23#define INCL_DOSPROCESS // DosSleep
24
[1213]25#include "fm3dll.h"
26#include "fm3str.h"
27#include "init.h" // Data declaration(s)
[1394]28#include "mainwnd.h" // FM3ModHandle
29#include "wrappers.h"
30#include "errutil.h"
[907]31#include "strutil.h"
[2]32#include "version.h"
33
[1394]34static PSZ pszSrcFile = __FILE__;
[907]35
[1394]36//== GetPString() return a readonly pointer to the requested string in memory ==
[2]37
[1394]38PCSZ GetPString(ULONG id)
[333]39{
[1394]40 PSZ psz;
41 LONG l;
42 CHAR sz[257];
43 ULONG ulNewFirstId;
44 ULONG ulNewLastId;
[2]45
[1394]46 static PSZ *pLoadedStrings;
47 static ULONG ulFirstId;
48 static ULONG ulLastId;
[333]49
[1394]50 // Strings that must be combined because stringtable items limited to 256
51 static struct LongString {
52 ULONG id;
53 ULONG sub_id;
54 } LongStrings[] = {
55 {IDS_SUGGEST1TEXT, IDS_SUGGEST1TEXT1},
56 {IDS_SUGGEST1TEXT, IDS_SUGGEST1TEXT2},
57 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT1},
58 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT2},
59 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT3},
60 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT4},
61 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT5},
62 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT6},
63 {IDS_ARCHIVERBB2TEXT, IDS_ARCHIVERBB2TEXT7},
64 {IDS_INIBINARYDATASKIPTEXT, IDS_INIBINARYDATASKIPTEXT1},
65 {IDS_INIBINARYDATASKIPTEXT, IDS_INIBINARYDATASKIPTEXT2},
66 {IDS_INSTANTHELPTEXT, IDS_INSTANTHELPTEXT1},
67 {IDS_INSTANTHELPTEXT, IDS_INSTANTHELPTEXT2},
68 {IDS_FSDERRORTEXT, IDS_FSDERRORTEXT1},
69 {IDS_FSDERRORTEXT, IDS_FSDERRORTEXT2},
70 {IDS_LANERRORTEXT, IDS_LANERRORTEXT1},
71 {IDS_LANERRORTEXT, IDS_LANERRORTEXT2},
72 {IDS_MAKESHADOWHELPTEXT, IDS_MAKESHADOWHELPTEXT1},
73 {IDS_MAKESHADOWHELPTEXT, IDS_MAKESHADOWHELPTEXT2},
74 {IDS_UNDELETEHELPTEXT, IDS_UNDELETEHELPTEXT1},
75 {IDS_UNDELETEHELPTEXT, IDS_UNDELETEHELPTEXT2},
76 {IDS_KILLPROCHELPTEXT, IDS_KILLPROCHELPTEXT1},
77 {IDS_KILLPROCHELPTEXT, IDS_KILLPROCHELPTEXT2},
78 {IDS_ARCNOTTHERETEXT, IDS_ARCNOTTHERETEXT1},
79 {IDS_ARCNOTTHERETEXT, IDS_ARCNOTTHERETEXT2},
80 {IDS_FM2CMDHELPTEXT, IDS_FM2CMDHELPTEXT1},
81 {IDS_FM2CMDHELPTEXT, IDS_FM2CMDHELPTEXT2},
82 {IDS_FM2CMDHELPTEXT, IDS_FM2CMDHELPTEXT3}
83 };
[2]84
[1394]85 static UINT cLongStrings = sizeof(LongStrings) / sizeof(struct LongString);
86
87 static volatile INT cBusy; // Need to be MT-safe
88 static ULONG ulDbgId; // 13 Jan 09 SHL fixme to be gone?
89 static UINT uDbgState; // 03 Feb 09 SHL fixme to be gone?
90 static ULONG ulDbgTid; // 13 Jan 09 SHL fixme to be gone?
91
92 UINT c;
93 // 23 Jan 09 SHL fixme to use SMP safe inc/dec?
94 extern void SMPSafeInc(void);
95 extern void SMPSafeDec(void);
96 #pragma aux SMPSafeInc = "lock inc cBusy" modify exact [];
97 #pragma aux SMPSafeDec = "lock dec cBusy" modify exact [];
98 // SMPSafeInc();
99 for (c = 0; ; c++) {
[1460]100 if (SMPSafeInc(), cBusy == 1)
[1394]101 break;
[1460]102 SMPSafeDec();
[1394]103 // Hold off 1 cycle before reporting since some contention expected
104 if (c == 1)
105 DbgMsg(pszSrcFile, __LINE__, "GetPString(%lu) waiting for tid %lu GetPString(%lu), state=%u", id, ulDbgTid, ulDbgId, uDbgState);
106 DosSleep(1); // Let current owner finish
107 }
108 if (c > 1)
109 DbgMsg(pszSrcFile, __LINE__, "continuing with GetPString(%lu) after tid %lu GetPString(%lu), state=%u", id, ulDbgTid, ulDbgId, uDbgState);
110
111 // Remember id and thread ordinal for diagnosing MT hangs
112 // Use fast DosGetInfoBlocks to ensure debug logic does not change timing
113 {
114 extern PTIB2 GetPTIB2(void);
115 #pragma aux GetPTIB2 = "mov eax,fs:[12]" value [eax];
116 // PIB *ppib;
117 // TIB *ptib;
118 TIB2 *ptib2 = GetPTIB2();
119 // APIRET apiret = DosGetInfoBlocks(&ptib, &ppib);
120 ulDbgId = id;
121 // ulDbgTid = apiret == 0 ? ptib->tib_ptib2->tib2_ultid : 0;
122 ulDbgTid = ptib2->tib2_ultid;
123 }
124
125 // If string already loaded, return it now
126 if (id >= ulFirstId &&
127 id <= ulLastId &&
128 pLoadedStrings &&
129 (psz = pLoadedStrings[id - ulFirstId]) != NULL) {
130 cBusy--;
131 if (((ULONG)psz & 0xffff0000) == 0)
132 DbgMsg(pszSrcFile, __LINE__, "id %lu corrupted %p", id, psz);
133 return psz;
134 }
135
136 // Try to load
137 // 11 Jan 09 SHL fixme to use global HAB?
138 uDbgState = 1;
139 l = WinLoadString((HAB)NULL, FM3ModHandle, id, sizeof(sz), sz);
140 uDbgState = 2;
141
142 if (l != 0) {
143 psz = xstrdup(sz, pszSrcFile, __LINE__);
144 if (!psz) {
145 cBusy--;
146 return NullStr;
[2]147 }
148 }
[1394]149 else {
150 // Assume string must be built from multiple strings - find first
151 UINT i;
152 psz = NULL;
153 for (i = 0; i < cLongStrings && LongStrings[i].id != id; i++); // Scan
[2]154
[1394]155 if (i < cLongStrings) {
156 // Combine stringtable items to build long string
157 for (; LongStrings[i].id == id; i++) {
158 uDbgState = 3;
159 l = WinLoadString((HAB)NULL, FM3ModHandle, LongStrings[i].sub_id, sizeof(sz), sz);
160 uDbgState = 4;
161 if (l == 0) {
162 cBusy--;
163 Runtime_Error(pszSrcFile, __LINE__, "string %lu missing", LongStrings[i].sub_id);
164 xfree(psz, pszSrcFile, __LINE__);
165 return NullStr;
166 }
167 if (!psz) {
168 // Remember 1st string
169 psz = strdup(sz);
170 if (!psz) {
171 cBusy--;
172 return NullStr;
173 }
174 }
175 else {
176 // Append string
177 UINT curLen = strlen(psz);
178 PSZ psz2 = xrealloc(psz, curLen + l + 1, pszSrcFile, __LINE__);
179 if (!psz2) {
180 xfree(psz, pszSrcFile, __LINE__);
181 cBusy--;
182 return NullStr;
183 }
184 memcpy(psz2 + curLen, sz, l); // Append
185 *(psz2 + curLen + l) = 0; // Terminate
186 psz = psz2; // Remember
187 l += curLen;
188 }
189 } // while
190 } // if long
191 } // if loaded
192
193 if (l == 0) {
194 DbgMsg(pszSrcFile, __LINE__, "Error loading %lu", id);
195 sprintf(sz, "** Error loading id %lu **", id);
196 psz = xstrdup(sz, pszSrcFile, __LINE__);
197 if (psz)
198 l = strlen(sz);
199 else
200 psz = NullStr; // Oh heck
[2]201 }
202
[1394]203 uDbgState = 5;
204 // Add to cache
205 // Calculate new array limits
206 if (!pLoadedStrings) {
207 ulNewFirstId = id;
208 ulNewLastId = id;
209 ulFirstId = id;
210 ulLastId = id;
211 }
212 else {
213 ulNewFirstId = id < ulFirstId ? id : ulFirstId;
214 ulNewLastId = id > ulLastId ? id : ulLastId;
215 }
[2]216
[1394]217 if (ulNewFirstId != ulFirstId ||
218 ulNewLastId != ulLastId ||
219 !pLoadedStrings) {
220 PSZ *pNewLoadedStrings;
221 pNewLoadedStrings = xrealloc(pLoadedStrings,
222 (ulNewLastId - ulNewFirstId + 1) * sizeof(PSZ),
223 pszSrcFile, __LINE__);
224 if (!pNewLoadedStrings) {
225 cBusy--;
226 Runtime_Error(pszSrcFile, __LINE__, "realloc failed");
227 xfree(psz, pszSrcFile, __LINE__);
228 return NullStr;
229 }
230 // Align existing entries and zero fill unused entries as needed
231 if (ulNewFirstId < ulFirstId) {
232 // Move room for new entries at head of array
233 memmove(pNewLoadedStrings + (ulFirstId - ulNewFirstId),
234 pNewLoadedStrings,
235 (ulLastId - ulFirstId + 1) * sizeof(PSZ));
236 // Null unused placeholder entries
237 if (ulFirstId - ulNewFirstId > 1)
238 memset(pNewLoadedStrings + 1, 0, (ulFirstId - ulNewFirstId - 1) * sizeof(PSZ));
239 }
240 if (ulNewLastId - ulLastId > 1) {
241 // Null unused placeholder entries
242 memset(pNewLoadedStrings + (ulLastId - ulNewFirstId + 1),
243 0,
244 (ulNewLastId - ulLastId - 1) * sizeof(PSZ));
245 }
246 pLoadedStrings = pNewLoadedStrings;
247 ulFirstId = ulNewFirstId;
248 ulLastId = ulNewLastId;
249 }
[2]250
[1394]251 uDbgState = 6;
252 pLoadedStrings[id - ulFirstId] = psz;
253 cBusy--;
254 return psz;
[2]255}
[793]256
257#pragma alloc_text(STRINGS,LoadStrings,GetPString)
Note: See TracBrowser for help on using the repository browser.