1715 |
equality. Return is string-boolean, ie, the empty string is false. |
equality. Return is string-boolean, ie, the empty string is false. |
1716 |
*/ |
*/ |
1717 |
static char * |
static char * |
1718 |
func_eq (char* o, char **argv, char *funcname) |
func_eq (char *o, char **argv, char *funcname) |
1719 |
{ |
{ |
1720 |
int result = ! strcmp (argv[0], argv[1]); |
int result = ! strcmp (argv[0], argv[1]); |
1721 |
o = variable_buffer_output (o, result ? "1" : "", result); |
o = variable_buffer_output (o, result ? "1" : "", result); |
1727 |
string-boolean not operator. |
string-boolean not operator. |
1728 |
*/ |
*/ |
1729 |
static char * |
static char * |
1730 |
func_not (char* o, char **argv, char *funcname) |
func_not (char *o, char **argv, char *funcname) |
1731 |
{ |
{ |
1732 |
char * s = argv[0]; |
char *s = argv[0]; |
1733 |
int result = 0; |
int result = 0; |
1734 |
while (isspace ((unsigned char)*s)) |
while (isspace ((unsigned char)*s)) |
1735 |
s++; |
s++; |
1740 |
#endif |
#endif |
1741 |
|
|
1742 |
|
|
1743 |
|
/* Return the absolute name of file NAME which does not contain any `.', |
1744 |
|
`..' components nor any repeated path separators ('/'). */ |
1745 |
|
|
1746 |
|
static char * |
1747 |
|
abspath (const char *name, char *apath) |
1748 |
|
{ |
1749 |
|
char *dest; |
1750 |
|
const char *start, *end, *apath_limit; |
1751 |
|
|
1752 |
|
if (name[0] == '\0' || apath == NULL) |
1753 |
|
return NULL; |
1754 |
|
|
1755 |
|
apath_limit = apath + PATH_MAX; |
1756 |
|
|
1757 |
|
if (name[0] != '/') |
1758 |
|
{ |
1759 |
|
/* It is unlikely we would make it until here but just to make sure. */ |
1760 |
|
if (!starting_directory) |
1761 |
|
return NULL; |
1762 |
|
|
1763 |
|
strcpy (apath, starting_directory); |
1764 |
|
|
1765 |
|
dest = strchr (apath, '\0'); |
1766 |
|
} |
1767 |
|
else |
1768 |
|
{ |
1769 |
|
apath[0] = '/'; |
1770 |
|
dest = apath + 1; |
1771 |
|
} |
1772 |
|
|
1773 |
|
for (start = end = name; *start != '\0'; start = end) |
1774 |
|
{ |
1775 |
|
unsigned long len; |
1776 |
|
|
1777 |
|
/* Skip sequence of multiple path-separators. */ |
1778 |
|
while (*start == '/') |
1779 |
|
++start; |
1780 |
|
|
1781 |
|
/* Find end of path component. */ |
1782 |
|
for (end = start; *end != '\0' && *end != '/'; ++end) |
1783 |
|
; |
1784 |
|
|
1785 |
|
len = end - start; |
1786 |
|
|
1787 |
|
if (len == 0) |
1788 |
|
break; |
1789 |
|
else if (len == 1 && start[0] == '.') |
1790 |
|
/* nothing */; |
1791 |
|
else if (len == 2 && start[0] == '.' && start[1] == '.') |
1792 |
|
{ |
1793 |
|
/* Back up to previous component, ignore if at root already. */ |
1794 |
|
if (dest > apath + 1) |
1795 |
|
while ((--dest)[-1] != '/'); |
1796 |
|
} |
1797 |
|
else |
1798 |
|
{ |
1799 |
|
if (dest[-1] != '/') |
1800 |
|
*dest++ = '/'; |
1801 |
|
|
1802 |
|
if (dest + len >= apath_limit) |
1803 |
|
return NULL; |
1804 |
|
|
1805 |
|
dest = memcpy (dest, start, len); |
1806 |
|
dest += len; |
1807 |
|
*dest = '\0'; |
1808 |
|
} |
1809 |
|
} |
1810 |
|
|
1811 |
|
/* Unless it is root strip trailing separator. */ |
1812 |
|
if (dest > apath + 1 && dest[-1] == '/') |
1813 |
|
--dest; |
1814 |
|
|
1815 |
|
*dest = '\0'; |
1816 |
|
|
1817 |
|
return apath; |
1818 |
|
} |
1819 |
|
|
1820 |
|
|
1821 |
|
static char * |
1822 |
|
func_realpath (char *o, char **argv, const char *funcname UNUSED) |
1823 |
|
{ |
1824 |
|
/* Expand the argument. */ |
1825 |
|
char *p = argv[0]; |
1826 |
|
char *path = 0; |
1827 |
|
int doneany = 0; |
1828 |
|
unsigned int len = 0; |
1829 |
|
|
1830 |
|
char in[PATH_MAX]; |
1831 |
|
char out[PATH_MAX]; |
1832 |
|
|
1833 |
|
while ((path = find_next_token (&p, &len)) != 0) |
1834 |
|
{ |
1835 |
|
if (len < PATH_MAX) |
1836 |
|
{ |
1837 |
|
strncpy (in, path, len); |
1838 |
|
in[len] = '\0'; |
1839 |
|
|
1840 |
|
if |
1841 |
|
( |
1842 |
|
#ifdef HAVE_REALPATH |
1843 |
|
realpath (in, out) |
1844 |
|
#else |
1845 |
|
abspath (in, out) |
1846 |
|
#endif |
1847 |
|
) |
1848 |
|
{ |
1849 |
|
o = variable_buffer_output (o, out, strlen (out)); |
1850 |
|
o = variable_buffer_output (o, " ", 1); |
1851 |
|
doneany = 1; |
1852 |
|
} |
1853 |
|
} |
1854 |
|
} |
1855 |
|
|
1856 |
|
/* Kill last space. */ |
1857 |
|
if (doneany) |
1858 |
|
--o; |
1859 |
|
|
1860 |
|
return o; |
1861 |
|
} |
1862 |
|
|
1863 |
|
static char * |
1864 |
|
func_abspath (char *o, char **argv, const char *funcname UNUSED) |
1865 |
|
{ |
1866 |
|
/* Expand the argument. */ |
1867 |
|
char *p = argv[0]; |
1868 |
|
char *path = 0; |
1869 |
|
int doneany = 0; |
1870 |
|
unsigned int len = 0; |
1871 |
|
|
1872 |
|
char in[PATH_MAX]; |
1873 |
|
char out[PATH_MAX]; |
1874 |
|
|
1875 |
|
while ((path = find_next_token (&p, &len)) != 0) |
1876 |
|
{ |
1877 |
|
if (len < PATH_MAX) |
1878 |
|
{ |
1879 |
|
strncpy (in, path, len); |
1880 |
|
in[len] = '\0'; |
1881 |
|
|
1882 |
|
if (abspath (in, out)) |
1883 |
|
{ |
1884 |
|
o = variable_buffer_output (o, out, strlen (out)); |
1885 |
|
o = variable_buffer_output (o, " ", 1); |
1886 |
|
doneany = 1; |
1887 |
|
} |
1888 |
|
} |
1889 |
|
} |
1890 |
|
|
1891 |
|
/* Kill last space. */ |
1892 |
|
if (doneany) |
1893 |
|
--o; |
1894 |
|
|
1895 |
|
return o; |
1896 |
|
} |
1897 |
|
|
1898 |
/* Lookup table for builtin functions. |
/* Lookup table for builtin functions. |
1899 |
|
|
1900 |
This doesn't have to be sorted; we use a straight lookup. We might gain |
This doesn't have to be sorted; we use a straight lookup. We might gain |
1913 |
static struct function_table_entry function_table_init[] = |
static struct function_table_entry function_table_init[] = |
1914 |
{ |
{ |
1915 |
/* Name/size */ /* MIN MAX EXP? Function */ |
/* Name/size */ /* MIN MAX EXP? Function */ |
1916 |
|
{ STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath}, |
1917 |
{ STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, |
{ STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, |
1918 |
{ STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, |
{ STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, |
1919 |
{ STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir}, |
{ STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir}, |
1928 |
{ STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, |
{ STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, |
1929 |
{ STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword}, |
{ STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword}, |
1930 |
{ STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, |
{ STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, |
1931 |
|
{ STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath}, |
1932 |
{ STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, |
{ STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, |
1933 |
{ STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, |
{ STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, |
1934 |
{ STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip}, |
{ STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip}, |