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
Line 
1
2/***********************************************************************
3
4 $Id: strutil.c 1877 2015-10-11 21:43:27Z gyoung $
5
6 External strings support - stored in STRINGTABLE
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2006, 2009 Steven H. Levine
10
11 22 Jul 06 SHL Comments
12 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
13 05 Jan 08 SHL Rename from string.c to avoid string.h conflict
14 03 Feb 09 SHL Switch to STRINGTABLE and const return
15 19 Sep 09 GKY Make GetPString more SMP safe
16
17***********************************************************************/
18
19#include <stdio.h>
20#include <share.h>
21#include <string.h>
22
23#define INCL_DOSPROCESS // DosSleep
24
25#include "fm3dll.h"
26#include "fm3str.h"
27#include "init.h" // Data declaration(s)
28#include "mainwnd.h" // FM3ModHandle
29#include "wrappers.h"
30#include "errutil.h"
31#include "strutil.h"
32#include "version.h"
33
34static PSZ pszSrcFile = __FILE__;
35
36//== GetPString() return a readonly pointer to the requested string in memory ==
37
38PCSZ GetPString(ULONG id)
39{
40 PSZ psz;
41 LONG l;
42 CHAR sz[257];
43 ULONG ulNewFirstId;
44 ULONG ulNewLastId;
45
46 static PSZ *pLoadedStrings;
47 static ULONG ulFirstId;
48 static ULONG ulLastId;
49
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 };
84
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++) {
100 if (SMPSafeInc(), cBusy == 1)
101 break;
102 SMPSafeDec();
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;
147 }
148 }
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
154
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
201 }
202
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 }
216
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 }
250
251 uDbgState = 6;
252 pLoadedStrings[id - ulFirstId] = psz;
253 cBusy--;
254 return psz;
255}
256
257#pragma alloc_text(STRINGS,LoadStrings,GetPString)
Note: See TracBrowser for help on using the repository browser.