1/* 2 * print -- loadable ksh-93 style print builtin 3 */ 4 5#ifdef HAVE_CONFIG_H 6# include <config.h> 7#endif 8 9#include "bashtypes.h" 10 11#include <errno.h> 12#include <limits.h> 13#include <stdio.h> 14 15#include "bashansi.h" 16#include "shell.h" 17#include "builtins.h" 18#include "stdc.h" 19#include "bashgetopt.h" 20 21#if !defined (errno) 22extern int errno; 23#endif 24 25int print_builtin (); 26static int printargs (); 27 28static FILE *ofp; 29 30extern char *this_command_name; 31 32static char *print_doc[] = { 33 "Output the arguments. The -f option means to use the argument as a", 34 "format string as would be supplied to printf(1). The rest of the", 35 "options are as in ksh.", 36 (char *)NULL 37}; 38 39struct builtin print_struct = { 40 "print", 41 print_builtin, 42 BUILTIN_ENABLED, 43 print_doc, 44 "print [-Rnprs] [-u unit] [-f format] [arguments]", 45 (char *)0 46}; 47 48#ifndef ISOPTION 49#define ISOPTION(s, c) (s[0] == '-' && s[2] == '\0' && s[1] == c) 50#endif 51 52int 53print_builtin (list) 54 WORD_LIST *list; 55{ 56 int c, r, nflag, raw, ofd, sflag; 57 intmax_t lfd; 58 char **v, *pfmt, *arg; 59 WORD_LIST *l; 60 61 nflag = raw = sflag = 0; 62 ofd = 1; 63 pfmt = 0; 64 65 reset_internal_getopt (); 66 while ((c = internal_getopt (list, "Rnprsu:f:")) != -1) 67 { 68 switch (c) 69 { 70 case 'R': 71 raw = 2; 72 loptend = lcurrent; 73 if (loptend && ISOPTION (loptend->word->word, 'n')) 74 { 75 loptend = loptend->next; 76 nflag = 1; 77 } 78 goto opt_end; 79 case 'r': 80 raw = 1; 81 break; 82 case 'n': 83 nflag = 1; 84 break; 85 case 's': 86 sflag = 1; 87 break; 88 case 'p': 89 break; /* NOP */ 90 case 'u': 91 if (all_digits (list_optarg) && legal_number (list_optarg, &lfd) && lfd == (int)lfd) 92 ofd = lfd; 93 else 94 { 95 for (l = list; l->next && l->next != lcurrent; l = l->next); 96 lcurrent = loptend = l; 97 goto opt_end; 98 } 99 break; 100 case 'f': 101 pfmt = list_optarg; 102 break; 103 default: 104 builtin_usage (); 105 return (EX_USAGE); 106 } 107 } 108 109opt_end: 110 list = loptend; 111 112 ofp = (ofd == 1) ? stdout : fdopen (dup (ofd), "w"); 113 114 if (pfmt) 115 { 116 WORD_DESC *w; 117 WORD_LIST *nlist; 118 119 w = make_word (pfmt); 120 nlist = make_word_list (w, list); 121 r = printf_builtin (nlist); 122 nlist->next = (WORD_LIST *)NULL; 123 dispose_words (nlist); 124 return (r); 125 } 126 127 if (raw) 128 { 129 for (l = list; l; l = l->next) 130 { 131 fprintf (ofp, "%s", l->word->word); 132 if (l->next) 133 fprintf (ofp, " "); 134 } 135 if (nflag == 0) 136 fprintf (ofp, "\n"); 137 fflush (ofp); 138 return (0); 139 } 140 141 r = printargs (list, ofp); 142 if (r && nflag == 0) 143 fprintf (ofp, "\n"); 144 if (ofd != 1) 145 fclose (ofp); 146 return 0; 147} 148 149static int 150printargs (list, ofp) 151 WORD_LIST *list; 152 FILE *ofp; 153{ 154 WORD_LIST *l; 155 char *ostr; 156 int sawc; 157 158 for (sawc = 0, l = list; l; l = l->next) 159 { 160 ostr = ansicstr (l->word->word, strlen (l->word->word), 0, &sawc, (int *)0); 161 fprintf (ofp, "%s", ostr); 162 free (ostr); 163 if (sawc) 164 return (0); 165 if (l->next) 166 fprintf (ofp, " "); 167 } 168 return (1); 169} 170