* Build an environment block combining the inherited environment * merged with the given list of settings. * * Values of the form "KEY=VALUE" in deltaenv override inherited values. * Values of the form "KEY" in deltaenv delete inherited values. * * Multiple entries in deltaenv for the same key are explicitly allowed. * * We return a contiguous block of UNICODE strings with a final trailing
| 1784 | * zero word. |
| 1785 | */ |
| 1786 | static wchar_t *make_environment_block(char **deltaenv) |
| 1787 | { |
| 1788 | wchar_t *wenv = GetEnvironmentStringsW(), *wdeltaenv, *result, *p; |
| 1789 | size_t wlen, s, delta_size, size; |
| 1790 | |
| 1791 | wchar_t **array = NULL; |
| 1792 | size_t alloc = 0, nr = 0, i; |
| 1793 | |
| 1794 | size = 1; /* for extra NUL at the end */ |
| 1795 | |
| 1796 | /* If there is no deltaenv to apply, simply return a copy. */ |
| 1797 | if (!deltaenv || !*deltaenv) { |
| 1798 | for (p = wenv; p && *p; ) { |
| 1799 | size_t s = wcslen(p) + 1; |
| 1800 | size += s; |
| 1801 | p += s; |
| 1802 | } |
| 1803 | |
| 1804 | DUP_ARRAY(result, wenv, size); |
| 1805 | FreeEnvironmentStringsW(wenv); |
| 1806 | return result; |
| 1807 | } |
| 1808 | |
| 1809 | /* |
| 1810 | * If there is a deltaenv, let's accumulate all keys into `array`, |
| 1811 | * sort them using the stable git_stable_qsort() and then copy, |
| 1812 | * skipping duplicate keys |
| 1813 | */ |
| 1814 | for (p = wenv; p && *p; ) { |
| 1815 | ALLOC_GROW(array, nr + 1, alloc); |
| 1816 | s = wcslen(p) + 1; |
| 1817 | array[nr++] = p; |
| 1818 | p += s; |
| 1819 | size += s; |
| 1820 | } |
| 1821 | |
| 1822 | /* (over-)assess size needed for wchar version of deltaenv */ |
| 1823 | for (delta_size = 0, i = 0; deltaenv[i]; i++) |
| 1824 | delta_size += strlen(deltaenv[i]) * 2 + 1; |
| 1825 | ALLOC_ARRAY(wdeltaenv, delta_size); |
| 1826 | |
| 1827 | /* convert the deltaenv, appending to array */ |
| 1828 | for (i = 0, p = wdeltaenv; deltaenv[i]; i++) { |
| 1829 | ALLOC_GROW(array, nr + 1, alloc); |
| 1830 | wlen = xutftowcs(p, deltaenv[i], wdeltaenv + delta_size - p); |
| 1831 | array[nr++] = p; |
| 1832 | p += wlen + 1; |
| 1833 | } |
| 1834 | |
| 1835 | git_stable_qsort(array, nr, sizeof(*array), wenvcmp); |
| 1836 | ALLOC_ARRAY(result, size + delta_size); |
| 1837 | |
| 1838 | for (p = result, i = 0; i < nr; i++) { |
| 1839 | /* Skip any duplicate keys; last one wins */ |
| 1840 | while (i + 1 < nr && !wenvcmp(array + i, array + i + 1)) |
| 1841 | i++; |
| 1842 | |
| 1843 | /* Skip "to delete" entry */ |
no test coverage detected