diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-10-24 10:59:04 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-17 15:25:24 +0200 |
commit | d72f0a0008697df2533aad69e9daddaa4ace10ca (patch) | |
tree | 4db7b31955d636126f55c5cb528952e0379ae22a | |
parent | 9dcef9e579d2e06f294dabe7918fe6753054e6cb (diff) | |
download | grecs-d72f0a0008697df2533aad69e9daddaa4ace10ca.tar.gz grecs-d72f0a0008697df2533aad69e9daddaa4ace10ca.tar.bz2 |
Various improvements in wordsplit
* src/wordsplit.c (wordsplit_trimws): Retutn int.
(wordsplit_tildexpand,wordsplit_pathexpand): Add missing return.
(wordsplit_process_list): Rewrite in a table-driven fashion.
-rw-r--r-- | src/wordsplit.c | 147 |
1 files changed, 58 insertions, 89 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index 6b01887..403ffed 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -1183,7 +1183,7 @@ wordsplit_cmdexp (struct wordsplit *wsp) | |||
1183 | /* Strip off any leading and trailing whitespace. This function is called | 1183 | /* Strip off any leading and trailing whitespace. This function is called |
1184 | right after the initial scanning, therefore it assumes that every | 1184 | right after the initial scanning, therefore it assumes that every |
1185 | node in the list is a text reference node. */ | 1185 | node in the list is a text reference node. */ |
1186 | static void | 1186 | static int |
1187 | wordsplit_trimws (struct wordsplit *wsp) | 1187 | wordsplit_trimws (struct wordsplit *wsp) |
1188 | { | 1188 | { |
1189 | struct wordsplit_node *p; | 1189 | struct wordsplit_node *p; |
@@ -1209,6 +1209,7 @@ wordsplit_trimws (struct wordsplit *wsp) | |||
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | wsnode_nullelim (wsp); | 1211 | wsnode_nullelim (wsp); |
1212 | return 0; | ||
1212 | } | 1213 | } |
1213 | 1214 | ||
1214 | static int | 1215 | static int |
@@ -1230,7 +1231,6 @@ wordsplit_tildexpand (struct wordsplit *wsp) | |||
1230 | { | 1231 | { |
1231 | size_t i, size, dlen; | 1232 | size_t i, size, dlen; |
1232 | size_t slen = wsnode_len (p); | 1233 | size_t slen = wsnode_len (p); |
1233 | char *dir; | ||
1234 | struct passwd *pw; | 1234 | struct passwd *pw; |
1235 | char *newstr; | 1235 | char *newstr; |
1236 | 1236 | ||
@@ -1282,6 +1282,7 @@ wordsplit_tildexpand (struct wordsplit *wsp) | |||
1282 | } | 1282 | } |
1283 | } | 1283 | } |
1284 | free (uname); | 1284 | free (uname); |
1285 | return 0; | ||
1285 | } | 1286 | } |
1286 | 1287 | ||
1287 | static int | 1288 | static int |
@@ -1302,7 +1303,6 @@ wordsplit_pathexpand (struct wordsplit *wsp) | |||
1302 | char *pattern = NULL; | 1303 | char *pattern = NULL; |
1303 | size_t patsize = 0; | 1304 | size_t patsize = 0; |
1304 | size_t slen; | 1305 | size_t slen; |
1305 | char *str; | ||
1306 | int flags = 0; | 1306 | int flags = 0; |
1307 | 1307 | ||
1308 | #ifdef GLOB_PERIOD | 1308 | #ifdef GLOB_PERIOD |
@@ -1398,6 +1398,7 @@ wordsplit_pathexpand (struct wordsplit *wsp) | |||
1398 | } | 1398 | } |
1399 | } | 1399 | } |
1400 | free (pattern); | 1400 | free (pattern); |
1401 | return 0; | ||
1401 | } | 1402 | } |
1402 | 1403 | ||
1403 | static int | 1404 | static int |
@@ -1805,9 +1806,37 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex) | |||
1805 | } | 1806 | } |
1806 | } | 1807 | } |
1807 | 1808 | ||
1809 | struct exptab | ||
1810 | { | ||
1811 | char *descr; | ||
1812 | int flag; | ||
1813 | int opt; | ||
1814 | int (*expansion) (struct wordsplit *wsp); | ||
1815 | }; | ||
1816 | |||
1817 | #define EXPOPT_NEG 0x01 | ||
1818 | #define EXPOPT_COALESCE 0x02 | ||
1819 | |||
1820 | static struct exptab exptab[] = { | ||
1821 | { N_("WS trimming"), WRDSF_WS, 0, wordsplit_trimws }, | ||
1822 | { N_("tilde expansion"), WRDSF_PATHEXPAND, 0, wordsplit_tildexpand }, | ||
1823 | { N_("variable expansion"), WRDSF_NOVAR, EXPOPT_NEG, | ||
1824 | wordsplit_varexp }, | ||
1825 | { N_("quote removal"), 0, EXPOPT_NEG, | ||
1826 | wsnode_quoteremoval }, | ||
1827 | { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE, | ||
1828 | wordsplit_cmdexp }, | ||
1829 | { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, | ||
1830 | NULL }, | ||
1831 | { N_("path expansion"), WRDSF_PATHEXPAND, 0, wordsplit_pathexpand }, | ||
1832 | { NULL } | ||
1833 | }; | ||
1834 | |||
1808 | static int | 1835 | static int |
1809 | wordsplit_process_list (struct wordsplit *wsp, size_t start) | 1836 | wordsplit_process_list (struct wordsplit *wsp, size_t start) |
1810 | { | 1837 | { |
1838 | struct exptab *p; | ||
1839 | |||
1811 | if (wsp->ws_flags & WRDSF_NOSPLIT) | 1840 | if (wsp->ws_flags & WRDSF_NOSPLIT) |
1812 | { | 1841 | { |
1813 | /* Treat entire input as a quoted argument */ | 1842 | /* Treat entire input as a quoted argument */ |
@@ -1829,97 +1858,37 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start) | |||
1829 | 1858 | ||
1830 | if (wsp->ws_flags & WRDSF_SHOWDBG) | 1859 | if (wsp->ws_flags & WRDSF_SHOWDBG) |
1831 | { | 1860 | { |
1832 | wsp->ws_debug ("Initial list:"); | 1861 | wsp->ws_debug (_("Initial list:")); |
1833 | wordsplit_dump_nodes (wsp); | 1862 | wordsplit_dump_nodes (wsp); |
1834 | } | 1863 | } |
1835 | 1864 | ||
1836 | if (wsp->ws_flags & WRDSF_WS) | 1865 | for (p = exptab; p->descr; p++) |
1837 | { | ||
1838 | /* Trim leading and trailing whitespace */ | ||
1839 | wordsplit_trimws (wsp); | ||
1840 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1841 | { | ||
1842 | wsp->ws_debug ("After WS trimming:"); | ||
1843 | wordsplit_dump_nodes (wsp); | ||
1844 | } | ||
1845 | } | ||
1846 | |||
1847 | if (wsp->ws_flags & WRDSF_PATHEXPAND) | ||
1848 | { | 1866 | { |
1849 | wordsplit_tildexpand (wsp); | 1867 | if ((p->opt & EXPOPT_NEG) |
1850 | if (wsp->ws_flags & WRDSF_SHOWDBG) | 1868 | ? !(wsp->ws_flags & p->flag) : (wsp->ws_flags & p->flag)) |
1851 | { | 1869 | { |
1852 | wsp->ws_debug ("After tilde expansion:"); | 1870 | if (p->opt & EXPOPT_COALESCE) |
1853 | wordsplit_dump_nodes (wsp); | 1871 | { |
1854 | } | 1872 | if (wsnode_coalesce (wsp)) |
1855 | } | 1873 | break; |
1856 | 1874 | if (wsp->ws_flags & WRDSF_SHOWDBG) | |
1857 | /* Expand variables */ | 1875 | { |
1858 | if (!(wsp->ws_flags & WRDSF_NOVAR)) | 1876 | wsp->ws_debug (_("Coalesced list:")); |
1859 | { | 1877 | wordsplit_dump_nodes (wsp); |
1860 | if (wordsplit_varexp (wsp)) | 1878 | } |
1861 | { | 1879 | } |
1862 | wordsplit_free_nodes (wsp); | 1880 | if (p->expansion) |
1863 | return wsp->ws_errno; | 1881 | { |
1864 | } | 1882 | if (p->expansion (wsp)) |
1865 | if (wsp->ws_flags & WRDSF_SHOWDBG) | 1883 | break; |
1866 | { | 1884 | if (wsp->ws_flags & WRDSF_SHOWDBG) |
1867 | wsp->ws_debug ("After variable expansion:"); | 1885 | { |
1868 | wordsplit_dump_nodes (wsp); | 1886 | wsp->ws_debug ("%s:", _(p->descr)); |
1869 | } | 1887 | wordsplit_dump_nodes (wsp); |
1870 | } | 1888 | } |
1871 | 1889 | } | |
1872 | if (wsnode_quoteremoval (wsp)) | ||
1873 | return wsp->ws_errno; | ||
1874 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1875 | { | ||
1876 | wsp->ws_debug ("After quote removal:"); | ||
1877 | wordsplit_dump_nodes (wsp); | ||
1878 | } | ||
1879 | |||
1880 | /* Expand commands */ | ||
1881 | if (!(wsp->ws_flags & WRDSF_NOCMD)) | ||
1882 | { | ||
1883 | if (wsnode_coalesce (wsp)) | ||
1884 | return wsp->ws_errno; | ||
1885 | |||
1886 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1887 | { | ||
1888 | wsp->ws_debug ("Coalesced list:"); | ||
1889 | wordsplit_dump_nodes (wsp); | ||
1890 | } | ||
1891 | |||
1892 | if (wordsplit_cmdexp (wsp)) | ||
1893 | { | ||
1894 | wordsplit_free_nodes (wsp); | ||
1895 | return wsp->ws_errno; | ||
1896 | } | ||
1897 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1898 | { | ||
1899 | wsp->ws_debug ("After command expansion:"); | ||
1900 | wordsplit_dump_nodes (wsp); | ||
1901 | } | 1890 | } |
1902 | } | 1891 | } |
1903 | |||
1904 | if (wsnode_coalesce (wsp)) | ||
1905 | return wsp->ws_errno; | ||
1906 | |||
1907 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1908 | { | ||
1909 | wsp->ws_debug ("Coalesced list:"); | ||
1910 | wordsplit_dump_nodes (wsp); | ||
1911 | } | ||
1912 | |||
1913 | if (wsp->ws_flags & WRDSF_PATHEXPAND) | ||
1914 | { | ||
1915 | wordsplit_pathexpand (wsp); | ||
1916 | if (wsp->ws_flags & WRDSF_SHOWDBG) | ||
1917 | { | ||
1918 | wsp->ws_debug ("After path expansion:"); | ||
1919 | wordsplit_dump_nodes (wsp); | ||
1920 | } | ||
1921 | } | ||
1922 | |||
1923 | return wsp->ws_errno; | 1892 | return wsp->ws_errno; |
1924 | } | 1893 | } |
1925 | 1894 | ||
@@ -1957,7 +1926,7 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, | |||
1957 | } | 1926 | } |
1958 | 1927 | ||
1959 | if (wsp->ws_flags & WRDSF_SHOWDBG) | 1928 | if (wsp->ws_flags & WRDSF_SHOWDBG) |
1960 | wsp->ws_debug ("Input:%.*s;", (int) cmdlen, cmdptr); | 1929 | wsp->ws_debug (_("Input:%.*s;"), (int) cmdlen, cmdptr); |
1961 | 1930 | ||
1962 | rc = wordsplit_process_list (wsp, start); | 1931 | rc = wordsplit_process_list (wsp, start); |
1963 | if (rc == 0 && (flags & WRDSF_INCREMENTAL)) | 1932 | if (rc == 0 && (flags & WRDSF_INCREMENTAL)) |
@@ -1969,7 +1938,7 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, | |||
1969 | { | 1938 | { |
1970 | cmdptr = wsp->ws_input + wsp->ws_endp; | 1939 | cmdptr = wsp->ws_input + wsp->ws_endp; |