| 1 | /* $Id: echo.c 3192 2018-03-26 20:25:56Z bird $ */ | 
|---|
| 2 | /** @file | 
|---|
| 3 | * kMk Builtin command - echo | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | /* | 
|---|
| 7 | * Copyright (c) 2018 knut st. osmundsen <bird-kBuild-spamx@anduin.net> | 
|---|
| 8 | * | 
|---|
| 9 | * This file is part of kBuild. | 
|---|
| 10 | * | 
|---|
| 11 | * kBuild is free software; you can redistribute it and/or modify | 
|---|
| 12 | * it under the terms of the GNU General Public License as published by | 
|---|
| 13 | * the Free Software Foundation; either version 3 of the License, or | 
|---|
| 14 | * (at your option) any later version. | 
|---|
| 15 | * | 
|---|
| 16 | * kBuild is distributed in the hope that it will be useful, | 
|---|
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 19 | * GNU General Public License for more details. | 
|---|
| 20 | * | 
|---|
| 21 | * You should have received a copy of the GNU General Public License | 
|---|
| 22 | * along with kBuild.  If not, see <http://www.gnu.org/licenses/> | 
|---|
| 23 | * | 
|---|
| 24 | */ | 
|---|
| 25 |  | 
|---|
| 26 |  | 
|---|
| 27 | /********************************************************************************************************************************* | 
|---|
| 28 | *   Header Files                                                                                                                 * | 
|---|
| 29 | *********************************************************************************************************************************/ | 
|---|
| 30 | #include "config.h" | 
|---|
| 31 |  | 
|---|
| 32 | #include <string.h> | 
|---|
| 33 | #include <stdlib.h> | 
|---|
| 34 | #include <stdio.h> | 
|---|
| 35 | #ifdef HAVE_UNISTD_H | 
|---|
| 36 | # include <unistd.h> | 
|---|
| 37 | #endif | 
|---|
| 38 | #ifdef _MSC_VER | 
|---|
| 39 | # include <io.h> | 
|---|
| 40 | #endif | 
|---|
| 41 |  | 
|---|
| 42 | #include "kmkbuiltin.h" | 
|---|
| 43 | #include "err.h" | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 | int kmk_builtin_echo(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) | 
|---|
| 47 | { | 
|---|
| 48 | int     rcExit = 0; | 
|---|
| 49 | int     iFirst = 1; | 
|---|
| 50 | int     i; | 
|---|
| 51 | char   *pszBuf; | 
|---|
| 52 | size_t  cbBuf; | 
|---|
| 53 |  | 
|---|
| 54 | /* | 
|---|
| 55 | * Check for the -n option. | 
|---|
| 56 | */ | 
|---|
| 57 | int fNoNewLine = 0; | 
|---|
| 58 | if (   argc > iFirst | 
|---|
| 59 | && strcmp(argv[iFirst], "-n") == 0) | 
|---|
| 60 | { | 
|---|
| 61 | iFirst++; | 
|---|
| 62 | fNoNewLine = 1; | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | /* | 
|---|
| 66 | * Calc buffer size and allocate it. | 
|---|
| 67 | */ | 
|---|
| 68 | cbBuf = 1 + 1; | 
|---|
| 69 | for (i = 1; i < argc; i++) | 
|---|
| 70 | cbBuf += (i > iFirst) + strlen(argv[i]); | 
|---|
| 71 | pszBuf = (char *)malloc(cbBuf); | 
|---|
| 72 | if (pszBuf) | 
|---|
| 73 | { | 
|---|
| 74 | /* | 
|---|
| 75 | * Assembler the output into the buffer. | 
|---|
| 76 | */ | 
|---|
| 77 | char *pszDst = pszBuf; | 
|---|
| 78 | for (i = iFirst; i < argc; i++) | 
|---|
| 79 | { | 
|---|
| 80 | const char *pszArg = argv[i]; | 
|---|
| 81 | size_t      cchArg = strlen(pszArg); | 
|---|
| 82 |  | 
|---|
| 83 | /* Check for "\c" in final argument (same as -n). */ | 
|---|
| 84 | if (i + 1 >= argc | 
|---|
| 85 | && cchArg >= 2 | 
|---|
| 86 | && pszArg[cchArg - 2] == '\\' | 
|---|
| 87 | && pszArg[cchArg - 1] == 'c') | 
|---|
| 88 | { | 
|---|
| 89 | fNoNewLine = 1; | 
|---|
| 90 | cchArg -= 2; | 
|---|
| 91 | } | 
|---|
| 92 | if (i > iFirst) | 
|---|
| 93 | *pszDst++ = ' '; | 
|---|
| 94 | memcpy(pszDst, pszArg, cchArg); | 
|---|
| 95 | pszDst += cchArg; | 
|---|
| 96 | } | 
|---|
| 97 | if (!fNoNewLine) | 
|---|
| 98 | *pszDst++ = '\n'; | 
|---|
| 99 | *pszDst = '\0'; | 
|---|
| 100 |  | 
|---|
| 101 | /* | 
|---|
| 102 | * Push it out. | 
|---|
| 103 | */ | 
|---|
| 104 | #ifndef KMK_BUILTIN_STANDALONE | 
|---|
| 105 | if (output_write_text(pCtx->pOut, 0, pszBuf, pszDst - pszBuf) == -1) | 
|---|
| 106 | rcExit = err(pCtx, 1, "output_write_text"); | 
|---|
| 107 | #else | 
|---|
| 108 | if (write(STDOUT_FILENO, pszBuf, pszDst - pszBuf) == -1) | 
|---|
| 109 | rcExit = err(pCtx, 1, "write"); | 
|---|
| 110 | #endif | 
|---|
| 111 | free(pszBuf); | 
|---|
| 112 | } | 
|---|
| 113 | else | 
|---|
| 114 | rcExit = err(pCtx, 1, "malloc(%lu)", (unsigned long)cbBuf); | 
|---|
| 115 | return rcExit; | 
|---|
| 116 | } | 
|---|
| 117 |  | 
|---|
| 118 | #ifdef KMK_BUILTIN_STANDALONE | 
|---|
| 119 | int main(int argc, char **argv, char **envp) | 
|---|
| 120 | { | 
|---|
| 121 | KMKBUILTINCTX Ctx = { "kmk_echo", NULL }; | 
|---|
| 122 | return kmk_builtin_echo(argc, argv, envp, &Ctx); | 
|---|
| 123 | } | 
|---|
| 124 | #endif | 
|---|
| 125 |  | 
|---|