Changeset 2616 in kBuild for trunk/src/kObjCache/kObjCache.c
- Timestamp:
- Aug 2, 2012 1:43:58 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kObjCache/kObjCache.c
r2615 r2616 113 113 #define MY_IS_BLANK(a_ch) ((a_ch) == ' ' || (a_ch) == '\t') 114 114 115 #define KOC_BUF_MIN KOC_BUF_ALIGNMENT 116 #define KOC_BUF_INCR KOC_BUF_ALIGNMENT 117 #define KOC_BUF_ALIGNMENT (4U*1024U*1024U) 118 115 119 116 120 /******************************************************************************* … … 1089 1093 FatalMsg("Failed to write dependency file '%s': %s\n", pszFilename, strerror(errno)); 1090 1094 } 1095 1096 1097 /** 1098 * Preprocessor output reader state. 1099 */ 1100 typedef struct KOCCPPRD 1101 { 1102 /** Pointer to the preprocessor output. */ 1103 char *pszBuf; 1104 /** Allocated buffer size. */ 1105 size_t cbBufAlloc; 1106 /** Amount preprocessor output that we've completed optimizations for. */ 1107 size_t cchOptimized; 1108 /** The offset of the next bits to process. */ 1109 size_t offCur; 1110 /** The offset where to put more raw preprocessor output. */ 1111 size_t offRead; 1112 /** The line number corresponding to offOptimized. */ 1113 uint32_t uOptLineNo; 1114 /** The current line number. */ 1115 uint32_t uCurLineNo; 1116 /** The number of lines found to be empty starting at cchOptimized. */ 1117 uint32_t cEmptyLines; 1118 /** Set if we're done, clear if we're expecting more preprocessor output. */ 1119 int fDone; 1120 /** The saved character at cchOptimized. */ 1121 char chSaved; 1122 /** Whether the optimizations are enabled. */ 1123 int fOptimize; 1124 1125 /** Buffer holding the current file name (unescaped). */ 1126 char *pszFileNmBuf; 1127 /** The size of the file name buffer. */ 1128 size_t cbFileNmBuf; 1129 /** The length of the current file string. */ 1130 size_t cchCurFileNm; 1131 1132 /** Line directive / new line sequence buffer. */ 1133 char *pszLineBuf; 1134 /** The size of the buffer pointed to by pszLineBuf. */ 1135 size_t cbLineBuf; 1136 } KOCCPPRD; 1137 /** Pointer to a preprocessor reader state. */ 1138 typedef KOCCPPRD *PKOCCPPRD; 1139 1140 1141 /** 1142 * Allocate the initial C preprocessor output buffer. 1143 * 1144 * @param pCppRd The C preprocessor reader instance. 1145 * @param cbOldCpp The size of the output the last time. This is 0 if 1146 * there was not previous run. 1147 * @param fOptimize Whether optimizations are enabled. 1148 */ 1149 static void kOCCppRdInit(PKOCCPPRD pCppRd, size_t cbOldCpp, int fOptimize) 1150 { 1151 pCppRd->cbBufAlloc = cbOldCpp ? (cbOldCpp + KOC_BUF_INCR) & ~(KOC_BUF_ALIGNMENT - 1) : KOC_BUF_MIN; 1152 pCppRd->pszBuf = xmalloc(pCppRd->cbBufAlloc); 1153 pCppRd->cchCurFileNm = 0; 1154 pCppRd->cchOptimized = 0; 1155 pCppRd->offCur = 0; 1156 pCppRd->offRead = 0; 1157 pCppRd->uOptLineNo = 1; 1158 pCppRd->uCurLineNo = 1; 1159 pCppRd->cEmptyLines = 0; 1160 pCppRd->fDone = 0; 1161 pCppRd->chSaved = 0; 1162 pCppRd->fOptimize = fOptimize; 1163 1164 pCppRd->pszFileNmBuf = NULL; 1165 pCppRd->cbFileNmBuf = 0; 1166 pCppRd->cchCurFileNm = 0; 1167 1168 pCppRd->pszLineBuf = NULL; 1169 pCppRd->cbLineBuf = 0; 1170 } 1171 1172 1173 static void kOCCppRdDelete(PKOCCPPRD pCppRd) 1174 { 1175 free(pCppRd->pszBuf); 1176 pCppRd->pszBuf = NULL; 1177 1178 free(pCppRd->pszFileNmBuf); 1179 pCppRd->pszFileNmBuf = NULL; 1180 1181 free(pCppRd->pszLineBuf); 1182 pCppRd->pszLineBuf = NULL; 1183 } 1184 1185 1186 /** 1187 * Allocate more buffer space for the C preprocessor output. 1188 * 1189 * @param pCppRd The C preprocessor reader instance. 1190 */ 1191 static size_t kOCCppRdGrowBuffer(PKOCCPPRD pCppRd) 1192 { 1193 pCppRd->cbBufAlloc += KOC_BUF_INCR; 1194 pCppRd->pszBuf = xrealloc(pCppRd->pszBuf, pCppRd->cbBufAlloc); 1195 1196 return pCppRd->cbBufAlloc - pCppRd->offRead; 1197 } 1198 1199 1200 static char *kOCCppRdOptRemove(PKOCCPPRD pCppRd, char *pszStart, size_t cbRemove) 1201 { 1202 size_t offStart = pszStart - pCppRd->pszBuf; 1203 size_t cbToMove = pCppRd->offRead - offStart; 1204 1205 assert(pCppRd->offRead >= offStart); 1206 1207 memmove(pszStart, pszStart + cbRemove, cbToMove + 1); 1208 1209 pCppRd->offRead -= cbRemove; 1210 assert(offStart >= pCppRd->offCur); 1211 assert(pCppRd->offRead < 1 || pCppRd->pszBuf[pCppRd->offRead - 1] != '\0'); 1212 return pszStart; 1213 } 1214 1215 1216 static size_t kOCCppRdOptReplace(PKOCCPPRD pCppRd, size_t offStart, size_t cchReplaced, 1217 const char *pchReplacement, size_t cchReplacement) 1218 { 1219 size_t offDelta = cchReplacement - cchReplaced; 1220 1221 if (offDelta) 1222 { 1223 size_t cbLeft = pCppRd->offRead - offStart - cchReplaced; 1224 assert(cbLeft <= pCppRd->offRead); 1225 1226 if (cchReplacement > cchReplaced) 1227 while (pCppRd->offRead + offDelta >= pCppRd->cbBufAlloc) 1228 kOCCppRdGrowBuffer(pCppRd); 1229 1230 memmove(pCppRd->pszBuf + offStart + cchReplacement, 1231 pCppRd->pszBuf + offStart + cchReplaced, 1232 cbLeft + 1); 1233 1234 pCppRd->offRead += offDelta; 1235 if (pCppRd->offCur > offStart) 1236 { 1237 assert(pCppRd->offCur >= offStart + cchReplaced); 1238 pCppRd->offCur += offDelta; 1239 } 1240 assert(pCppRd->offRead < 1 || pCppRd->pszBuf[pCppRd->offRead - 1] != '\0'); 1241 } 1242 1243 memcpy(pCppRd->pszBuf + offStart, pchReplacement, cchReplacement); 1244 1245 return offDelta; 1246 } 1247 1248 1249 static char *kOCCppRdOptGetEol(PKOCCPPRD pCppRd, char *pszCur, size_t cbLeft) 1250 { 1251 char *pszEol = memchr(pszCur, '\n', cbLeft); 1252 if (pszEol) 1253 { 1254 if (pszCur != pszEol && pszEol[-1] == '\r') 1255 pszEol--; 1256 } 1257 else if (pCppRd->fDone && cbLeft) 1258 pszEol = pszCur + cbLeft; 1259 return pszEol; 1260 } 1261 1262 static void kOCCppRdOptSetFile(PKOCCPPRD pCppRd, const char *pchFile, size_t cchFile) 1263 { 1264 if (cchFile >= pCppRd->cbFileNmBuf) 1265 { 1266 pCppRd->cbFileNmBuf = (cchFile + 15) & ~(size_t)15; 1267 pCppRd->pszFileNmBuf = xrealloc(pCppRd->pszFileNmBuf, pCppRd->cbFileNmBuf); 1268 } 1269 memcpy(pCppRd->pszFileNmBuf, pchFile, cchFile); 1270 pCppRd->pszFileNmBuf[cchFile] = '\0'; 1271 pCppRd->cchCurFileNm = cchFile; 1272 } 1273 1274 1275 static size_t kOCCppRdOptFmtLine(PKOCCPPRD pCppRd, uint32_t uLine, const char *pchFile, size_t cchFile) 1276 { 1277 size_t cchUsed; 1278 size_t cbNeeded; 1279 1280 /* Make sure we've got enough buffer space. */ 1281 cbNeeded = sizeof("#line 4888222111 \"\"\n") + cchFile; 1282 if (cbNeeded > pCppRd->cbLineBuf) 1283 { 1284 pCppRd->cbLineBuf = (cbNeeded + 32 + 15) & ~(size_t)15; 1285 pCppRd->pszLineBuf = xrealloc(pCppRd->pszLineBuf, pCppRd->cbLineBuf); 1286 } 1287 1288 /* Do the formatting. */ 1289 cchUsed = sprintf(pCppRd->pszLineBuf, "#line %lu", (unsigned long)uLine); 1290 if (cchFile) 1291 { 1292 pCppRd->pszLineBuf[cchUsed++] = ' '; 1293 pCppRd->pszLineBuf[cchUsed++] = '"'; 1294 memcpy(&pCppRd->pszLineBuf[cchUsed], pchFile, cchFile); 1295 cchUsed += cchFile; 1296 pCppRd->pszLineBuf[cchUsed++] = '"'; 1297 } 1298 pCppRd->pszLineBuf[cchUsed++] = '\n'; 1299 pCppRd->pszLineBuf[cchUsed] = '\0'; 1300 1301 return cchUsed; 1302 } 1303 1304 1305 static size_t kOCCppRdOptFmtNewLines(PKOCCPPRD pCppRd, uint32_t cNewLines) 1306 { 1307 if (cNewLines + 1 > pCppRd->cbLineBuf) 1308 { 1309 pCppRd->cbLineBuf = (cNewLines + 1 + 32 + 15) & ~(size_t)15; 1310 pCppRd->pszLineBuf = xrealloc(pCppRd->pszLineBuf, pCppRd->cbLineBuf); 1311 } 1312 1313 memset(pCppRd->pszLineBuf, '\n', cNewLines); 1314 pCppRd->pszLineBuf[cNewLines] = '\0'; 1315 return cNewLines; 1316 } 1317 1318 1319 1320 static char *kOCCppRdOptFlush(PKOCCPPRD pCppRd, char *pszCur, int fLineDirNext) 1321 { 1322 size_t const cchOptimized = pCppRd->cchOptimized; 1323 size_t const offTmp = pszCur - pCppRd->pszBuf; 1324 assert(offTmp >= cchOptimized); 1325 if (pCppRd->offCur > cchOptimized) 1326 { 1327 /* 1328 * We've got unflushed whitelines. 1329 */ 1330 size_t const cchInQuestion = pCppRd->offCur - cchOptimized; 1331 uint32_t const cLinesInQuestion = pCppRd->uCurLineNo - pCppRd->uOptLineNo; 1332 size_t cchLineDir; 1333 size_t offDelta; 1334 1335 if ( cLinesInQuestion <= 7 1336 || (cchLineDir = kOCCppRdOptFmtLine(pCppRd, pCppRd->uCurLineNo, NULL, 0)) >= cLinesInQuestion) 1337 cchLineDir = kOCCppRdOptFmtNewLines(pCppRd, cLinesInQuestion); 1338 1339 offDelta = kOCCppRdOptReplace(pCppRd, cchOptimized, cchInQuestion, pCppRd->pszLineBuf, cchLineDir); 1340 pszCur += offDelta; 1341 1342 pCppRd->cchOptimized = cchOptimized + cchLineDir; 1343 pCppRd->uOptLineNo = pCppRd->uCurLineNo; 1344 1345 /* pCppRd->offCur is adjusted by the replace call */ 1346 } 1347 1348 (void)fLineDirNext; /* Use later if required. */ 1349 return pszCur; 1350 } 1351 1352 1353 static int kOCCppRdOptParseLine(PKOCCPPRD pCppRd, char *pszCur, char *pszEol, 1354 uint32_t *puNewLineNo, char **ppszNewFile, size_t *pcchNewFile) 1355 { 1356 char *psz = pszCur; 1357 uint32_t uNewLineNo; 1358 int fIsShort; 1359 1360 /* 1361 * Check if it's a #line directive of some kind and parse it. 1362 */ 1363 if (*psz != '#') 1364 return 0; 1365 psz++; 1366 1367 fIsShort = MY_IS_BLANK(*psz); 1368 while (MY_IS_BLANK(*psz)) 1369 psz++; 1370 1371 if ( psz[0] == 'l' 1372 && psz[1] == 'i' 1373 && psz[2] == 'n' 1374 && psz[3] == 'e' 1375 && MY_IS_BLANK(psz[4]) ) 1376 { 1377 fIsShort = 0; 1378 psz += 5; 1379 while (MY_IS_BLANK(*psz)) 1380 psz++; 1381 } 1382 else if (fIsShort && isdigit(*psz)) 1383 fIsShort = 1; 1384 else 1385 return 0; 1386 1387 /* Parse the line number. */ 1388 if (!isdigit(*psz)) 1389 return 0; 1390 1391 uNewLineNo = *psz++ - '0'; 1392 while (isdigit(*psz)) 1393 { 1394 uNewLineNo *= 10; 1395 uNewLineNo += *psz++ - '0'; 1396 } 1397 if ( psz != pszEol 1398 && !MY_IS_BLANK(*psz)) 1399 return 0; 1400 1401 /* 1402 * The file name part is optional. 1403 */ 1404 while (MY_IS_BLANK(*psz)) 1405 psz++; 1406 1407 if ( psz != pszEol 1408 && *psz == '"') 1409 { 1410 *ppszNewFile = ++psz; 1411 while ( psz != pszEol 1412 && ( *psz != '"' 1413 || ( psz[-1] == '\\' 1414 && kOCDepIsEscaped(psz, psz - *ppszNewFile)) ) 1415 ) 1416 psz++; 1417 if (psz == pszEol) 1418 { 1419 /** @todo complain? */ 1420 return 0; 1421 } 1422 *pcchNewFile = psz - *ppszNewFile; 1423 1424 do 1425 psz++; 1426 while (psz != pszEol && MY_IS_BLANK(*psz)); 1427 } 1428 else 1429 { 1430 /* No file given => Same as the current. */ 1431 *ppszNewFile = pCppRd->cchCurFileNm ? pCppRd->pszFileNmBuf : NULL; 1432 *pcchNewFile = pCppRd->cchCurFileNm; 1433 } 1434 if (psz != pszEol) 1435 { 1436 /** @todo complain? */ 1437 return 0; 1438 } 1439 1440 *puNewLineNo = uNewLineNo; 1441 return 1; 1442 } 1443 1444 1445 static char *kOCCppRdOptHandleLine(PKOCCPPRD pCppRd, char *pszCur, size_t *pcbLeft, int *pfEmptyLine, char *pszEol) 1446 { 1447 size_t const cchEol = pszEol - pszCur; 1448 char *pszNewFile; 1449 size_t cchNewFile; 1450 uint32_t uNewLineNo; 1451 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1452 1453 if (!kOCCppRdOptParseLine(pCppRd, pszCur, pszEol, &uNewLineNo, &pszNewFile, &cchNewFile)) 1454 { 1455 /* 1456 * No line directive. Flush pending optimizations and indicate that 1457 * the line isn't empty and needs to be commited at EOL. 1458 */ 1459 pszEol = kOCCppRdOptFlush(pCppRd, pszEol, 0); 1460 *pfEmptyLine = 0; 1461 } 1462 else 1463 { 1464 char *pszCurFile = pCppRd->cchCurFileNm ? pCppRd->pszFileNmBuf : NULL; 1465 if ( pszNewFile == pszCurFile 1466 || ( cchNewFile == pCppRd->cchCurFileNm 1467 && !memcmp(pszNewFile, pszCurFile, cchNewFile)) ) 1468 { 1469 /* 1470 * A #line directive specifying the same file. 1471 */ 1472 if (uNewLineNo >= pCppRd->uCurLineNo) 1473 *pfEmptyLine = 1; 1474 else 1475 { 1476 /* 1477 * It went backwards, so we need to flush the old section of 1478 * the file and emit another directive for starting the new one. 1479 */ 1480 size_t const cchOrgLine = pszEol - pCppRd->pszBuf - pCppRd->offCur; 1481 size_t cchLineDir; 1482 pszEol = kOCCppRdOptFlush(pCppRd, pszEol, 1); 1483 1484 cchLineDir = kOCCppRdOptFmtLine(pCppRd, uNewLineNo, NULL, 0) - 1; /* sans \n */ 1485 1486 pszEol += kOCCppRdOptReplace(pCppRd, pCppRd->offCur, cchOrgLine, 1487 pCppRd->pszLineBuf, cchLineDir); 1488 1489 *pfEmptyLine = 0; 1490 } 1491 } 1492 else 1493 { 1494 /* 1495 * The #line directive changed the file. 1496 */ 1497 size_t const cchOrgLine = pszEol - pCppRd->pszBuf - pCppRd->offCur; 1498 size_t cchLineDir; 1499 size_t offDelta; 1500 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1501 1502 offDelta = kOCCppRdOptFlush(pCppRd, pszEol, 1) - pszEol; 1503 pszEol += offDelta; 1504 pszNewFile += offDelta; 1505 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1506 1507 kOCCppRdOptSetFile(pCppRd, pszNewFile, cchNewFile); 1508 cchLineDir = kOCCppRdOptFmtLine(pCppRd, uNewLineNo, pszNewFile, cchNewFile) - 1; /* sans \n */ 1509 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1510 1511 pszEol += kOCCppRdOptReplace(pCppRd, pCppRd->offCur, cchOrgLine, 1512 pCppRd->pszLineBuf, cchLineDir); 1513 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1514 1515 *pfEmptyLine = 0; 1516 } 1517 1518 pCppRd->uCurLineNo = uNewLineNo - 1; 1519 assert(*pszEol == '\r' || *pszEol == '\n' || *pszEol == '\0'); 1520 } 1521 1522 pCppRd->offCur = pszEol - pCppRd->pszBuf; 1523 *pcbLeft -= cchEol; 1524 return pszEol; 1525 } 1526 1527 1528 static void kOCCppRdOpt(PKOCCPPRD pCppRd) 1529 { 1530 size_t cch; 1531 char *pszEol; 1532 char *pszCur = pCppRd->pszBuf + pCppRd->offCur; 1533 size_t cbTodo = pCppRd->offRead - pCppRd->offCur; 1534 int fEmptyLine = 1; 1535 1536 while (cbTodo > 0) 1537 { 1538 switch (*pszCur) 1539 { 1540 case ' ': 1541 case '\t': 1542 break; 1543 1544 case '\n': 1545 pCppRd->offCur = pszCur - pCppRd->pszBuf + 1; 1546 pCppRd->uCurLineNo++; 1547 if (!fEmptyLine) 1548 { 1549 pCppRd->cchOptimized = pCppRd->offCur; 1550 pCppRd->uOptLineNo = pCppRd->uCurLineNo; 1551 } 1552 else 1553 pCppRd->cEmptyLines++; 1554 fEmptyLine = 1; 1555 break; 1556 1557 case '\r': /* "\r\n" -> "\n" */ 1558 if (cbTodo == 1 && !pCppRd->fDone) 1559 return; 1560 if (pszCur[1] == '\n') 1561 { 1562 pszCur = kOCCppRdOptRemove(pCppRd, pszCur, 1); 1563 cbTodo -= 1; 1564 continue; 1565 } 1566 break; 1567 1568 case '#': 1569 pszEol = kOCCppRdOptGetEol(pCppRd, pszCur + 1, cbTodo - 1); 1570 if (!pszEol) 1571 return; 1572 pszCur = kOCCppRdOptHandleLine(pCppRd, pszCur, &cbTodo, &fEmptyLine, pszEol); 1573 continue; 1574 1575 default: 1576 /* 1577 * Some non-white stuff encountered, flush pending white 1578 * line optimizations and skip to the end of the line. 1579 */ 1580 fEmptyLine = 0; 1581 pszEol = kOCCppRdOptGetEol(pCppRd, pszCur + 1, cbTodo - 1); 1582 if (!pszEol) 1583 return; 1584 cch = pszEol - pszCur; 1585 1586 pszCur = kOCCppRdOptFlush(pCppRd, pszCur, 0); 1587 1588 cbTodo -= cch; 1589 pszCur += cch; 1590 continue; 1591 } 1592 1593 cbTodo--; 1594 pszCur++; 1595 } 1596 } 1597 1598 1599 static void kOCCppRdOptFinalize(PKOCCPPRD pCppRd) 1600 { 1601 pCppRd->fDone = 1; 1602 assert(pCppRd->offRead < 1 || pCppRd->pszBuf[pCppRd->offRead - 1] != '\0'); 1603 pCppRd->pszBuf[pCppRd->offRead] = '\0'; 1604 kOCCppRdOpt(pCppRd); 1605 kOCCppRdOptFlush(pCppRd, pCppRd->pszBuf + pCppRd->offCur, 0); 1606 } 1607 1608 1609 1610 /** 1611 * Read C preprocessor output from the given file descriptor, optionally 1612 * optimzing it. 1613 * 1614 * @returns Number of bytes read. 0 indicates end of file. 1615 * 1616 * @param pCppRd The C preprocessor reader instance. 1617 * @param fdIn The file descriptor to read the raw preprocessor output 1618 * from. 1619 * @param ppszRet Where to return the pointer to the output. 1620 * 1621 * @remarks Won't return on error, calls FatalDie on those occasions. 1622 */ 1623 static long kOCCppRdRead(PKOCCPPRD pCppRd, int fdIn, const char **ppszRet) 1624 { 1625 size_t cbLeft; 1626 long cbRead; 1627 1628 if (pCppRd->fOptimize) 1629 { 1630 /* 1631 * Optimize the C preprocessor output on the way thru. 1632 */ 1633 size_t const cchOldOptimized = pCppRd->cchOptimized; 1634 if (pCppRd->chSaved) 1635 pCppRd->pszBuf[pCppRd->cchOptimized] = pCppRd->chSaved; 1636 1637 do 1638 { 1639 /* Read more raw C preprocessor output. */ 1640 cbLeft = pCppRd->cbBufAlloc - pCppRd->offRead; 1641 if (cbLeft <= 1) 1642 cbLeft = kOCCppRdGrowBuffer(pCppRd); 1643 if (cbLeft > 256*1024) 1644 cbLeft = 256*1024; /* memmove() get's expensive if there is to much to work on - bad algorithm! */ 1645 1646 do 1647 cbRead = read(fdIn, pCppRd->pszBuf + pCppRd->offRead, (long)(cbLeft - 1)); 1648 while (cbRead < 0 && errno == EINTR); 1649 if (cbRead < 0) 1650 FatalDie("kOCCppRdRead - read(%d,,%ld) failed: %s\n", 1651 fdIn, (long)(cbLeft - 1), strerror(errno)); 1652 pCppRd->offRead += cbRead; 1653 1654 /* Optimize it. */ 1655 if (!cbRead) 1656 { 1657 kOCCppRdOptFinalize(pCppRd); 1658 break; 1659 } 1660 kOCCppRdOpt(pCppRd); 1661 } while (pCppRd->cchOptimized == cchOldOptimized); 1662 1663 *ppszRet = &pCppRd->pszBuf[cchOldOptimized]; 1664 pCppRd->chSaved = pCppRd->pszBuf[pCppRd->cchOptimized]; 1665 pCppRd->pszBuf[pCppRd->cchOptimized] = '\0'; 1666 cbRead = (long)(pCppRd->cchOptimized - cchOldOptimized); 1667 } 1668 else 1669 { 1670 /* 1671 * Pass thru. 1672 */ 1673 char *pszBuf; 1674 cbLeft = pCppRd->cbBufAlloc - pCppRd->offRead; 1675 if (cbLeft <= 1) 1676 cbLeft = kOCCppRdGrowBuffer(pCppRd); 1677 pszBuf = pCppRd->pszBuf + pCppRd->offRead; 1678 1679 do 1680 cbRead = read(fdIn, pszBuf, (long)(cbLeft - 1)); 1681 while (cbRead < 0 && errno == EINTR); 1682 if (cbRead < 0) 1683 FatalDie("kOCCppRdRead - read(%d,,%ld) failed: %s\n", 1684 fdIn, (long)(cbLeft - 1), strerror(errno)); 1685 1686 *ppszRet = pszBuf; 1687 pCppRd->offRead += cbRead; 1688 pszBuf[cbRead] = '\0'; 1689 } 1690 1691 return cbRead; 1692 } 1693 1694 1695 /** 1696 * Grabs the output buffer from the C preprocessor reader. 1697 * 1698 * @param pCppRd The C preprocessor reader instance. 1699 * @param ppszRet Where to return the pointer to the output. 1700 * @param pcbRet Where to return the size of the output. 1701 */ 1702 static void kOCCppRdGrabOutput(PKOCCPPRD pCppRd, char **ppszRet, size_t *pcbRet) 1703 { 1704 assert(pCppRd->offRead < 1 || pCppRd->pszBuf[pCppRd->offRead - 1] != '\0'); 1705 *ppszRet = pCppRd->pszBuf; 1706 *pcbRet = pCppRd->offRead; 1707 pCppRd->pszBuf = NULL; 1708 pCppRd->offRead = 0; 1709 } 1710 1711 1091 1712 1092 1713 … … 1433 2054 /** The dependency collector state. */ 1434 2055 KOCDEP DepState; 2056 /** Whether the optimizations are enabled. */ 2057 int fOptimizeCpp; 1435 2058 /** Cache entry key that's used for some quick digest validation. */ 1436 2059 uint32_t uKey; … … 2045 2668 2046 2669 /** 2670 * Configures the preprocessor output optimizations. 2671 * 2672 * @param pEntry The cache entry. 2673 * @param fOptimizeCpp The one and only flag, so far. 2674 */ 2675 static void kOCEntrySetOptimizations(PKOCENTRY pEntry, int fOptimizeCpp) 2676 { 2677 pEntry->fOptimizeCpp = fOptimizeCpp; 2678 } 2679 2680 2681 /** 2047 2682 * Spawns a child in a synchronous fashion. 2048 2683 * Terminating on failure. … … 2470 3105 { 2471 3106 KOCSUMCTX Ctx; 2472 long cbLeft; 2473 long cbAlloc; 2474 char *psz; 3107 KOCCPPRD CppRd; 2475 3108 2476 3109 kOCSumInitWithCtx(&pEntry->New.SumHead, &Ctx); 2477 cbAlloc = pEntry->Old.cbCpp ? ((long)pEntry->Old.cbCpp + 4*1024*1024 + 4096) & ~(4*1024*1024 - 1) : 4*1024*1024; 2478 cbLeft = cbAlloc; 2479 pEntry->New.pszCppMapping = psz = xmalloc(cbAlloc); 3110 kOCCppRdInit(&CppRd, pEntry->Old.cbCpp, pEntry->fOptimizeCpp); 3111 2480 3112 for (;;) 2481 3113 { … … 2483 3115 * Read data from the pipe. 2484 3116 */ 2485 long cbRead = read(fdIn, psz, cbLeft - 1); 3117 const char *psz; 3118 long cbRead = kOCCppRdRead(&CppRd, fdIn, &psz); 2486 3119 if (!cbRead) 2487 3120 break; 2488 if (cbRead < 0)2489 {2490 if (errno == EINTR)2491 continue;2492 FatalDie("PreProcess - read(%d,,%ld) failed: %s\n",2493 fdIn, (long)cbLeft, strerror(errno));2494 }2495 3121 2496 3122 /* 2497 3123 * Process the data. 2498 3124 */ 2499 psz[cbRead] = '\0';2500 3125 kOCSumUpdate(&pEntry->New.SumHead, &Ctx, psz, cbRead); 2501 3126 if (pEntry->pszMakeDepFilename) 2502 3127 kOCDepConsumer(&pEntry->DepState, psz, cbRead); 2503 2504 /*2505 * Advance.2506 */2507 psz += cbRead;2508 cbLeft -= cbRead;2509 if (cbLeft <= 1)2510 {2511 size_t off = psz - pEntry->New.pszCppMapping;2512 cbLeft += 4*1024*1024;2513 cbAlloc += 4*1024*1024;2514 pEntry->New.pszCppMapping = xrealloc(pEntry->New.pszCppMapping, cbAlloc);2515 psz = pEntry->New.pszCppMapping + off;2516 }2517 3128 } 2518 3129 2519 3130 close(fdIn); 2520 pEntry->New.cbCpp = cbAlloc - cbLeft; 3131 kOCCppRdGrabOutput(&CppRd, &pEntry->New.pszCppMapping, &pEntry->New.cbCpp); 3132 kOCCppRdDelete(&CppRd); 2521 3133 kOCSumFinalize(&pEntry->New.SumHead, &Ctx); 2522 3134 kOCSumInfo(&pEntry->New.SumHead, 4, "cpp (pipe)"); … … 2566 3178 2567 3179 /* 2568 * Pre compileit and calculate the checksum on the output.3180 * Preprocess it and calculate the checksum on the output. 2569 3181 */ 2570 3182 InfoMsg(3, "precompiling -> '%s'...\n", pEntry->New.pszCppName); … … 2747 3359 #endif 2748 3360 KOCSUMCTX Ctx; 2749 long cbLeft; 2750 long cbAlloc; 2751 char *psz; 3361 KOCCPPRD CppRd; 2752 3362 2753 3363 kOCSumInitWithCtx(&pEntry->New.SumHead, &Ctx); 2754 cbAlloc = pEntry->Old.cbCpp ? ((long)pEntry->Old.cbCpp + 4*1024*1024 + 4096) & ~(4*1024*1024 - 1) : 4*1024*1024; 2755 cbLeft = cbAlloc; 2756 pEntry->New.pszCppMapping = psz = xmalloc(cbAlloc); 3364 kOCCppRdInit(&CppRd, pEntry->Old.cbCpp, pEntry->fOptimizeCpp); 2757 3365 InfoMsg(3, "preprocessor|compile - starting passhtru...\n"); 2758 3366 for (;;) … … 2761 3369 * Read data from the pipe. 2762 3370 */ 2763 long cbRead = read(fdIn, psz, cbLeft - 1); 3371 const char *psz; 3372 long cbRead = kOCCppRdRead(&CppRd, fdIn, &psz); 2764 3373 if (!cbRead) 2765 3374 break; 2766 if (cbRead < 0)2767 {2768 if (errno == EINTR)2769 continue;2770 FatalDie("preprocess|compile - read(%d,,%ld) failed: %s\n",2771 fdIn, (long)cbLeft, strerror(errno));2772 }2773 3375 InfoMsg(3, "preprocessor|compile - read %d\n", cbRead); 2774 3376 … … 2776 3378 * Process the data. 2777 3379 */ 2778 psz[cbRead] = '\0';2779 3380 kOCSumUpdate(&pEntry->New.SumHead, &Ctx, psz, cbRead); 2780 3381 if (pEntry->pszMakeDepFilename) … … 2797 3398 psz += cbWritten; 2798 3399 cbRead -= cbWritten; 2799 cbLeft -= cbWritten;2800 3400 } while (cbRead > 0); 2801 3401 2802 /*2803 * Expand the buffer?2804 */2805 if (cbLeft <= 1)2806 {2807 size_t off = psz - pEntry->New.pszCppMapping;2808 cbLeft = 4*1024*1024;2809 cbAlloc += cbLeft;2810 pEntry->New.pszCppMapping = xrealloc(pEntry->New.pszCppMapping, cbAlloc);2811 psz = pEntry->New.pszCppMapping + off;2812 }2813 3402 } 2814 3403 InfoMsg(3, "preprocessor|compile - done passhtru\n"); … … 2816 3405 close(fdIn); 2817 3406 close(fdOut); 2818 pEntry->New.cbCpp = cbAlloc - cbLeft; 3407 kOCCppRdGrabOutput(&CppRd, &pEntry->New.pszCppMapping, &pEntry->New.cbCpp); 3408 kOCCppRdDelete(&CppRd); 2819 3409 kOCSumFinalize(&pEntry->New.SumHead, &Ctx); 2820 3410 kOCSumInfo(&pEntry->New.SumHead, 4, "cpp (tee)"); … … 4270 4860 int fMakeDepGenStubs = 0; 4271 4861 int fMakeDepQuiet = 0; 4862 int fOptimizePreprocessorOutput = 0; 4272 4863 4273 4864 const char *pszTarget = NULL; … … 4387 4978 else if (!strcmp(argv[i], "--make-dep-quiet")) 4388 4979 fMakeDepQuiet = 1; 4980 else if (!strcmp(argv[i], "-O1") || !strcmp(argv[i], "--optimize-1")) 4981 fOptimizePreprocessorOutput = 1; 4389 4982 else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--passthru")) 4390 4983 fRedirPreCompStdOut = fRedirCompileStdIn = 1; … … 4438 5031 if (!psz || psz <= pszCacheName) 4439 5032 psz = (char *)pszCacheName + cch; 4440 memcpy(psz, ".koc", sizeof(".koc") - 1);5033 memcpy(psz, ".koc", sizeof(".koc")); 4441 5034 } 4442 5035 pszCacheFile = MakePathFromDirAndFile(pszCacheName, pszCacheDir); … … 4461 5054 kOCEntrySetPipedMode(pEntry, fRedirPreCompStdOut, fRedirCompileStdIn, pszNmPipeCompile); 4462 5055 kOCEntrySetDepFilename(pEntry, pszMakeDepFilename, fMakeDepFixCase, fMakeDepQuiet, fMakeDepGenStubs); 5056 kOCEntrySetOptimizations(pEntry, fOptimizePreprocessorOutput); 4463 5057 4464 5058 /*
Note:
See TracChangeset
for help on using the changeset viewer.