Changeset 40569 in vbox for trunk/src/bldprogs
- Timestamp:
- Mar 21, 2012 4:13:52 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76963
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/VBoxTpG.cpp
r40558 r40569 35 35 #include <iprt/stream.h> 36 36 #include <iprt/string.h> 37 #include <iprt/strcache.h>38 37 39 38 #include "scmstream.h" … … 86 85 RTLISTNODE ListEntry; 87 86 const char *pszName; 88 c har*pszType;87 const char *pszType; 89 88 } VTGARG; 90 89 typedef VTGARG *PVTGARG; … … 114 113 typedef VTGPROVIDER *PVTGPROVIDER; 115 114 115 /** 116 * A string table string. 117 */ 118 typedef struct VTGSTRING 119 { 120 /** The string space core. */ 121 RTSTRSPACECORE Core; 122 /** The string table offset. */ 123 uint32_t offStrTab; 124 /** The actual string. */ 125 char szString[1]; 126 } VTGSTRING; 127 typedef VTGSTRING *PVTGSTRING; 128 116 129 117 130 /******************************************************************************* 118 131 * Global Variables * 119 132 *******************************************************************************/ 120 /** String cache used for storing strings when parsing. */ 121 static RTSTRCACHE g_hStrCache = NIL_RTSTRCACHE; 133 /** The string space organizing the string table strings. Each node is a VTGSTRING. */ 134 static RTSTRSPACE g_StrSpace = NULL; 135 /** Used by the string table enumerator to set VTGSTRING::offStrTab. */ 136 static uint32_t g_offStrTab; 122 137 /** List of providers created by the parser. */ 123 138 static RTLISTANCHOR g_ProviderHead; … … 165 180 166 181 182 /** 183 * Inserts a string into the string table, reusing any matching existing string 184 * if possible. 185 * 186 * @returns Read only string. 187 * @param pch The string to insert (need not be terminated). 188 * @param cch The length of the string. 189 */ 190 static const char *strtabInsertN(const char *pch, size_t cch) 191 { 192 PVTGSTRING pStr = (PVTGSTRING)RTStrSpaceGetN(&g_StrSpace, pch, cch); 193 if (pStr) 194 return pStr->szString; 195 196 /* 197 * Create a new entry. 198 */ 199 pStr = (PVTGSTRING)RTMemAlloc(RT_OFFSETOF(VTGSTRING, szString[cch + 1])); 200 if (!pStr) 201 return NULL; 202 203 pStr->Core.pszString = pStr->szString; 204 memcpy(pStr->szString, pch, cch); 205 pStr->szString[cch] = '\0'; 206 pStr->offStrTab = UINT32_MAX; 207 208 bool fRc = RTStrSpaceInsert(&g_StrSpace, &pStr->Core); 209 Assert(fRc); NOREF(fRc); 210 return pStr->szString; 211 } 212 213 167 214 static RTEXITCODE generateInvokeAssembler(const char *pszOutput, const char *pszTempAsm) 168 215 { … … 236 283 237 284 285 /** 286 * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes the string table strings.} 287 */ 288 static DECLCALLBACK(int) generateAssemblyStrTabCallback(PRTSTRSPACECORE pStr, void *pvUser) 289 { 290 PVTGSTRING pVtgStr = (PVTGSTRING)pStr; 291 PSCMSTREAM pStrm = (PSCMSTREAM)pvUser; 292 293 pVtgStr->offStrTab = g_offStrTab; 294 g_offStrTab += pVtgStr->Core.cchString + 1; 295 296 ScmStreamPrintf(pStrm, 297 " db '%s', 0 ; off=%u len=%zu\n", 298 pVtgStr->szString, pVtgStr->offStrTab, pVtgStr->Core.cchString); 299 return VINF_SUCCESS; 300 } 301 302 238 303 static RTEXITCODE generateAssembly(PSCMSTREAM pStrm) 239 304 { … … 252 317 "%include \"iprt/asmdefs.h\"\n" 253 318 "\n" 319 "%ifdef ASM_FORMAT_OMF\n" 320 " segment VTGObject public CLASS=VTGObject align=16 use32" 254 321 , 255 322 g_pszScript); 323 324 /* 325 * Dump the string table to set the offsets before we use them anywhere. 326 */ 327 ScmStreamPrintf(pStrm, 328 ";\n" 329 "; The string table.\n" 330 ";\n" 331 "BEGINDATA\n" 332 "GLOBALNAME g_achVTGStringTable\n"); 333 g_offStrTab = 0; 334 RTStrSpaceEnumerate(&g_StrSpace, generateAssemblyStrTabCallback, pStrm); 335 ScmStreamPrintf(pStrm, 336 "GLOBALNAME g_achVTGStringTable_End\n"); 256 337 257 338 /* … … 291 372 ";\n" 292 373 "BEGINDATA\n" 293 "GLOBALNAME g_a VTGProbeData\n"374 "GLOBALNAME g_abVTGProbeData\n" 294 375 "\n"); 295 376 RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry) … … 305 386 } 306 387 } 307 ScmStreamPrintf(pStrm, "GLOBALNAME g_aVTGProbeData_End\n"); 308 309 /* 310 * Write the string table. 311 */ 312 ScmStreamPrintf(pStrm, 313 "\n" 314 ";\n" 315 "; String table.\n" 316 ";\n" 317 "BEGINDATA\n" 318 "GLOBALNAME g_abVTGProbeStrings\n" 319 "\n"); 320 /** @todo */ 321 ScmStreamPrintf(pStrm, "GLOBALNAME g_abVTGProbeStrings_End\n"); 388 ScmStreamPrintf(pStrm, "GLOBALNAME g_abVTGProbeData_End\n"); 322 389 323 390 return RTEXITCODE_SUCCESS; … … 1061 1128 RTListInit(&pProbe->ArgHead); 1062 1129 RTListAppend(&pProv->ProbeHead, &pProbe->ListEntry); 1063 pProbe->pszName = RTStrCacheEnterN(g_hStrCache,pszProbe, cchProbe);1130 pProbe->pszName = strtabInsertN(pszProbe, cchProbe); 1064 1131 if (!pProbe->pszName) 1065 1132 return parseError(pStrm, 0, "Out of memory"); … … 1070 1137 PVTGARG pArg = NULL; 1071 1138 size_t cchName = 0; 1139 size_t cchArg = 0; 1140 char szArg[4096]; 1072 1141 for (;;) 1073 1142 { … … 1083 1152 if (!cchName) 1084 1153 return parseError(pStrm, 1, "Argument has no name"); 1085 char *pszName; 1086 pArg->pszName = pszName = strchr(pArg->pszType, '\0') - cchName; 1087 pszName[-1] = '\0'; 1154 pArg->pszType = strtabInsertN(szArg, cchArg - cchName - 1); 1155 pArg->pszName = strtabInsertN(&szArg[cchArg - cchName], cchName); 1156 if (!pArg->pszType || !pArg->pszName) 1157 return parseError(pStrm, 1, "Out of memory"); 1088 1158 pArg = NULL; 1159 cchName = cchArg = 0; 1089 1160 } 1090 1161 if (ch == ')') … … 1101 1172 default: 1102 1173 { 1103 int rc;1104 1174 size_t cchWord; 1105 1175 const char *pszWord = ScmStreamCGetWordM1(pStrm, &cchWord); … … 1114 1184 pProbe->cArgs++; 1115 1185 1116 rc = RTStrAAppendN(&pArg->pszType, pszWord, cchWord); 1186 if (cchWord + 1 > sizeof(szArg)) 1187 return parseError(pStrm, 1, "Too long parameter declaration"); 1188 memcpy(szArg, pszWord, cchWord); 1189 szArg[cchWord] = '\0'; 1190 cchArg = cchWord; 1117 1191 cchName = 0; 1118 1192 } 1119 1193 else 1120 1194 { 1121 rc = RTStrAAppendExN(&pArg->pszType, 2, RT_STR_TUPLE(" "), pszWord, cchWord); 1195 if (cchArg + 1 + cchWord + 1 > sizeof(szArg)) 1196 return parseError(pStrm, 1, "Too long parameter declaration"); 1197 1198 szArg[cchArg++] = ' '; 1199 memcpy(&szArg[cchArg], pszWord, cchWord); 1200 cchArg += cchWord; 1201 szArg[cchArg] = '\0'; 1122 1202 cchName = cchWord; 1123 1203 } 1124 if (RT_FAILURE(rc))1125 return parseError(pStrm, 1, "Out of memory");1126 1204 break; 1127 1205 } … … 1131 1209 if (!pArg) 1132 1210 return parseError(pStrm, 1, "A parameter type does not start with an asterix"); 1133 int rc = RTStrAAppend(&pArg->pszType, " *"); 1134 if (RT_FAILURE(rc)) 1135 return parseError(pStrm, 1, "Out of memory"); 1211 if (cchArg + sizeof(" *") >= sizeof(szArg)) 1212 return parseError(pStrm, 1, "Too long parameter declaration"); 1213 szArg[cchArg++] = ' '; 1214 szArg[cchArg++] = '*'; 1215 szArg[cchArg ] = '\0'; 1136 1216 cchName = 0; 1137 1217 break; … … 1177 1257 RTListInit(&pProv->ProbeHead); 1178 1258 RTListAppend(&g_ProviderHead, &pProv->ListEntry); 1179 pProv->pszName = RTStrCacheEnterN(g_hStrCache,pszName, cchName);1259 pProv->pszName = strtabInsertN(pszName, cchName); 1180 1260 if (!pProv->pszName) 1181 1261 return parseError(pStrm, 0, "Out of memory"); … … 1467 1547 * Parse the script. 1468 1548 */ 1469 rc = RTStrCacheCreate(&g_hStrCache, "VBoxTpG"); 1470 if (RT_SUCCESS(rc)) 1549 RTListInit(&g_ProviderHead); 1550 rcExit = parseScript(g_pszScript); 1551 if (rcExit == RTEXITCODE_SUCCESS) 1471 1552 { 1472 RTListInit(&g_ProviderHead); 1473 rcExit = parseScript(g_pszScript); 1474 if (rcExit == RTEXITCODE_SUCCESS) 1475 { 1476 /* 1477 * Take action. 1478 */ 1479 if (g_enmAction == kVBoxTpGAction_GenerateHeader) 1480 rcExit = generateHeader(g_pszOutput); 1481 else 1482 rcExit = generateObject(g_pszOutput, g_pszTempAsm); 1483 } 1484 RTStrCacheDestroy(g_hStrCache); 1553 /* 1554 * Take action. 1555 */ 1556 if (g_enmAction == kVBoxTpGAction_GenerateHeader) 1557 rcExit = generateHeader(g_pszOutput); 1558 else 1559 rcExit = generateObject(g_pszOutput, g_pszTempAsm); 1485 1560 } 1486 1561 }
Note:
See TracChangeset
for help on using the changeset viewer.