- Timestamp:
- Mar 31, 2020 1:12:19 AM (5 years ago)
- Location:
- trunk/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kDepPre/kDepPre.c
r3167 r3315 469 469 { 470 470 depOptimize(&This, fFixCase, 0 /* fQuiet */, NULL /*pszIgnoredExt*/); 471 fprintf(pOutput, "%s:", pszTarget); 472 depPrint(&This, pOutput); 471 depPrintTargetWithDeps(&This, pOutput, pszTarget, 1 /*fEscapeTarget*/); 473 472 if (fStubs) 474 473 depPrintStubs(&This, pOutput); -
trunk/src/kObjCache/kObjCache.c
r3239 r3315 1134 1134 *psz++ = '/'; 1135 1135 1136 fprintf(pFile, "%s:", pszObjFileAbs);1136 depPrintTargetWithDeps(&pDepState->Core, pFile, pszObjFileAbs, 1 /*fEscapeTarget*/); 1137 1137 free(pszObjFileAbs); 1138 depPrint(&pDepState->Core, pFile);1139 1138 if (fGenStubs) 1140 1139 depPrintStubs(&pDepState->Core, pFile); -
trunk/src/kmk/kmkbuiltin/kDepIDB.c
r3192 r3315 830 830 { 831 831 depOptimize(&This.Core, fFixCase, fQuiet, NULL /*pszIgnoredExt*/); 832 fprintf(pOutput, "%s:", pszTarget); 833 depPrint(&This.Core, pOutput); 832 depPrintTargetWithDeps(&This.Core, pOutput, pszTarget, 1 /*fEscapeTarget*/); 834 833 if (fStubs) 835 834 depPrintStubs(&This.Core, pOutput); -
trunk/src/kmk/kmkbuiltin/kDepObj.c
r3238 r3315 1188 1188 { 1189 1189 depOptimize(&This.Core, fFixCase, fQuiet, pszIgnoreExt); 1190 fprintf(pOutput, "%s:", pszTarget); 1191 depPrint(&This.Core, pOutput); 1190 depPrintTargetWithDeps(&This.Core, pOutput, pszTarget, 1 /*fEscapeTarget*/); 1192 1191 if (fStubs) 1193 1192 depPrintStubs(&This.Core, pOutput); -
trunk/src/lib/kDep.c
r3174 r3315 326 326 327 327 /** 328 * Write a filename that contains characters that needs escaping. 329 * 330 * @param pOutput The output stream. 331 * @param pszFile The filename. 332 * @param cchFile The length of the filename. 333 * @param fDep Whether this is for a dependency file or a target file. 334 */ 335 int depNeedsEscaping(const char *pszFile, size_t cchFile, int fDependency) 336 { 337 return memchr(pszFile, ' ', cchFile) != NULL 338 || memchr(pszFile, '\t', cchFile) != NULL 339 || memchr(pszFile, '#', cchFile) != NULL 340 || memchr(pszFile, '=', cchFile) != NULL 341 || memchr(pszFile, ';', cchFile) != NULL 342 || memchr(pszFile, '$', cchFile) != NULL 343 || memchr(pszFile, fDependency ? '|' : '%', cchFile) != NULL; 344 } 345 346 347 /** 348 * Write a filename that contains characters that needs escaping. 349 * 350 * @param pOutput The output stream. 351 * @param pszFile The filename. 352 * @param cchFile The length of the filename. 353 * @param fDep Whether this is for a dependency file or a target file. 354 */ 355 void depEscapedWrite(FILE *pOutput, const char *pszFile, size_t cchFile, int fDepenency) 356 { 357 size_t cchWritten = 0; 358 size_t off = 0; 359 while (off < cchFile) 360 { 361 char const ch = pszFile[off]; 362 switch (ch) 363 { 364 default: 365 off++; 366 break; 367 368 /* 369 * Escaped by slash, but any preceeding slashes must be escaped too. 370 * A couple of characters are only escaped on one side of the ':'. 371 */ 372 case '%': /* target side only */ 373 case '|': /* dependency side only */ 374 if (ch != (fDepenency ? '|' : '%')) 375 { 376 off++; 377 break; 378 } 379 /* fall thru */ 380 case ' ': 381 case '\t': 382 case '#': 383 case '=': /** @todo buggy GNU make handling */ 384 case ';': /** @todo buggy GNU make handling */ 385 if (cchWritten < off) 386 fwrite(&pszFile[cchWritten], off - cchWritten, 1, pOutput); 387 if (off == 0 || pszFile[off - 1] != '\\') 388 { 389 fputc('\\', pOutput); 390 cchWritten = off; /* We write the escaped character with the next bunch. */ 391 } 392 else 393 { 394 size_t cchSlashes = 1; 395 while (cchSlashes < off && pszFile[off - cchSlashes - 1] == '\\') 396 cchSlashes++; 397 fwrite(&pszFile[off - cchSlashes], cchSlashes, 1, pOutput); 398 cchWritten = off - 1; /* Write a preceeding slash and the escaped character with the next bunch. */ 399 } 400 off += 1; 401 break; 402 403 /* 404 * Escaped by doubling it. 405 * Implemented by including in the pending writeout job as well as in the next one. 406 */ 407 case '$': 408 fwrite(&pszFile[cchWritten], off - cchWritten + 1, 1, pOutput); 409 cchWritten = off++; /* write it again the next time */ 410 break; 411 } 412 } 413 414 /* Remainder: */ 415 if (cchWritten < cchFile) 416 fwrite(&pszFile[cchWritten], cchFile - cchWritten, 1, pOutput); 417 } 418 419 420 /** 421 * Escapes all trailing trailing slashes in a filename that ends with such. 422 */ 423 static void depPrintTrailngSlashEscape(FILE *pOutput, const char *pszFilename, size_t cchFilename) 424 { 425 size_t cchSlashes = 1; 426 while (cchSlashes < cchFilename && pszFilename[cchFilename - cchSlashes - 1] == '\\') 427 cchSlashes++; 428 fwrite(&pszFilename[cchFilename - cchSlashes], cchSlashes, 1, pOutput); 429 } 430 431 432 /** 328 433 * Prints the dependency chain. 329 434 * … … 331 436 * @param pOutput Output stream. 332 437 */ 333 void depPrint(PDEPGLOBALS pThis, FILE *pOutput) 334 { 438 void depPrintChain(PDEPGLOBALS pThis, FILE *pOutput) 439 { 440 static char const g_szEntryText[] = " \\\n\t"; 441 static char const g_szTailText[] = "\n\n"; 442 static char const g_szTailSlashText[] = " \\\n\n"; 443 PDEP pDep; 444 for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext) 445 { 446 fwrite(g_szEntryText, sizeof(g_szEntryText) - 1, 1, pOutput); 447 if (!pDep->fNeedsEscaping) 448 fwrite(pDep->szFilename, pDep->cchFilename, 1, pOutput); 449 else 450 depEscapedWrite(pOutput, pDep->szFilename, pDep->cchFilename, 1 /*fDependency*/); 451 if (pDep->fTrailingSlash) 452 { /* Escape only if more dependencies. If last, we must add a line continuation or it won't work. */ 453 if (pDep->pNext) 454 depPrintTrailngSlashEscape(pOutput, pDep->szFilename, pDep->cchFilename); 455 else 456 { 457 fwrite(g_szTailSlashText, sizeof(g_szTailSlashText), 1, pOutput); 458 return; 459 } 460 } 461 } 462 463 fwrite(g_szTailText, sizeof(g_szTailText) - 1, 1, pOutput); 464 } 465 466 467 /** 468 * Prints the dependency chain with a preceeding target. 469 * 470 * @param pThis The 'dep' instance. 471 * @param pOutput Output stream. 472 * @param pszTarget The target filename. 473 * @param fEscapeTarget Whether to consider escaping the target. 474 */ 475 void depPrintTargetWithDeps(PDEPGLOBALS pThis, FILE *pOutput, const char *pszTarget, int fEscapeTarget) 476 { 477 static char const g_szSeparator[] = ":"; 478 size_t const cchTarget = strlen(pszTarget); 479 if (!fEscapeTarget || !depNeedsEscaping(pszTarget, cchTarget, 0 /*fDependency*/)) 480 fwrite(pszTarget, cchTarget, 1, pOutput); 481 else 482 depEscapedWrite(pOutput, pszTarget, cchTarget, 0 /*fDependency*/); 483 484 if (cchTarget == 0 || pszTarget[cchTarget - 1] != '\\') 485 { /* likely */ } 486 else 487 depPrintTrailngSlashEscape(pOutput, pszTarget, cchTarget); 488 fwrite(g_szSeparator, sizeof(g_szSeparator) - 1, 1, pOutput); 489 490 depPrintChain(pThis, pOutput); 491 } 492 493 494 /** 495 * Prints empty dependency stubs for all dependencies. 496 * 497 * @param pThis The 'dep' instance. 498 * @param pOutput Output stream. 499 */ 500 void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput) 501 { 502 static char g_szTailText[] = ":\n\n"; 335 503 PDEP pDep; 336 504 for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext) 337 fprintf(pOutput, " \\\n\t%s", pDep->szFilename); 338 fprintf(pOutput, "\n\n"); 339 } 340 341 342 /** 343 * Prints empty dependency stubs for all dependencies. 344 * 345 * @param pThis The 'dep' instance. 346 * @param pOutput Output stream. 347 */ 348 void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput) 349 { 350 PDEP pDep; 351 for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext) 352 fprintf(pOutput, "%s:\n\n", pDep->szFilename); 505 { 506 if (!pDep->fNeedsEscaping && memchr(pDep->szFilename, '%', pDep->cchFilename) == 0) 507 fwrite(pDep->szFilename, pDep->cchFilename, 1, pOutput); 508 else 509 depEscapedWrite(pOutput, pDep->szFilename, pDep->cchFilename, 0 /*fDependency*/); 510 511 if (pDep->cchFilename == 0 || !pDep->fTrailingSlash) 512 { /* likely */ } 513 else 514 depPrintTrailngSlashEscape(pOutput, pDep->szFilename, pDep->cchFilename); 515 fwrite(g_szTailText, sizeof(g_szTailText) - 1, 1, pOutput); 516 } 353 517 } 354 518 … … 415 579 memcpy(pDep->szFilename, pszFilename, cchFilename); 416 580 pDep->szFilename[cchFilename] = '\0'; 581 pDep->fNeedsEscaping = depNeedsEscaping(pszFilename, cchFilename, 1 /*fDependency*/); 582 pDep->fTrailingSlash = cchFilename > 0 && pszFilename[cchFilename - 1] == '\\'; 417 583 pDep->uHash = uHash; 418 584 -
trunk/src/lib/kDep.h
r3167 r3315 40 40 /** The filename hash. */ 41 41 unsigned uHash; 42 /** Set if needs escaping. */ 43 char fNeedsEscaping; 44 /** Set if filename ends with a slash and may require special processing. */ 45 char fTrailingSlash; 42 46 /** The length of the filename. */ 43 47 size_t cchFilename; … … 58 62 extern PDEP depAdd(PDEPGLOBALS pThis, const char *pszFilename, size_t cchFilename); 59 63 extern void depOptimize(PDEPGLOBALS pThis, int fFixCase, int fQuiet, const char *pszIgnoredExt); 60 extern void depPrint(PDEPGLOBALS pThis, FILE *pOutput); 64 extern int depNeedsEscaping(const char *pszFile, size_t cchFile, int fDependency); 65 extern void depEscapedWrite(FILE *pOutput, const char *pszFile, size_t cchFile, int fDepenency); 66 extern void depPrintChain(PDEPGLOBALS pThis, FILE *pOutput); 67 extern void depPrintTargetWithDeps(PDEPGLOBALS pThis, FILE *pOutput, const char *pszTarget, int fEscapeTarget); 61 68 extern void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput); 62 69
Note:
See TracChangeset
for help on using the changeset viewer.