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
RevLine 
[333]1
2/***********************************************************************
3
4 $Id: strutil.c 1880 2015-10-12 18:26:16Z 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 for (c = 0; ; c++) {
[1460]99 if (SMPSafeInc(), cBusy == 1)
[1394]100 break;
[1460]101 SMPSafeDec();
[1394]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;
[2]142 }
143 }
[1394]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
[2]149
[1394]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
[2]196 }
197
[1394]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 }
[2]211
[1394]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 }
[2]245
[1394]246 uDbgState = 6;
247 pLoadedStrings[id - ulFirstId] = psz;
248 cBusy--;
249 return psz;
[2]250}
[793]251
252#pragma alloc_text(STRINGS,LoadStrings,GetPString)
Note: See TracBrowser for help on using the repository browser.