| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: parse.c,v 1.387 2020/10/18 19:11:35 rillig Exp $ */ | | 1 | /* $NetBSD: parse.c,v 1.388 2020/10/18 20:07:26 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -121,27 +121,27 @@ | | | @@ -121,27 +121,27 @@ |
121 | #ifndef MAP_FILE | | 121 | #ifndef MAP_FILE |
122 | #define MAP_FILE 0 | | 122 | #define MAP_FILE 0 |
123 | #endif | | 123 | #endif |
124 | #ifndef MAP_COPY | | 124 | #ifndef MAP_COPY |
125 | #define MAP_COPY MAP_PRIVATE | | 125 | #define MAP_COPY MAP_PRIVATE |
126 | #endif | | 126 | #endif |
127 | | | 127 | |
128 | #include "make.h" | | 128 | #include "make.h" |
129 | #include "dir.h" | | 129 | #include "dir.h" |
130 | #include "job.h" | | 130 | #include "job.h" |
131 | #include "pathnames.h" | | 131 | #include "pathnames.h" |
132 | | | 132 | |
133 | /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ | | 133 | /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ |
134 | MAKE_RCSID("$NetBSD: parse.c,v 1.387 2020/10/18 19:11:35 rillig Exp $"); | | 134 | MAKE_RCSID("$NetBSD: parse.c,v 1.388 2020/10/18 20:07:26 rillig Exp $"); |
135 | | | 135 | |
136 | /* types and constants */ | | 136 | /* types and constants */ |
137 | | | 137 | |
138 | /* | | 138 | /* |
139 | * Structure for a file being read ("included file") | | 139 | * Structure for a file being read ("included file") |
140 | */ | | 140 | */ |
141 | typedef struct IFile { | | 141 | typedef struct IFile { |
142 | char *fname; /* name of file */ | | 142 | char *fname; /* name of file */ |
143 | Boolean fromForLoop; /* simulated .include by the .for loop */ | | 143 | Boolean fromForLoop; /* simulated .include by the .for loop */ |
144 | int lineno; /* current line number in file */ | | 144 | int lineno; /* current line number in file */ |
145 | int first_lineno; /* line number of start of text */ | | 145 | int first_lineno; /* line number of start of text */ |
146 | unsigned int cond_depth; /* 'if' nesting when file opened */ | | 146 | unsigned int cond_depth; /* 'if' nesting when file opened */ |
147 | Boolean depending; /* state of doing_depend on EOF */ | | 147 | Boolean depending; /* state of doing_depend on EOF */ |
| @@ -1743,26 +1743,71 @@ ParseDoDependency(char *line) | | | @@ -1743,26 +1743,71 @@ ParseDoDependency(char *line) |
1743 | if (!ParseDoDependencySourcesMundane(line, cp, specType, tOp)) | | 1743 | if (!ParseDoDependencySourcesMundane(line, cp, specType, tOp)) |
1744 | goto out; | | 1744 | goto out; |
1745 | } | | 1745 | } |
1746 | | | 1746 | |
1747 | FindMainTarget(); | | 1747 | FindMainTarget(); |
1748 | | | 1748 | |
1749 | out: | | 1749 | out: |
1750 | if (paths != NULL) | | 1750 | if (paths != NULL) |
1751 | Lst_Free(paths); | | 1751 | Lst_Free(paths); |
1752 | if (curTargs != NULL) | | 1752 | if (curTargs != NULL) |
1753 | Lst_Free(curTargs); | | 1753 | Lst_Free(curTargs); |
1754 | } | | 1754 | } |
1755 | | | 1755 | |
| | | 1756 | /* Determine the assignment operator and adjust the end of the variable |
| | | 1757 | * name accordingly. */ |
| | | 1758 | static void |
| | | 1759 | ParseVarassignOp(VarAssign *var) |
| | | 1760 | { |
| | | 1761 | const char *op = var->eq; |
| | | 1762 | const char * const name = var->nameStart; |
| | | 1763 | VarAssignOp type; |
| | | 1764 | |
| | | 1765 | if (op > name && op[-1] == '+') { |
| | | 1766 | type = VAR_APPEND; |
| | | 1767 | op--; |
| | | 1768 | |
| | | 1769 | } else if (op > name && op[-1] == '?') { |
| | | 1770 | op--; |
| | | 1771 | type = VAR_DEFAULT; |
| | | 1772 | |
| | | 1773 | } else if (op > name && op[-1] == ':') { |
| | | 1774 | op--; |
| | | 1775 | type = VAR_SUBST; |
| | | 1776 | |
| | | 1777 | } else if (op > name && op[-1] == '!') { |
| | | 1778 | op--; |
| | | 1779 | type = VAR_SHELL; |
| | | 1780 | |
| | | 1781 | } else { |
| | | 1782 | type = VAR_NORMAL; |
| | | 1783 | #ifdef SUNSHCMD |
| | | 1784 | while (op > name && ch_isspace(op[-1])) |
| | | 1785 | op--; |
| | | 1786 | |
| | | 1787 | if (op >= name + 3 && op[-3] == ':' && op[-2] == 's' && op[-1] == 'h') { |
| | | 1788 | type = VAR_SHELL; |
| | | 1789 | op -= 3; |
| | | 1790 | } |
| | | 1791 | #endif |
| | | 1792 | } |
| | | 1793 | |
| | | 1794 | { |
| | | 1795 | const char *nameEnd = var->nameEndDraft < op ? var->nameEndDraft : op; |
| | | 1796 | var->varname = bmake_strsedup(var->nameStart, nameEnd); |
| | | 1797 | var->op = type; |
| | | 1798 | } |
| | | 1799 | } |
| | | 1800 | |
1756 | /* Parse a variable assignment, consisting of a single-word variable name, | | 1801 | /* Parse a variable assignment, consisting of a single-word variable name, |
1757 | * optional whitespace, an assignment operator, optional whitespace and the | | 1802 | * optional whitespace, an assignment operator, optional whitespace and the |
1758 | * variable value. | | 1803 | * variable value. |
1759 | * | | 1804 | * |
1760 | * Used for both lines in a file and command line arguments. */ | | 1805 | * Used for both lines in a file and command line arguments. */ |
1761 | Boolean | | 1806 | Boolean |
1762 | Parse_IsVar(const char *p, VarAssign *out_var) | | 1807 | Parse_IsVar(const char *p, VarAssign *out_var) |
1763 | { | | 1808 | { |
1764 | const char *firstSpace = NULL; | | 1809 | const char *firstSpace = NULL; |
1765 | char ch; | | 1810 | char ch; |
1766 | int level = 0; | | 1811 | int level = 0; |
1767 | | | 1812 | |
1768 | /* Skip to variable name */ | | 1813 | /* Skip to variable name */ |
| @@ -1824,71 +1869,26 @@ Parse_IsVar(const char *p, VarAssign *ou | | | @@ -1824,71 +1869,26 @@ Parse_IsVar(const char *p, VarAssign *ou |
1824 | ch == '?' ? VAR_DEFAULT : VAR_SHELL; | | 1869 | ch == '?' ? VAR_DEFAULT : VAR_SHELL; |
1825 | p++; | | 1870 | p++; |
1826 | cpp_skip_whitespace(&p); | | 1871 | cpp_skip_whitespace(&p); |
1827 | out_var->value = p; | | 1872 | out_var->value = p; |
1828 | return TRUE; | | 1873 | return TRUE; |
1829 | } | | 1874 | } |
1830 | if (firstSpace != NULL) | | 1875 | if (firstSpace != NULL) |
1831 | return FALSE; | | 1876 | return FALSE; |
1832 | } | | 1877 | } |
1833 | | | 1878 | |
1834 | return FALSE; | | 1879 | return FALSE; |
1835 | } | | 1880 | } |
1836 | | | 1881 | |
1837 | /* Determine the assignment operator and adjust the end of the variable | | | |
1838 | * name accordingly. */ | | | |
1839 | static void | | | |
1840 | ParseVarassignOp(VarAssign *var) | | | |
1841 | { | | | |
1842 | const char *op = var->eq; | | | |
1843 | const char * const name = var->nameStart; | | | |
1844 | VarAssignOp type; | | | |
1845 | | | | |
1846 | if (op > name && op[-1] == '+') { | | | |
1847 | type = VAR_APPEND; | | | |
1848 | op--; | | | |
1849 | | | | |
1850 | } else if (op > name && op[-1] == '?') { | | | |
1851 | op--; | | | |
1852 | type = VAR_DEFAULT; | | | |
1853 | | | | |
1854 | } else if (op > name && op[-1] == ':') { | | | |
1855 | op--; | | | |
1856 | type = VAR_SUBST; | | | |
1857 | | | | |
1858 | } else if (op > name && op[-1] == '!') { | | | |
1859 | op--; | | | |
1860 | type = VAR_SHELL; | | | |
1861 | | | | |
1862 | } else { | | | |
1863 | type = VAR_NORMAL; | | | |
1864 | #ifdef SUNSHCMD | | | |
1865 | while (op > name && ch_isspace(op[-1])) | | | |
1866 | op--; | | | |
1867 | | | | |
1868 | if (op >= name + 3 && op[-3] == ':' && op[-2] == 's' && op[-1] == 'h') { | | | |
1869 | type = VAR_SHELL; | | | |
1870 | op -= 3; | | | |
1871 | } | | | |
1872 | #endif | | | |
1873 | } | | | |
1874 | | | | |
1875 | { | | | |
1876 | const char *nameEnd = var->nameEndDraft < op ? var->nameEndDraft : op; | | | |
1877 | var->varname = bmake_strsedup(var->nameStart, nameEnd); | | | |
1878 | var->op = type; | | | |
1879 | } | | | |
1880 | } | | | |
1881 | | | | |
1882 | static void | | 1882 | static void |
1883 | VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *ctxt) | | 1883 | VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *ctxt) |
1884 | { | | 1884 | { |
1885 | if (DEBUG(LINT)) { | | 1885 | if (DEBUG(LINT)) { |
1886 | if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) { | | 1886 | if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) { |
1887 | /* Check for syntax errors such as unclosed expressions or | | 1887 | /* Check for syntax errors such as unclosed expressions or |
1888 | * unknown modifiers. */ | | 1888 | * unknown modifiers. */ |
1889 | char *expandedValue; | | 1889 | char *expandedValue; |
1890 | | | 1890 | |
1891 | (void)Var_Subst(uvalue, ctxt, VARE_NONE, &expandedValue); | | 1891 | (void)Var_Subst(uvalue, ctxt, VARE_NONE, &expandedValue); |
1892 | /* TODO: handle errors */ | | 1892 | /* TODO: handle errors */ |
1893 | free(expandedValue); | | 1893 | free(expandedValue); |
1894 | } | | 1894 | } |