source: trunk/dll/strutil.c@ 1880

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

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: strutil.c 1880 2015-10-12 18:26:16Z 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 for (c = 0; ; c++) {
99 if (SMPSafeInc(), cBusy == 1)
100 break;
101 SMPSafeDec();
102 // Hold off 1 cycle before reporting since some contention expected
103 if (c == 1)
104 DbgMsg(pszSrcFile, __LINE__, "GetPString(%lu) waiting for tid %lu GetPString(%lu), state=%u", id, ulDbgTid, ulDbgId, uDbgState);
105 DosSleep(1); // Let current owner finish
106 }
107 if (c > 1)
108 DbgMsg(pszSrcFile, __LINE__, "continuing with GetPString(%lu) after tid %lu GetPString(%lu), state=%u", id, ulDbgTid, ulDbgId, uDbgState);
109
110 // Remember id and thread ordinal for diagnosing MT hangs
111 // Use fast DosGetInfoBlocks to ensure debug logic does not change timing
112 {
113 extern PTIB2 GetPTIB2(void);
114 #pragma aux GetPTIB2 = "mov eax,fs:[12]" value [eax];
115 TIB2 *ptib2 = GetPTIB2();
116 ulDbgId = id;
117 ulDbgTid = ptib2->tib2_ultid;
118 }
119
120 // If string already loaded, return it now
121 if (id >= ulFirstId &&
122 id <= ulLastId &&
123 pLoadedStrings &&
124 (psz = pLoadedStrings[id - ulFirstId]) != NULL) {
125 cBusy--;
126 if (((ULONG)psz & 0xffff0000) == 0)
127 DbgMsg(pszSrcFile, __LINE__, "id %lu corrupted %p", id, psz);
128 return psz;
129 }
130
131 // Try to load
132 // 11 Jan 09 SHL fixme to use global HAB?
133 uDbgState = 1;
134 l = WinLoadString((HAB)NULL, FM3ModHandle, id, sizeof(sz), sz);
135 uDbgState = 2;
136
137 if (l != 0) {
138 psz = xstrdup(sz, pszSrcFile, __LINE__);
139 if (!psz) {
140 cBusy--;
141 return NullStr;
142 }
143 }
144 else {
145 // Assume string must be built from multiple strings - find first
146 UINT i;
147 psz = NULL;
148 for (i = 0; i < cLongStrings && LongStrings[i].id != id; i++); // Scan
149
150 if (i < cLongStrings) {
151 // Combine stringtable items to build long string
152 for (; LongStrings[i].id == id; i++) {
153 uDbgState = 3;
154 l = WinLoadString((HAB)NULL, FM3ModHandle, LongStrings[i].sub_id, sizeof(sz), sz);
155 uDbgState = 4;
156 if (l == 0) {
157 cBusy--;
158 Runtime_Error(pszSrcFile, __LINE__, "string %lu missing", LongStrings[i].sub_id);
159 xfree(psz, pszSrcFile, __LINE__);
160 return NullStr;
161 }
162 if (!psz) {
163 // Remember 1st string
164 psz = strdup(sz);
165 if (!psz) {
166 cBusy--;
167 return NullStr;
168 }
169 }
170 else {
171 // Append string
172 UINT curLen = strlen(psz);
173 PSZ psz2 = xrealloc(psz, curLen + l + 1, pszSrcFile, __LINE__);
174 if (!psz2) {
175 xfree(psz, pszSrcFile, __LINE__);
176 cBusy--;
177 return NullStr;
178 }
179 memcpy(psz2 + curLen, sz, l); // Append
180 *(psz2 + curLen + l) = 0; // Terminate
181 psz = psz2; // Remember
182 l += curLen;
183 }
184 } // while
185 } // if long
186 } // if loaded
187
188 if (l == 0) {
189 DbgMsg(pszSrcFile, __LINE__, "Error loading %lu", id);
190 sprintf(sz, "** Error loading id %lu **", id);
191 psz = xstrdup(sz, pszSrcFile, __LINE__);
192 if (psz)
193 l = strlen(sz);
194 else
195 psz = NullStr; // Oh heck
196 }
197
198 uDbgState = 5;
199 // Add to cache
200 // Calculate new array limits
201 if (!pLoadedStrings) {
202 ulNewFirstId = id;
203 ulNewLastId = id;
204 ulFirstId = id;
205 ulLastId = id;
206 }
207 else {
208 ulNewFirstId = id < ulFirstId ? id : ulFirstId;
209 ulNewLastId = id > ulLastId ? id : ulLastId;
210 }
211
212 if (ulNewFirstId != ulFirstId ||
213 ulNewLastId != ulLastId ||
214 !pLoadedStrings) {
215 PSZ *pNewLoadedStrings;
216 pNewLoadedStrings = xrealloc(pLoadedStrings,
217 (ulNewLastId - ulNewFirstId + 1) * sizeof(PSZ),
218 pszSrcFile, __LINE__);
219 if (!pNewLoadedStrings) {
220 cBusy--;
221 Runtime_Error(pszSrcFile, __LINE__, "realloc failed");
222 xfree(psz, pszSrcFile, __LINE__);
223 return NullStr;
224 }
225 // Align existing entries and zero fill unused entries as needed
226 if (ulNewFirstId < ulFirstId) {
227 // Move room for new entries at head of array
228 memmove(pNewLoadedStrings + (ulFirstId - ulNewFirstId),
229 pNewLoadedStrings,
230 (ulLastId - ulFirstId + 1) * sizeof(PSZ));
231 // Null unused placeholder entries
232 if (ulFirstId - ulNewFirstId > 1)
233 memset(pNewLoadedStrings + 1, 0, (ulFirstId - ulNewFirstId - 1) * sizeof(PSZ));
234 }
235 if (ulNewLastId - ulLastId > 1) {
236 // Null unused placeholder entries
237 memset(pNewLoadedStrings + (ulLastId - ulNewFirstId + 1),
238 0,
239 (ulNewLastId - ulLastId - 1) * sizeof(PSZ));
240 }
241 pLoadedStrings = pNewLoadedStrings;
242 ulFirstId = ulNewFirstId;
243 ulLastId = ulNewLastId;
244 }
245
246 uDbgState = 6;
247 pLoadedStrings[id - ulFirstId] = psz;
248 cBusy--;
249 return psz;
250}
251
252#pragma alloc_text(STRINGS,LoadStrings,GetPString)
Note: See TracBrowser for help on using the repository browser.