| 479 | */ |
| 480 | |
| 481 | char **CSLInsertStrings(char **papszStrList, int nInsertAtLineNo, |
| 482 | CSLConstList papszNewLines) |
| 483 | { |
| 484 | if (papszNewLines == nullptr) |
| 485 | return papszStrList; // Nothing to do! |
| 486 | |
| 487 | const int nToInsert = CSLCount(papszNewLines); |
| 488 | if (nToInsert == 0) |
| 489 | return papszStrList; // Nothing to do! |
| 490 | |
| 491 | const int nSrcLines = CSLCount(papszStrList); |
| 492 | const int nDstLines = nSrcLines + nToInsert; |
| 493 | |
| 494 | // Allocate room for the new strings. |
| 495 | papszStrList = static_cast<char **>( |
| 496 | CPLRealloc(papszStrList, (nDstLines + 1) * sizeof(char *))); |
| 497 | |
| 498 | // Make sure the array is NULL-terminated. It may not be if |
| 499 | // papszStrList was NULL before Realloc(). |
| 500 | papszStrList[nSrcLines] = nullptr; |
| 501 | |
| 502 | // Make some room in the original list at the specified location. |
| 503 | // Note that we also have to move the NULL pointer at the end of |
| 504 | // the source StringList. |
| 505 | if (nInsertAtLineNo == -1 || nInsertAtLineNo > nSrcLines) |
| 506 | nInsertAtLineNo = nSrcLines; |
| 507 | |
| 508 | { |
| 509 | char **ppszSrc = papszStrList + nSrcLines; |
| 510 | char **ppszDst = papszStrList + nDstLines; |
| 511 | |
| 512 | for (int i = nSrcLines; i >= nInsertAtLineNo; --i) |
| 513 | { |
| 514 | *ppszDst = *ppszSrc; |
| 515 | --ppszDst; |
| 516 | --ppszSrc; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | // Copy the strings to the list. |
| 521 | CSLConstList ppszSrc = papszNewLines; |
| 522 | char **ppszDst = papszStrList + nInsertAtLineNo; |
| 523 | |
| 524 | for (; *ppszSrc != nullptr; ++ppszSrc, ++ppszDst) |
| 525 | { |
| 526 | *ppszDst = CPLStrdup(*ppszSrc); |
| 527 | } |
| 528 | |
| 529 | return papszStrList; |
| 530 | } |
| 531 | |
| 532 | /********************************************************************** |
| 533 | * CSLInsertString() |
no test coverage detected