Changeset 21377 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jul 8, 2009 1:00:22 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/log/log.cpp
r21375 r21377 134 134 #endif /* IN_RING0 */ 135 135 136 /** 137 * Logger flags instructions. 138 */ 139 static struct 140 { 141 const char *pszInstr; /**< The name */ 142 size_t cchInstr; /**< The size of the name. */ 143 uint32_t fFlag; /**< The flag value. */ 144 bool fInverted; /**< Inverse meaning? */ 145 } 146 const s_aLogFlags[] = 147 { 148 { "disabled", sizeof("disabled" ) - 1, RTLOGFLAGS_DISABLED, false }, 149 { "enabled", sizeof("enabled" ) - 1, RTLOGFLAGS_DISABLED, true }, 150 { "buffered", sizeof("buffered" ) - 1, RTLOGFLAGS_BUFFERED, false }, 151 { "unbuffered", sizeof("unbuffered" ) - 1, RTLOGFLAGS_BUFFERED, true }, 152 { "usecrlf", sizeof("usecrlf" ) - 1, RTLOGFLAGS_USECRLF, false }, 153 { "uself", sizeof("uself" ) - 1, RTLOGFLAGS_USECRLF, true }, 154 { "append", sizeof("append" ) - 1, RTLOGFLAGS_APPEND, false }, 155 { "overwrite", sizeof("overwrite" ) - 1, RTLOGFLAGS_APPEND, true }, 156 { "rel", sizeof("rel" ) - 1, RTLOGFLAGS_REL_TS, false }, 157 { "abs", sizeof("abs" ) - 1, RTLOGFLAGS_REL_TS, true }, 158 { "dec", sizeof("dec" ) - 1, RTLOGFLAGS_DECIMAL_TS, false }, 159 { "hex", sizeof("hex" ) - 1, RTLOGFLAGS_DECIMAL_TS, true }, 160 { "lockcnts", sizeof("lockcnts" ) - 1, RTLOGFLAGS_PREFIX_LOCK_COUNTS, false }, 161 { "cpuid", sizeof("cpuid" ) - 1, RTLOGFLAGS_PREFIX_CPUID, false }, 162 { "pid", sizeof("pid" ) - 1, RTLOGFLAGS_PREFIX_PID, false }, 163 { "flagno", sizeof("flagno" ) - 1, RTLOGFLAGS_PREFIX_FLAG_NO, false }, 164 { "flag", sizeof("flag" ) - 1, RTLOGFLAGS_PREFIX_FLAG, false }, 165 { "groupno", sizeof("groupno" ) - 1, RTLOGFLAGS_PREFIX_GROUP_NO, false }, 166 { "group", sizeof("group" ) - 1, RTLOGFLAGS_PREFIX_GROUP, false }, 167 { "tid", sizeof("tid" ) - 1, RTLOGFLAGS_PREFIX_TID, false }, 168 { "thread", sizeof("thread" ) - 1, RTLOGFLAGS_PREFIX_THREAD, false }, 169 { "custom", sizeof("custom" ) - 1, RTLOGFLAGS_PREFIX_CUSTOM, false }, 170 { "timeprog", sizeof("timeprog" ) - 1, RTLOGFLAGS_PREFIX_TIME_PROG, false }, 171 { "time", sizeof("time" ) - 1, RTLOGFLAGS_PREFIX_TIME, false }, 172 { "msprog", sizeof("msprog" ) - 1, RTLOGFLAGS_PREFIX_MS_PROG, false }, 173 { "tsc", sizeof("tsc" ) - 1, RTLOGFLAGS_PREFIX_TSC, false }, /* before ts! */ 174 { "ts", sizeof("ts" ) - 1, RTLOGFLAGS_PREFIX_TS, false }, 175 }; 176 177 /** 178 * Logger destination instructions. 179 */ 180 static struct 181 { 182 const char *pszInstr; /**< The name. */ 183 size_t cchInstr; /**< The size of the name. */ 184 uint32_t fFlag; /**< The corresponding destination flag. */ 185 } const s_aLogDst[] = 186 { 187 { "file", sizeof("file" ) - 1, RTLOGDEST_FILE }, /* Must be 1st! */ 188 { "dir", sizeof("dir" ) - 1, RTLOGDEST_FILE }, /* Must be 2nd! */ 189 { "stdout", sizeof("stdout" ) - 1, RTLOGDEST_STDOUT }, 190 { "stderr", sizeof("stderr" ) - 1, RTLOGDEST_STDERR }, 191 { "debugger", sizeof("debugger") - 1, RTLOGDEST_DEBUGGER }, 192 { "com", sizeof("com" ) - 1, RTLOGDEST_COM }, 193 { "user", sizeof("user" ) - 1, RTLOGDEST_USER }, 194 }; 195 136 196 137 197 /** … … 291 351 const char *pszVar = RTEnvGet(pszEnvVar); 292 352 if (pszVar) 293 { 294 while (*pszVar) 295 { 296 /* skip blanks. */ 297 while (RT_C_IS_SPACE(*pszVar)) 298 pszVar++; 299 if (!*pszVar) 300 break; 301 302 /* parse instruction. */ 303 static struct 304 { 305 const char *pszInstr; 306 unsigned fFlag; 307 } const aDest[] = 308 { 309 { "file", RTLOGDEST_FILE }, /* Must be 1st! */ 310 { "dir", RTLOGDEST_FILE }, /* Must be 2nd! */ 311 { "stdout", RTLOGDEST_STDOUT }, 312 { "stderr", RTLOGDEST_STDERR }, 313 { "debugger", RTLOGDEST_DEBUGGER }, 314 { "com", RTLOGDEST_COM }, 315 { "user", RTLOGDEST_USER }, 316 }; 317 318 /* check no prefix. */ 319 bool fNo = false; 320 if (pszVar[0] == 'n' && pszVar[1] == 'o') 321 { 322 fNo = true; 323 pszVar += 2; 324 } 325 326 /* instruction. */ 327 unsigned i; 328 for (i = 0; i < RT_ELEMENTS(aDest); i++) 329 { 330 size_t cchInstr = strlen(aDest[i].pszInstr); 331 if (!strncmp(pszVar, aDest[i].pszInstr, cchInstr)) 332 { 333 if (!fNo) 334 pLogger->fDestFlags |= aDest[i].fFlag; 335 else 336 pLogger->fDestFlags &= ~aDest[i].fFlag; 337 pszVar += cchInstr; 338 339 /* check for value. */ 340 while (RT_C_IS_SPACE(*pszVar)) 341 pszVar++; 342 if (*pszVar == '=' || *pszVar == ':') 343 { 344 pszVar++; 345 const char *pszEnd = strchr(pszVar, ';'); 346 if (!pszEnd) 347 pszEnd = strchr(pszVar, '\0'); 348 349 /* log file name */ 350 size_t cch = pszEnd - pszVar; 351 if (i == 0 /* file */ && !fNo) 352 { 353 memcpy(pLogger->pszFilename, pszVar, cch); 354 pLogger->pszFilename[cch] = '\0'; 355 } 356 /* log directory */ 357 else if (i == 1 /* dir */ && !fNo) 358 { 359 char szTmp[RTPATH_MAX]; 360 const char *pszFile = RTPathFilename(pLogger->pszFilename); 361 if (pszFile) 362 strcpy(szTmp, pszFile); 363 else 364 pszFile = ""; /* you've screwed up, sir. */ 365 366 memcpy(pLogger->pszFilename, pszVar, cch); 367 pLogger->pszFilename[cch] = '\0'; 368 RTPathStripTrailingSlash(pLogger->pszFilename); 369 370 cch = strlen(pLogger->pszFilename); 371 pLogger->pszFilename[cch++] = '/'; 372 strcpy(&pLogger->pszFilename[cch], szTmp); 373 } 374 else 375 AssertMsgFailed(("Invalid %s_DEST! %s%s doesn't take a value!\n", pszEnvVarBase, fNo ? "no" : "", aDest[i].pszInstr)); 376 pszVar = pszEnd + (*pszEnd != '\0'); 377 } 378 break; 379 } 380 } 381 /* unknown instruction? */ 382 if (i >= RT_ELEMENTS(aDest)) 383 { 384 AssertMsgFailed(("Invalid %s_DEST! unknown instruction %.20s\n", pszEnvVarBase, pszVar)); 385 pszVar++; 386 } 387 388 /* skip blanks and delimiters. */ 389 while (RT_C_IS_SPACE(*pszVar) || *pszVar == ';') 390 pszVar++; 391 } /* while more environment variable value left */ 392 } 353 RTLogDestinations(pLogger, pszVar); 393 354 394 355 /* … … 1264 1225 } 1265 1226 1227 /** 1228 * Helper for RTLogGetGroupSettings. 1229 */ 1230 static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst) 1231 { 1232 #define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0) 1233 #define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1) 1234 #define APPEND_CH(ch) do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0) 1235 1236 /* 1237 * Add the name. 1238 */ 1239 size_t cchName = strlen(pszName); 1240 if (cchName + 1 + *pfNotFirst > *pcchBuf) 1241 return VERR_BUFFER_OVERFLOW; 1242 if (*pfNotFirst) 1243 APPEND_CH(' '); 1244 else 1245 *pfNotFirst = true; 1246 APPEND_PSZ(pszName, cchName); 1247 1248 /* 1249 * Only generate mnemonics for the simple+common bits. 1250 */ 1251 if (fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1)) 1252 /* nothing */; 1253 else if ( fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_LEVEL_2 | RTLOGGRPFLAGS_FLOW) 1254 && *pcchBuf >= sizeof(".e.l.f")) 1255 APPEND_SZ(".e.l.f"); 1256 else if ( fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_FLOW) 1257 && *pcchBuf >= sizeof(".e.f")) 1258 APPEND_SZ(".e.f"); 1259 else if (*pcchBuf >= 1 + 10 + 1) 1260 { 1261 size_t cch; 1262 APPEND_CH('='); 1263 cch = RTStrFormatNumber(*ppszBuf, fGroup, 16, 0, 0, RTSTR_F_SPECIAL | RTSTR_F_32BIT); 1264 *ppszBuf += cch; 1265 *pcchBuf -= cch; 1266 } 1267 else 1268 return VERR_BUFFER_OVERFLOW; 1269 1270 #undef APPEND_PSZ 1271 #undef APPEND_SZ 1272 #undef APPEND_CH 1273 return VINF_SUCCESS; 1274 } 1275 1276 1277 /** 1278 * Get the current log group settings as a string. 1279 * 1280 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW. 1281 * @param pLogger Logger instance (NULL for default logger). 1282 * @param pszBuf The output buffer. 1283 * @param cchBuf The size of the output buffer. Must be greater 1284 * than zero. 1285 */ 1286 RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 1287 { 1288 bool fNotFirst = false; 1289 int rc = VINF_SUCCESS; 1290 uint32_t cGroups; 1291 uint32_t fGroup; 1292 uint32_t i; 1293 1294 Assert(cchBuf); 1295 1296 /* 1297 * Resolve defaults. 1298 */ 1299 if (!pLogger) 1300 { 1301 pLogger = RTLogDefaultInstance(); 1302 if (!pLogger) 1303 { 1304 *pszBuf = '\0'; 1305 return VINF_SUCCESS; 1306 } 1307 } 1308 1309 cGroups = pLogger->cGroups; 1310 1311 /* 1312 * Check if all are the same. 1313 */ 1314 fGroup = pLogger->afGroups[0]; 1315 for (i = 1; i < cGroups; i++) 1316 if (pLogger->afGroups[i] != fGroup) 1317 break; 1318 if (i >= cGroups) 1319 rc = rtLogGetGroupSettingsAddOne("all", fGroup, &pszBuf, &cchBuf, &fNotFirst); 1320 else 1321 { 1322 1323 /* 1324 * Iterate all the groups and print all that are enabled. 1325 */ 1326 for (i = 0; i < cGroups; i++) 1327 { 1328 fGroup = pLogger->afGroups[i]; 1329 if (fGroup) 1330 { 1331 const char *pszName = pLogger->papszGroups[i]; 1332 if (pszName) 1333 { 1334 rc = rtLogGetGroupSettingsAddOne(pszName, fGroup, &pszBuf, &cchBuf, &fNotFirst); 1335 if (rc) 1336 break; 1337 } 1338 } 1339 } 1340 } 1341 1342 *pszBuf = '\0'; 1343 return rc; 1344 } 1345 RT_EXPORT_SYMBOL(RTLogGetGroupSettings); 1266 1346 #endif /* !IN_RC */ 1267 1347 … … 1295 1375 while (*pszVar) 1296 1376 { 1297 /* parse instruction. */1298 static struct1299 {1300 const char *pszInstr;1301 size_t cchInstr;1302 unsigned fFlag;1303 bool fInverted;1304 } const aDest[] =1305 {1306 { "disabled", sizeof("disabled" ) - 1, RTLOGFLAGS_DISABLED, false },1307 { "enabled", sizeof("enabled" ) - 1, RTLOGFLAGS_DISABLED, true },1308 { "buffered", sizeof("buffered" ) - 1, RTLOGFLAGS_BUFFERED, false },1309 { "unbuffered", sizeof("unbuffered" ) - 1, RTLOGFLAGS_BUFFERED, true },1310 { "usecrlf", sizeof("usecrlf" ) - 1, RTLOGFLAGS_USECRLF, true },1311 { "uself", sizeof("uself" ) - 1, RTLOGFLAGS_USECRLF, false },1312 { "append", sizeof("append" ) - 1, RTLOGFLAGS_APPEND, false },1313 { "overwrite", sizeof("overwrite" ) - 1, RTLOGFLAGS_APPEND, true },1314 { "rel", sizeof("rel" ) - 1, RTLOGFLAGS_REL_TS, false },1315 { "abs", sizeof("abs" ) - 1, RTLOGFLAGS_REL_TS, true },1316 { "dec", sizeof("dec" ) - 1, RTLOGFLAGS_DECIMAL_TS, false },1317 { "hex", sizeof("hex" ) - 1, RTLOGFLAGS_DECIMAL_TS, true },1318 { "lockcnts", sizeof("lockcnts" ) - 1, RTLOGFLAGS_PREFIX_LOCK_COUNTS, false },1319 { "cpuid", sizeof("cpuid" ) - 1, RTLOGFLAGS_PREFIX_CPUID, false },1320 { "pid", sizeof("pid" ) - 1, RTLOGFLAGS_PREFIX_PID, false },1321 { "flagno", sizeof("flagno" ) - 1, RTLOGFLAGS_PREFIX_FLAG_NO, false },1322 { "flag", sizeof("flag" ) - 1, RTLOGFLAGS_PREFIX_FLAG, false },1323 { "groupno", sizeof("groupno" ) - 1, RTLOGFLAGS_PREFIX_GROUP_NO, false },1324 { "group", sizeof("group" ) - 1, RTLOGFLAGS_PREFIX_GROUP, false },1325 { "tid", sizeof("tid" ) - 1, RTLOGFLAGS_PREFIX_TID, false },1326 { "thread", sizeof("thread" ) - 1, RTLOGFLAGS_PREFIX_THREAD, false },1327 { "custom", sizeof("custom" ) - 1, RTLOGFLAGS_PREFIX_CUSTOM, false },1328 { "timeprog", sizeof("timeprog" ) - 1, RTLOGFLAGS_PREFIX_TIME_PROG, false },1329 { "time", sizeof("time" ) - 1, RTLOGFLAGS_PREFIX_TIME, false },1330 { "msprog", sizeof("msprog" ) - 1, RTLOGFLAGS_PREFIX_MS_PROG, false },1331 { "tsc", sizeof("tsc" ) - 1, RTLOGFLAGS_PREFIX_TSC, false }, /* before ts! */1332 { "ts", sizeof("ts" ) - 1, RTLOGFLAGS_PREFIX_TS, false },1333 };1334 1335 1377 /* check no prefix. */ 1336 1378 bool fNo = false; … … 1366 1408 1367 1409 /* instruction. */ 1368 for (i = 0; i < RT_ELEMENTS( aDest); i++)1369 { 1370 if (!strncmp(pszVar, aDest[i].pszInstr, aDest[i].cchInstr))1371 { 1372 if (fNo == aDest[i].fInverted)1373 pLogger->fFlags |= aDest[i].fFlag;1410 for (i = 0; i < RT_ELEMENTS(s_aLogFlags); i++) 1411 { 1412 if (!strncmp(pszVar, s_aLogFlags[i].pszInstr, s_aLogFlags[i].cchInstr)) 1413 { 1414 if (fNo == s_aLogFlags[i].fInverted) 1415 pLogger->fFlags |= s_aLogFlags[i].fFlag; 1374 1416 else 1375 pLogger->fFlags &= ~ aDest[i].fFlag;1376 pszVar += aDest[i].cchInstr;1417 pLogger->fFlags &= ~s_aLogFlags[i].fFlag; 1418 pszVar += s_aLogFlags[i].cchInstr; 1377 1419 break; 1378 1420 } … … 1380 1422 1381 1423 /* unknown instruction? */ 1382 if (i >= RT_ELEMENTS( aDest))1424 if (i >= RT_ELEMENTS(s_aLogFlags)) 1383 1425 { 1384 1426 AssertMsgFailed(("Invalid flags! unknown instruction %.20s\n", pszVar)); … … 1394 1436 } 1395 1437 RT_EXPORT_SYMBOL(RTLogFlags); 1438 1439 1440 #ifndef IN_RC 1441 /** 1442 * Get the current log flags as a string. 1443 * 1444 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW. 1445 * @param pLogger Logger instance (NULL for default logger). 1446 * @param pszBuf The output buffer. 1447 * @param cchBuf The size of the output buffer. Must be greater 1448 * than zero. 1449 */ 1450 RTDECL(int) RTLogGetFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 1451 { 1452 bool fNotFirst = false; 1453 int rc = VINF_SUCCESS; 1454 uint32_t fFlags; 1455 unsigned i; 1456 1457 Assert(cchBuf); 1458 1459 /* 1460 * Resolve defaults. 1461 */ 1462 if (!pLogger) 1463 { 1464 pLogger = RTLogDefaultInstance(); 1465 if (!pLogger) 1466 { 1467 *pszBuf = '\0'; 1468 return VINF_SUCCESS; 1469 } 1470 } 1471 1472 /* 1473 * Add the flags in the list. 1474 */ 1475 fFlags = pLogger->fFlags; 1476 for (i = 0; i < RT_ELEMENTS(s_aLogFlags); i++) 1477 if ( !s_aLogFlags[i].fInverted 1478 ? (s_aLogFlags[i].fFlag & fFlags) 1479 : !(s_aLogFlags[i].fFlag & fFlags)) 1480 { 1481 size_t cchInstr = s_aLogFlags[i].cchInstr; 1482 if (cchInstr + fNotFirst + 1 > cchBuf) 1483 { 1484 rc = VERR_BUFFER_OVERFLOW; 1485 break; 1486 } 1487 if (fNotFirst) 1488 { 1489 *pszBuf++ = ' '; 1490 cchBuf--; 1491 } 1492 memcpy(pszBuf, s_aLogFlags[i].pszInstr, cchInstr); 1493 pszBuf += cchInstr; 1494 cchBuf -= cchInstr; 1495 fNotFirst = true; 1496 } 1497 *pszBuf = '\0'; 1498 return rc; 1499 } 1500 RT_EXPORT_SYMBOL(RTLogGetFlags); 1501 1502 1503 /** 1504 * Updates the logger desination using the specified string. 1505 * 1506 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW. 1507 * @param pLogger Logger instance (NULL for default logger). 1508 * @param pszVar The value to parse. 1509 */ 1510 RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar) 1511 { 1512 /* 1513 * Resolve defaults. 1514 */ 1515 if (!pLogger) 1516 { 1517 pLogger = RTLogDefaultInstance(); 1518 if (!pLogger) 1519 return VINF_SUCCESS; 1520 } 1521 1522 /* 1523 * Do the parsing. 1524 */ 1525 while (*pszVar) 1526 { 1527 /* skip blanks. */ 1528 while (RT_C_IS_SPACE(*pszVar)) 1529 pszVar++; 1530 if (!*pszVar) 1531 break; 1532 1533 /* check no prefix. */ 1534 bool fNo = false; 1535 if (pszVar[0] == 'n' && pszVar[1] == 'o') 1536 { 1537 fNo = true; 1538 pszVar += 2; 1539 } 1540 1541 /* instruction. */ 1542 unsigned i; 1543 for (i = 0; i < RT_ELEMENTS(s_aLogDst); i++) 1544 { 1545 size_t cchInstr = strlen(s_aLogDst[i].pszInstr); 1546 if (!strncmp(pszVar, s_aLogDst[i].pszInstr, cchInstr)) 1547 { 1548 if (!fNo) 1549 pLogger->fDestFlags |= s_aLogDst[i].fFlag; 1550 else 1551 pLogger->fDestFlags &= ~s_aLogDst[i].fFlag; 1552 pszVar += cchInstr; 1553 1554 /* check for value. */ 1555 while (RT_C_IS_SPACE(*pszVar)) 1556 pszVar++; 1557 if (*pszVar == '=' || *pszVar == ':') 1558 { 1559 pszVar++; 1560 const char *pszEnd = strchr(pszVar, ';'); 1561 if (!pszEnd) 1562 pszEnd = strchr(pszVar, '\0'); 1563 #ifndef IN_RING0 1564 size_t cch = pszEnd - pszVar; 1565 1566 /* log file name */ 1567 if (i == 0 /* file */ && !fNo) 1568 { 1569 AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE); 1570 memcpy(pLogger->pszFilename, pszVar, cch); 1571 pLogger->pszFilename[cch] = '\0'; 1572 } 1573 /* log directory */ 1574 else if (i == 1 /* dir */ && !fNo) 1575 { 1576 char szTmp[RTPATH_MAX]; 1577 const char *pszFile = RTPathFilename(pLogger->pszFilename); 1578 size_t cchFile = pszFile ? strlen(pszFile) : 0; 1579 AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE); 1580 memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1); 1581 1582 memcpy(pLogger->pszFilename, pszVar, cch); 1583 pLogger->pszFilename[cch] = '\0'; 1584 RTPathStripTrailingSlash(pLogger->pszFilename); 1585 1586 cch = strlen(pLogger->pszFilename); 1587 pLogger->pszFilename[cch++] = '/'; 1588 memcpy(&pLogger->pszFilename[cch], szTmp, cchFile); 1589 } 1590 else 1591 AssertMsgFailedReturn(("Invalid destination value! %s%s doesn't take a value!\n", 1592 fNo ? "no" : "", s_aLogDst[i].pszInstr), 1593 VERR_INVALID_PARAMETER); 1594 #endif 1595 pszVar = pszEnd + (*pszEnd != '\0'); 1596 } 1597 break; 1598 } 1599 } 1600 1601 /* assert known instruction */ 1602 AssertMsgReturn(i < RT_ELEMENTS(s_aLogDst), 1603 ("Invalid destination value! unknown instruction %.20s\n", pszVar), 1604 VERR_INVALID_PARAMETER); 1605 1606 /* skip blanks and delimiters. */ 1607 while (RT_C_IS_SPACE(*pszVar) || *pszVar == ';') 1608 pszVar++; 1609 } /* while more environment variable value left */ 1610 1611 return VINF_SUCCESS; 1612 } 1613 RT_EXPORT_SYMBOL(RTLogDestinations); 1614 1615 1616 /** 1617 * Get the current log destinations as a string. 1618 * 1619 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW. 1620 * @param pLogger Logger instance (NULL for default logger). 1621 * @param pszBuf The output buffer. 1622 * @param cchBuf The size of the output buffer. Must be greater 1623 * than 0. 1624 */ 1625 RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 1626 { 1627 bool fNotFirst = false; 1628 int rc = VINF_SUCCESS; 1629 uint32_t fDestFlags; 1630 unsigned i; 1631 1632 Assert(cchBuf); 1633 1634 /* 1635 * Resolve defaults. 1636 */ 1637 if (!pLogger) 1638 { 1639 pLogger = RTLogDefaultInstance(); 1640 if (!pLogger) 1641 { 1642 *pszBuf = '\0'; 1643 return VINF_SUCCESS; 1644 } 1645 } 1646 #define APPEND_PSZ(psz,cch) do { memcpy(pszBuf, (psz), (cch)); pszBuf += (cch); cchBuf -= (cch); } while (0) 1647 #define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1) 1648 #define APPEND_CH(ch) do { *pszBuf++ = (ch); cchBuf--; } while (0) 1649 1650 /* 1651 * Add the flags in the list. 1652 */ 1653 fDestFlags = pLogger->fDestFlags; 1654 for (i = 2; i < RT_ELEMENTS(s_aLogDst); i++) 1655 if (s_aLogDst[i].fFlag & fDestFlags) 1656 { 1657 size_t cchInstr = s_aLogDst[i].cchInstr; 1658 if (cchInstr + fNotFirst + 1 > cchBuf) 1659 { 1660 rc = VERR_BUFFER_OVERFLOW; 1661 break; 1662 } 1663 if (fNotFirst) 1664 APPEND_CH(' '); 1665 fNotFirst = true; 1666 APPEND_PSZ(s_aLogDst[i].pszInstr, cchInstr); 1667 } 1668 1669 /* 1670 * Add the filename. 1671 */ 1672 if ( (fDestFlags & RTLOGDEST_FILE) 1673 && VALID_PTR(pLogger->pszFilename) 1674 && RT_SUCCESS(rc)) 1675 { 1676 size_t cchFilename = strlen(pLogger->pszFilename); 1677 if (cchFilename + sizeof("file=") - 1 + fNotFirst + 1 <= cchBuf) 1678 { 1679 if (fNotFirst) 1680 APPEND_SZ(" file="); 1681 else 1682 APPEND_SZ("file="); 1683 APPEND_PSZ(pLogger->pszFilename, cchFilename); 1684 } 1685 else 1686 rc = VERR_BUFFER_OVERFLOW; 1687 } 1688 1689 #undef APPEND_PSZ 1690 #undef APPEND_SZ 1691 #undef APPEND_CH 1692 1693 *pszBuf = '\0'; 1694 return rc; 1695 } 1696 RT_EXPORT_SYMBOL(RTLogGetDestinations); 1697 #endif /* !IN_RC */ 1396 1698 1397 1699
Note:
See TracChangeset
for help on using the changeset viewer.