echo: corrected usage of getopt
[meinos.git] / apps / utils / echo.c
blobd18eab4aa1988a4a24eba9f06375d651a9b0f6d3
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <stddef.h>
25 void usage(char *prog,int ret) {
26 FILE *stream = stdout;//ret==0?stdout:stderr;
27 fprintf(stream,"Usage: %s [OPTION]... [STRING]...\n");
28 fprintf(stream,"Echo the STRING(s) to standard output\n");
29 fprintf(stream,"\t-n\tdo not output the trailing newline\n");
30 fprintf(stream,"\t-e\tenable interpretation of backslash escapes\n");
31 fprintf(stream,"\t-E\tdisable interpretation of backslash escapes (default)\n");
32 fprintf(stream,"\t-h\tdisplay this help and exit\n");
33 fprintf(stream,"\t-v\toutput version information and exit\n");
36 int octal2num(char *str) {
37 char buf[4];
38 memcpy(buf,str,3);
39 buf[3] = 0;
40 int num = strtoul(buf,NULL,8);
41 return num;
44 char *escape_string(char *str,int *newline) {
45 char *new = malloc(strlen(str)+1);
46 size_t i,j;
47 for (i=0,j=0;str[i];i++,j++) {
48 if (str[i]=='\\' && str[i+1]!=0) { // escape code
49 i++;
50 if (str[i]=='\\') new[j] = '\\'; // backslash
51 else if (str[i]=='a') new[j] = '\a'; // alert
52 else if (str[i]=='b') new[j] = '\b'; // backspace
53 else if (str[i]=='c') *newline = 0; // supress trailing newline
54 else if (str[i]=='f') new[j] = '\f'; // form feed
55 else if (str[i]=='n') new[j] = '\n'; // new line
56 else if (str[i]=='r') new[j] = '\r'; // carriage return
57 else if (str[i]=='t') new[j] = '\t'; // horizontal tab
58 else if (str[i]=='v') new[j] = '\v'; // vertical tab
59 else if (str[i]=='0' && str[i+1]!=0 && str[i+2]!=0 && str[i+3]!=0) {
60 // character in octal
61 new[j] = octal2num(str+i+1);
64 else new[j] = str[i];
66 return new;
69 int main(int argc,char *argv[]) {
70 int c;
71 int newline = 1;
72 int escape = 0;
74 while ((c = getopt(argc,argv,":neEhv"))!=-1) {
75 switch(c) {
76 case 'n':
77 newline = 0;
78 break;
79 case 'e':
80 escape = 1;
81 break;
82 case 'E':
83 escape = 0;
84 break;
85 case 'h':
86 usage(argv[0],0);
87 break;
88 case 'v':
89 printf("echo v0.1\n(c) 2008 Janosch Graef\n");
90 return 0;
91 break;
92 case '?':
93 fprintf(stderr,"Unrecognized option: -%c\n", optopt);
94 usage(argv[0],1);
95 break;
99 for (c=optind;c<argc;c++) {
100 char *string;
101 if (escape) string = escape_string(argv[c],&newline);
102 else string = argv[c];
104 printf("%s",string);
105 if (c<argc-1) putchar(' ');
107 if (escape) free(string);
110 if (newline) putchar('\n');
112 return 0;