From f970315766906ed789656d87720328b5513e5942 Mon Sep 17 00:00:00 2001 From: Hartmut Becker Date: Sat, 23 Aug 2014 17:54:21 +0200 Subject: [PATCH] Enhance/fix VMS multi-line support. * job.c: split the command line at a newline. * default.c, vmsjobs.c: change ECHO variable to a pseudo builtin, which ensures that the VMS/DCL ECHO ("write sys$output") is used and is correctly quoted. * vmsjobs.c: remove unused builtin 'rm'. --- default.c | 2 +- job.c | 23 ++++++++++++++++++++- vmsjobs.c | 60 +++++++++++++++++++++++++++++-------------------------- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/default.c b/default.c index 48b899d9..48974c9d 100644 --- a/default.c +++ b/default.c @@ -333,7 +333,7 @@ static const char *default_variables[] = #endif "CD", "builtin_cd", "MAKE", "make", - "ECHO", "write sys$$output \"", + "ECHO", "builtin_echo", #ifdef GCC_IS_NATIVE "C++", "gcc/plus", "CXX", "gcc/plus", diff --git a/job.c b/job.c index f75c7f2e..b3eab130 100644 --- a/job.c +++ b/job.c @@ -1,5 +1,5 @@ /* Job execution and handling for GNU Make. -Copyright (C) 1988-2013 Free Software Foundation, Inc. +Copyright (C) 1988-2014 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the @@ -1214,6 +1214,27 @@ start_job_command (struct child *child) char *end = 0; #ifdef VMS argv = p; + /* Although construct_command_argv contains some code for VMS, it was/is + not called/used. Please note, for VMS argv is a string (not an array + of strings) which contains the complete command line, which for + multi-line variables still includes the newlines. So detect newlines + and set 'end' (which is used for child->command_ptr) instead of + (re-)writing construct_command_argv */ + { + char *s = p; + int instring = 0; + while (*s) + { + if (*s == '"') + instring = !instring; + else if (*s == '\n' && !instring) + { + end = s; + break; + } + ++s; + } + } #else argv = construct_command_argv (p, &end, child->file, child->file->cmds->lines_flags[child->command_line - 1], diff --git a/vmsjobs.c b/vmsjobs.c index 8109b5be..8fe50158 100644 --- a/vmsjobs.c +++ b/vmsjobs.c @@ -1,7 +1,7 @@ /* --------------- Moved here from job.c --------------- This file must be #included in job.c, as it accesses static functions. -Copyright (C) 1996-2013 Free Software Foundation, Inc. +Copyright (C) 1996-2014 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the @@ -431,36 +431,40 @@ child_execute_job (char *argv, struct child *child) else return 1; } - else if ((*(p) == 'r') - && (*(p+1) == 'm') - && ((*(p+2) == ' ') || (*(p+2) == '\t'))) + else if ((*(p) == 'e') + && (*(p+1) == 'c') + && (*(p+2) == 'h') + && (*(p+3) == 'o') + && ((*(p+4) == ' ') || (*(p+4) == '\t') || (*(p+4) == '\0'))) { - int in_arg; - - /* rm */ - p += 3; - while ((*p == ' ') || (*p == '\t')) - p++; - in_arg = 1; - - DB (DB_JOBS, (_("BUILTIN RM %s\n"), p)); - while (*p) + /* This is not a real builtin, it is a built in pre-processing + for the VMS/DCL echo (write sys$output) to ensure the to be echoed + string is correctly quoted (with the DCL quote character '"'). */ +#define VMS_EMPTY_ECHO "$ write sys$output \"\"" + char *vms_echo; + p += 4; + if (*p == '\0') { - switch (*p) - { - case ' ': - case '\t': - if (in_arg) - { - *p++ = ';'; - in_arg = 0; - } - break; - default: - break; - } - p++; + cmd = VMS_EMPTY_ECHO; } + else + { + p++; + while ((*p == ' ') || (*p == '\t')) + p++; + if (*p == '\0') + cmd = VMS_EMPTY_ECHO; + else + { + vms_echo = alloca(strlen(p) + sizeof VMS_EMPTY_ECHO); + strcpy(vms_echo, VMS_EMPTY_ECHO); + vms_echo[sizeof VMS_EMPTY_ECHO - 2] = '\0'; + strcat(vms_echo, p); + strcat(vms_echo, "\""); + cmd = vms_echo; + } + } + DB(DB_JOBS, (_("BUILTIN ECHO %s\n"), p)); } else {