aboutsummaryrefslogtreecommitdiffstats
path: root/builtins/echo.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/echo.c')
-rw-r--r--builtins/echo.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/builtins/echo.c b/builtins/echo.c
new file mode 100644
index 0000000..442ca41
--- /dev/null
+++ b/builtins/echo.c
@@ -0,0 +1,135 @@
+/* echo.c, created from echo.def. */
+#line 22 "./echo.def"
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "../bashansi.h"
+
+#include <stdio.h>
+#include "../shell.h"
+
+#include "common.h"
+
+#line 67 "./echo.def"
+
+#line 82 "./echo.def"
+
+#if defined (V9_ECHO)
+# define VALID_ECHO_OPTIONS "neE"
+#else /* !V9_ECHO */
+# define VALID_ECHO_OPTIONS "n"
+#endif /* !V9_ECHO */
+
+/* System V machines already have a /bin/sh with a v9 behaviour. We
+ give Bash the identical behaviour for these machines so that the
+ existing system shells won't barf. Regrettably, the SUS v2 has
+ standardized the Sys V echo behavior. This variable is external
+ so that we can have a `shopt' variable to control it at runtime. */
+#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
+int xpg_echo = 1;
+#else
+int xpg_echo = 0;
+#endif /* DEFAULT_ECHO_TO_XPG */
+
+extern int posixly_correct;
+
+/* Print the words in LIST to standard output. If the first word is
+ `-n', then don't print a trailing newline. We also support the
+ echo syntax from Version 9 Unix systems. */
+int
+echo_builtin (list)
+ WORD_LIST *list;
+{
+ int display_return, do_v9, i, len;
+ char *temp, *s;
+
+ do_v9 = xpg_echo;
+ display_return = 1;
+
+ if (posixly_correct && xpg_echo)
+ goto just_echo;
+
+ for (; list && (temp = list->word->word) && *temp == '-'; list = list->next)
+ {
+ /* If it appears that we are handling options, then make sure that
+ all of the options specified are actually valid. Otherwise, the
+ string should just be echoed. */
+ temp++;
+
+ for (i = 0; temp[i]; i++)
+ {
+ if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
+ break;
+ }
+
+ /* echo - and echo -<nonopt> both mean to just echo the arguments. */
+ if (*temp == 0 || temp[i])
+ break;
+
+ /* All of the options in TEMP are valid options to ECHO.
+ Handle them. */
+ while (i = *temp++)
+ {
+ switch (i)
+ {
+ case 'n':
+ display_return = 0;
+ break;
+#if defined (V9_ECHO)
+ case 'e':
+ do_v9 = 1;
+ break;
+ case 'E':
+ do_v9 = 0;
+ break;
+#endif /* V9_ECHO */
+ default:
+ goto just_echo; /* XXX */
+ }
+ }
+ }
+
+just_echo:
+
+ clearerr (stdout); /* clear error before writing and testing success */
+
+ terminate_immediately++;
+ while (list)
+ {
+ i = len = 0;
+ temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), 1, &i, &len)
+ : list->word->word;
+ if (temp)
+ {
+ if (do_v9)
+ {
+ for (s = temp; len > 0; len--)
+ putchar (*s++);
+ }
+ else
+ printf ("%s", temp);
+#if defined (SunOS5)
+ fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */
+#endif
+ }
+ if (do_v9 && temp)
+ free (temp);
+ list = list->next;
+ if (i)
+ {
+ display_return = 0;
+ break;
+ }
+ if (list)
+ putchar(' ');
+ }
+
+ if (display_return)
+ putchar ('\n');
+
+ terminate_immediately--;
+ return (sh_chkwrite (EXECUTION_SUCCESS));
+}