Sun Apr 4 09:58:51 2021 UTC ()
make: rename ambiguous functions

These two functions have counterparts that include the word 'Do' in
their name, which is confusing.

No functional change.


(rillig)
diff -r1.422 -r1.423 src/usr.bin/make/job.c
diff -r1.554 -r1.555 src/usr.bin/make/parse.c
diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-for-errors.mk
diff -r1.8 -r1.9 src/usr.bin/make/unit-tests/opt-jobs-no-action.mk
diff -r1.7 -r1.8 src/usr.bin/make/unit-tests/shell-csh.mk

cvs diff -r1.422 -r1.423 src/usr.bin/make/job.c (expand / switch to unified diff)

--- src/usr.bin/make/job.c 2021/04/03 14:39:02 1.422
+++ src/usr.bin/make/job.c 2021/04/04 09:58:51 1.423
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: job.c,v 1.422 2021/04/03 14:39:02 rillig Exp $ */ 1/* $NetBSD: job.c,v 1.423 2021/04/04 09:58:51 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * 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.
@@ -132,27 +132,27 @@ @@ -132,27 +132,27 @@
132#ifndef USE_SELECT 132#ifndef USE_SELECT
133#include <poll.h> 133#include <poll.h>
134#endif 134#endif
135#include <signal.h> 135#include <signal.h>
136#include <utime.h> 136#include <utime.h>
137 137
138#include "make.h" 138#include "make.h"
139#include "dir.h" 139#include "dir.h"
140#include "job.h" 140#include "job.h"
141#include "pathnames.h" 141#include "pathnames.h"
142#include "trace.h" 142#include "trace.h"
143 143
144/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ 144/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
145MAKE_RCSID("$NetBSD: job.c,v 1.422 2021/04/03 14:39:02 rillig Exp $"); 145MAKE_RCSID("$NetBSD: job.c,v 1.423 2021/04/04 09:58:51 rillig Exp $");
146 146
147/* 147/*
148 * A shell defines how the commands are run. All commands for a target are 148 * A shell defines how the commands are run. All commands for a target are
149 * written into a single file, which is then given to the shell to execute 149 * written into a single file, which is then given to the shell to execute
150 * the commands from it. The commands are written to the file using a few 150 * the commands from it. The commands are written to the file using a few
151 * templates for echo control and error control. 151 * templates for echo control and error control.
152 * 152 *
153 * The name of the shell is the basename for the predefined shells, such as 153 * The name of the shell is the basename for the predefined shells, such as
154 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its 154 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its
155 * basename is used to select the type of shell; the longest match wins. 155 * basename is used to select the type of shell; the longest match wins.
156 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. 156 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh.
157 * 157 *
158 * The echoing of command lines is controlled using hasEchoCtl, echoOff, 158 * The echoing of command lines is controlled using hasEchoCtl, echoOff,
@@ -1719,27 +1719,27 @@ JobStart(GNode *gn, bool special) @@ -1719,27 +1719,27 @@ JobStart(GNode *gn, bool special)
1719 /* Create the pipe by which we'll get the shell's output. */ 1719 /* Create the pipe by which we'll get the shell's output. */
1720 JobCreatePipe(job, 3); 1720 JobCreatePipe(job, 3);
1721 1721
1722 JobExec(job, argv); 1722 JobExec(job, argv);
1723 return JOB_RUNNING; 1723 return JOB_RUNNING;
1724} 1724}
1725 1725
1726/* 1726/*
1727 * Print the output of the shell command, skipping the noPrint text of the 1727 * Print the output of the shell command, skipping the noPrint text of the
1728 * shell, if any. The default shell does not have noPrint though, which means 1728 * shell, if any. The default shell does not have noPrint though, which means
1729 * that in all practical cases, handling the output is left to the caller. 1729 * that in all practical cases, handling the output is left to the caller.
1730 */ 1730 */
1731static char * 1731static char *
1732JobOutput(char *cp, char *endp) /* XXX: should all be const */ 1732PrintOutput(char *cp, char *endp) /* XXX: should all be const */
1733{ 1733{
1734 char *ecp; /* XXX: should be const */ 1734 char *ecp; /* XXX: should be const */
1735 1735
1736 if (shell->noPrint == NULL || shell->noPrint[0] == '\0') 1736 if (shell->noPrint == NULL || shell->noPrint[0] == '\0')
1737 return cp; 1737 return cp;
1738 1738
1739 /* 1739 /*
1740 * XXX: What happens if shell->noPrint occurs on the boundary of 1740 * XXX: What happens if shell->noPrint occurs on the boundary of
1741 * the buffer? To work correctly in all cases, this should rather 1741 * the buffer? To work correctly in all cases, this should rather
1742 * be a proper stream filter instead of doing string matching on 1742 * be a proper stream filter instead of doing string matching on
1743 * selected chunks of the output. 1743 * selected chunks of the output.
1744 */ 1744 */
1745 while ((ecp = strstr(cp, shell->noPrint)) != NULL) { 1745 while ((ecp = strstr(cp, shell->noPrint)) != NULL) {
@@ -1856,27 +1856,27 @@ again: @@ -1856,27 +1856,27 @@ again:
1856 * Need to send the output to the screen. Null terminate it 1856 * Need to send the output to the screen. Null terminate it
1857 * first, overwriting the newline character if there was one. 1857 * first, overwriting the newline character if there was one.
1858 * So long as the line isn't one we should filter (according 1858 * So long as the line isn't one we should filter (according
1859 * to the shell description), we print the line, preceded 1859 * to the shell description), we print the line, preceded
1860 * by a target banner if this target isn't the same as the 1860 * by a target banner if this target isn't the same as the
1861 * one for which we last printed something. 1861 * one for which we last printed something.
1862 * The rest of the data in the buffer are then shifted down 1862 * The rest of the data in the buffer are then shifted down
1863 * to the start of the buffer and curPos is set accordingly. 1863 * to the start of the buffer and curPos is set accordingly.
1864 */ 1864 */
1865 job->outBuf[i] = '\0'; 1865 job->outBuf[i] = '\0';
1866 if (i >= job->curPos) { 1866 if (i >= job->curPos) {
1867 char *cp; 1867 char *cp;
1868 1868
1869 cp = JobOutput(job->outBuf, &job->outBuf[i]); 1869 cp = PrintOutput(job->outBuf, &job->outBuf[i]);
1870 1870
1871 /* 1871 /*
1872 * There's still more in that thar buffer. This time, 1872 * There's still more in that thar buffer. This time,
1873 * though, we know there's no newline at the end, so 1873 * though, we know there's no newline at the end, so
1874 * we add one of our own free will. 1874 * we add one of our own free will.
1875 */ 1875 */
1876 if (*cp != '\0') { 1876 if (*cp != '\0') {
1877 if (!opts.beSilent) 1877 if (!opts.beSilent)
1878 SwitchOutputTo(job->node); 1878 SwitchOutputTo(job->node);
1879#ifdef USE_META 1879#ifdef USE_META
1880 if (useMeta) { 1880 if (useMeta) {
1881 meta_job_output(job, cp, 1881 meta_job_output(job, cp,
1882 gotNL ? "\n" : ""); 1882 gotNL ? "\n" : "");

cvs diff -r1.554 -r1.555 src/usr.bin/make/parse.c (expand / switch to unified diff)

--- src/usr.bin/make/parse.c 2021/04/03 14:31:44 1.554
+++ src/usr.bin/make/parse.c 2021/04/04 09:58:51 1.555
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parse.c,v 1.554 2021/04/03 14:31:44 rillig Exp $ */ 1/* $NetBSD: parse.c,v 1.555 2021/04/04 09:58:51 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.
@@ -99,27 +99,27 @@ @@ -99,27 +99,27 @@
99 99
100#include <sys/types.h> 100#include <sys/types.h>
101#include <sys/stat.h> 101#include <sys/stat.h>
102#include <errno.h> 102#include <errno.h>
103#include <stdarg.h> 103#include <stdarg.h>
104#include <stdint.h> 104#include <stdint.h>
105 105
106#include "make.h" 106#include "make.h"
107#include "dir.h" 107#include "dir.h"
108#include "job.h" 108#include "job.h"
109#include "pathnames.h" 109#include "pathnames.h"
110 110
111/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 111/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
112MAKE_RCSID("$NetBSD: parse.c,v 1.554 2021/04/03 14:31:44 rillig Exp $"); 112MAKE_RCSID("$NetBSD: parse.c,v 1.555 2021/04/04 09:58:51 rillig Exp $");
113 113
114/* types and constants */ 114/* types and constants */
115 115
116/* 116/*
117 * Structure for a file being read ("included file") 117 * Structure for a file being read ("included file")
118 */ 118 */
119typedef struct IFile { 119typedef struct IFile {
120 char *fname; /* name of file (relative? absolute?) */ 120 char *fname; /* name of file (relative? absolute?) */
121 bool fromForLoop; /* simulated .include by the .for loop */ 121 bool fromForLoop; /* simulated .include by the .for loop */
122 int lineno; /* current line number in file */ 122 int lineno; /* current line number in file */
123 int first_lineno; /* line number of start of text */ 123 int first_lineno; /* line number of start of text */
124 unsigned int cond_depth; /* 'if' nesting when file opened */ 124 unsigned int cond_depth; /* 'if' nesting when file opened */
125 bool depending; /* state of doing_depend on EOF */ 125 bool depending; /* state of doing_depend on EOF */
@@ -2827,27 +2827,27 @@ ParseSkippedBranches(void) @@ -2827,27 +2827,27 @@ ParseSkippedBranches(void)
2827{ 2827{
2828 char *line; 2828 char *line;
2829 2829
2830 while ((line = ParseGetLine(GLM_DOT)) != NULL) { 2830 while ((line = ParseGetLine(GLM_DOT)) != NULL) {
2831 if (Cond_EvalLine(line) == COND_PARSE) 2831 if (Cond_EvalLine(line) == COND_PARSE)
2832 break; 2832 break;
2833 /* 2833 /*
2834 * TODO: Check for typos in .elif directives 2834 * TODO: Check for typos in .elif directives
2835 * such as .elsif or .elseif. 2835 * such as .elsif or .elseif.
2836 * 2836 *
2837 * This check will probably duplicate some of 2837 * This check will probably duplicate some of
2838 * the code in ParseLine. Most of the code 2838 * the code in ParseLine. Most of the code
2839 * there cannot apply, only ParseVarassign and 2839 * there cannot apply, only ParseVarassign and
2840 * ParseDependency can, and to prevent code 2840 * ParseDependencyLine can, and to prevent code
2841 * duplication, these would need to be called 2841 * duplication, these would need to be called
2842 * with a flag called onlyCheckSyntax. 2842 * with a flag called onlyCheckSyntax.
2843 * 2843 *
2844 * See directive-elif.mk for details. 2844 * See directive-elif.mk for details.
2845 */ 2845 */
2846 } 2846 }
2847 2847
2848 return line != NULL; 2848 return line != NULL;
2849} 2849}
2850 2850
2851static bool 2851static bool
2852ParseForLoop(const char *line) 2852ParseForLoop(const char *line)
2853{ 2853{
@@ -3069,27 +3069,27 @@ FindSemicolon(char *p) @@ -3069,27 +3069,27 @@ FindSemicolon(char *p)
3069 else if (level > 0 && (*p == ')' || *p == '}')) 3069 else if (level > 0 && (*p == ')' || *p == '}'))
3070 level--; 3070 level--;
3071 else if (level == 0 && *p == ';') 3071 else if (level == 0 && *p == ';')
3072 break; 3072 break;
3073 } 3073 }
3074 return p; 3074 return p;
3075} 3075}
3076 3076
3077/* 3077/*
3078 * dependency -> target... op [source...] 3078 * dependency -> target... op [source...]
3079 * op -> ':' | '::' | '!' 3079 * op -> ':' | '::' | '!'
3080 */ 3080 */
3081static void 3081static void
3082ParseDependency(char *line) 3082ParseDependencyLine(char *line)
3083{ 3083{
3084 VarEvalFlags eflags; 3084 VarEvalFlags eflags;
3085 char *expanded_line; 3085 char *expanded_line;
3086 const char *shellcmd = NULL; 3086 const char *shellcmd = NULL;
3087 3087
3088 /* 3088 /*
3089 * For some reason - probably to make the parser impossible - 3089 * For some reason - probably to make the parser impossible -
3090 * a ';' can be used to separate commands from dependencies. 3090 * a ';' can be used to separate commands from dependencies.
3091 * Attempt to avoid ';' inside substitution patterns. 3091 * Attempt to avoid ';' inside substitution patterns.
3092 */ 3092 */
3093 { 3093 {
3094 char *semicolon = FindSemicolon(line); 3094 char *semicolon = FindSemicolon(line);
3095 if (*semicolon != '\0') { 3095 if (*semicolon != '\0') {
@@ -3180,27 +3180,27 @@ ParseLine(char *line) @@ -3180,27 +3180,27 @@ ParseLine(char *line)
3180 /* 3180 /*
3181 * It's a Gmake "export". 3181 * It's a Gmake "export".
3182 */ 3182 */
3183 ParseGmakeExport(line); 3183 ParseGmakeExport(line);
3184 return; 3184 return;
3185 } 3185 }
3186#endif 3186#endif
3187 3187
3188 if (ParseVarassign(line)) 3188 if (ParseVarassign(line))
3189 return; 3189 return;
3190 3190
3191 FinishDependencyGroup(); 3191 FinishDependencyGroup();
3192 3192
3193 ParseDependency(line); 3193 ParseDependencyLine(line);
3194} 3194}
3195 3195
3196/* 3196/*
3197 * Parse a top-level makefile, incorporating its content into the global 3197 * Parse a top-level makefile, incorporating its content into the global
3198 * dependency graph. 3198 * dependency graph.
3199 * 3199 *
3200 * Input: 3200 * Input:
3201 * name The name of the file being read 3201 * name The name of the file being read
3202 * fd The open file to parse; will be closed at the end 3202 * fd The open file to parse; will be closed at the end
3203 */ 3203 */
3204void 3204void
3205Parse_File(const char *name, int fd) 3205Parse_File(const char *name, int fd)
3206{ 3206{

cvs diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-for-errors.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/directive-for-errors.mk 2020/12/31 03:05:12 1.1
+++ src/usr.bin/make/unit-tests/directive-for-errors.mk 2021/04/04 09:58:51 1.2
@@ -1,29 +1,29 @@ @@ -1,29 +1,29 @@
1# $NetBSD: directive-for-errors.mk,v 1.1 2020/12/31 03:05:12 rillig Exp $ 1# $NetBSD: directive-for-errors.mk,v 1.2 2021/04/04 09:58:51 rillig Exp $
2# 2#
3# Tests for error handling in .for loops. 3# Tests for error handling in .for loops.
4 4
5# A .for directive must be followed by whitespace, everything else results 5# A .for directive must be followed by whitespace, everything else results
6# in a parse error. 6# in a parse error.
7.fori in 1 2 3 7.fori in 1 2 3
8. warning ${i} 8. warning ${i}
9.endfor 9.endfor
10 10
11# A slash is not whitespace, therefore this is not parsed as a .for loop. 11# A slash is not whitespace, therefore this is not parsed as a .for loop.
12# 12#
13# XXX: The error message is misleading though. As of 2020-12-31, it says 13# XXX: The error message is misleading though. As of 2020-12-31, it says
14# "Unknown directive "for"", but that directive is actually known. This is 14# "Unknown directive "for"", but that directive is actually known. This is
15# because ForEval does not detect the .for loop as such, so parsing 15# because ForEval does not detect the .for loop as such, so parsing
16# continues in ParseLine > ParseDependency > ParseDoDependency > 16# continues in ParseLine > ParseDependencyLine > ParseDoDependency >
17# ParseDoDependencyTargets > ParseErrorNoDependency, and there the directive 17# ParseDoDependencyTargets > ParseErrorNoDependency, and there the directive
18# name is parsed a bit differently. 18# name is parsed a bit differently.
19.for/i in 1 2 3 19.for/i in 1 2 3
20. warning ${i} 20. warning ${i}
21.endfor 21.endfor
22 22
23# As of 2020-12-31, the variable name can be an arbitrary word, it just needs 23# As of 2020-12-31, the variable name can be an arbitrary word, it just needs
24# to be separated by whitespace. Even '$' and '\' are valid variable names, 24# to be separated by whitespace. Even '$' and '\' are valid variable names,
25# which is not useful in practice. 25# which is not useful in practice.
26# 26#
27# The '$$' is not replaced with the values '1' or '3' from the .for loop, 27# The '$$' is not replaced with the values '1' or '3' from the .for loop,
28# instead it is kept as-is, and when the .info directive expands its argument, 28# instead it is kept as-is, and when the .info directive expands its argument,
29# each '$$' gets replaced with a single '$'. The "long variable expression" 29# each '$$' gets replaced with a single '$'. The "long variable expression"

cvs diff -r1.8 -r1.9 src/usr.bin/make/unit-tests/opt-jobs-no-action.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/opt-jobs-no-action.mk 2020/12/10 23:54:41 1.8
+++ src/usr.bin/make/unit-tests/opt-jobs-no-action.mk 2021/04/04 09:58:51 1.9
@@ -1,39 +1,39 @@ @@ -1,39 +1,39 @@
1# $NetBSD: opt-jobs-no-action.mk,v 1.8 2020/12/10 23:54:41 rillig Exp $ 1# $NetBSD: opt-jobs-no-action.mk,v 1.9 2021/04/04 09:58:51 rillig Exp $
2# 2#
3# Tests for the combination of the options -j and -n, which prints the 3# Tests for the combination of the options -j and -n, which prints the
4# commands instead of actually running them. 4# commands instead of actually running them.
5# 5#
6# The format of the output differs from the output of only the -n option, 6# The format of the output differs from the output of only the -n option,
7# without the -j. This is because all this code is implemented twice, once 7# without the -j. This is because all this code is implemented twice, once
8# in compat.c and once in job.c. 8# in compat.c and once in job.c.
9# 9#
10# See also: 10# See also:
11# opt-jobs.mk 11# opt-jobs.mk
12# The corresponding tests without the -n option 12# The corresponding tests without the -n option
13# opt-no-action-combined.mk 13# opt-no-action-combined.mk
14# The corresponding tests without the -j option 14# The corresponding tests without the -j option
15 15
16.MAKEFLAGS: -j1 -n 16.MAKEFLAGS: -j1 -n
17 17
18# Change the templates for running the commands in jobs mode, to make it 18# Change the templates for running the commands in jobs mode, to make it
19# easier to see what actually happens. 19# easier to see what actually happens.
20# 20#
21# The shell attributes are handled by Job_ParseShell. 21# The shell attributes are handled by Job_ParseShell.
22# The shell attributes 'quiet' and 'echo' don't need a trailing newline, 22# The shell attributes 'quiet' and 'echo' don't need a trailing newline,
23# this is handled by the [0] != '\0' checks in Job_ParseShell. 23# this is handled by the [0] != '\0' checks in Job_ParseShell.
24# The '\#' is handled by ParseGetLine. 24# The '\#' is handled by ParseGetLine.
25# The '\n' is handled by Str_Words in Job_ParseShell. 25# The '\n' is handled by Str_Words in Job_ParseShell.
26# The '$$' is handled by Var_Subst in ParseDependency. 26# The '$$' is handled by Var_Subst in ParseDependencyLine.
27.SHELL: \ 27.SHELL: \
28 name=sh \ 28 name=sh \
29 path=${.SHELL} \ 29 path=${.SHELL} \
30 quiet="\# .echoOff" \ 30 quiet="\# .echoOff" \
31 echo="\# .echoOn" \ 31 echo="\# .echoOn" \
32 filter="\# .noPrint\n" \ 32 filter="\# .noPrint\n" \
33 check="\# .echoTmpl\n""echo \"%s\"\n" \ 33 check="\# .echoTmpl\n""echo \"%s\"\n" \
34 ignore="\# .runIgnTmpl\n""%s\n" \ 34 ignore="\# .runIgnTmpl\n""%s\n" \
35 errout="\# .runChkTmpl\n""{ %s \n} || exit $$?\n" 35 errout="\# .runChkTmpl\n""{ %s \n} || exit $$?\n"
36 36
37all: explained combined 37all: explained combined
38.ORDER: explained combined 38.ORDER: explained combined
39 39

cvs diff -r1.7 -r1.8 src/usr.bin/make/unit-tests/shell-csh.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/shell-csh.mk 2020/12/13 02:09:55 1.7
+++ src/usr.bin/make/unit-tests/shell-csh.mk 2021/04/04 09:58:51 1.8
@@ -1,28 +1,28 @@ @@ -1,28 +1,28 @@
1# $NetBSD: shell-csh.mk,v 1.7 2020/12/13 02:09:55 sjg Exp $ 1# $NetBSD: shell-csh.mk,v 1.8 2021/04/04 09:58:51 rillig Exp $
2# 2#
3# Tests for using a C shell for running the commands. 3# Tests for using a C shell for running the commands.
4 4
5CSH!= which csh 2> /dev/null || true 5CSH!= which csh 2> /dev/null || true
6 6
7# The shell path must be an absolute path. 7# The shell path must be an absolute path.
8# This is only obvious in parallel mode since in compat mode, 8# This is only obvious in parallel mode since in compat mode,
9# simple commands are executed via execve directly. 9# simple commands are executed via execve directly.
10.if ${CSH} != "" 10.if ${CSH} != ""
11.SHELL: name="csh" path="${CSH}" 11.SHELL: name="csh" path="${CSH}"
12.endif 12.endif
13 13
14# In parallel mode, the shell->noPrint command is filtered from 14# In parallel mode, the shell->noPrint command is filtered from
15# the output, rather naively (in JobOutput). 15# the output, rather naively (in PrintOutput).
16# 16#
17# Until 2020-10-03, the output in parallel mode was garbled because 17# Until 2020-10-03, the output in parallel mode was garbled because
18# the definition of the csh had been wrong since 1993 at least. 18# the definition of the csh had been wrong since 1993 at least.
19.MAKEFLAGS: -j1 19.MAKEFLAGS: -j1
20 20
21all: 21all:
22.if ${CSH} != "" 22.if ${CSH} != ""
23 # This command is both printed and executed. 23 # This command is both printed and executed.
24 echo normal 24 echo normal
25 25
26 # This command is only executed. 26 # This command is only executed.
27 @echo hidden 27 @echo hidden
28 28