blob: d5c606569e763e43902b14912bf119e05dda197f [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ 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 Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18#include <ucommon/ucommon.h>
19
20using namespace UCOMMON_NAMESPACE;
21
22static shell::flagopt helpflag('h',"--help", _TEXT("display this list"));
23static shell::flagopt althelp('?', NULL, NULL);
24static shell::charopt delim('d', "--delim", _TEXT("set deliminter between arguments"));
25static shell::flagopt directory('D', "--directory", _TEXT("expand directory into file arguments"));
26static shell::flagopt lines('l', "--lines", _TEXT("list arguments on separate lines"));
27static shell::stringopt quote('q', "--quote", _TEXT("set quote for each argument"), "string", "");
28static shell::flagopt recursive('R', "--recursive", _TEXT("recursive directory scan"));
29static shell::flagopt follow('F', "--follow", _TEXT("follow symlinks"));
30static shell::flagopt rflag('r', "--reverse", _TEXT("reverse order of arguments"));
31
32static char prefix[80] = {0, 0};
33static char suffix[80] = {0, 0};
34
35static void output(bool middle, const char *arg)
36{
37 if(is(lines))
38 file::cout << prefix << arg << suffix << "\n";
39 else if(middle)
40 file::cout << *delim << prefix << arg << suffix;
41 else
42 file::cout << prefix << arg << suffix;
43}
44
45static void dirpath(bool middle, String path, bool top = true)
46{
47 char filename[128];
48 string_t subdir;
49 dir_t dir(path);
50 unsigned count = 0;
51
52 while(is(dir) && dir.read(filename, sizeof(filename))) {
53 if(*filename == '.')
54 continue;
55
56 ++count;
57 subdir = (String)path + (String)"/" + (String)filename;
58 output(middle, subdir);
59 middle = true;
60
61 if(fsys::is_dir(*subdir)) {
62 if(is(follow) || is(recursive)) {
63 if(!fsys::is_link(*subdir) || is(follow))
64 dirpath(true, subdir, false);
65 }
66 }
67 }
68 if(top && !count)
69 output(middle, path);
70}
71
72PROGRAM_MAIN(argc, argv)
73{
74 unsigned count = 0;
75 char *ep;
76 bool middle = false;
77
78 shell::bind("args");
79 shell args(argc, argv);
80
81 if(is(helpflag) || is(althelp)) {
82 printf("%s\n", _TEXT("Usage: args [options] arguments..."));
83 printf("%s\n\n", _TEXT("Echo command line arguments"));
84 printf("%s\n", _TEXT("Options:"));
85 shell::help();
86 printf("\n%s\n", _TEXT("Report bugs to dyfet@gnu.org"));
87 PROGRAM_EXIT(0);
88 }
89
90 if(!args())
91 PROGRAM_EXIT(0);
92
93 if(quote[0]) {
94 if(!quote[1]) {
95 prefix[0] = quote[0];
96 suffix[0] = quote[0];
97 }
98 else if(!quote[2]) {
99 prefix[0] = quote[0];
100 suffix[0] = quote[1];
101 }
102 else if(quote[0] == '<') {
103 String::set(prefix, sizeof(prefix), *quote);
104 snprintf(suffix, sizeof(suffix), "</%s", *quote + 1);
105 }
106 else if(quote[0] == '(') {
107 String::set(prefix, sizeof(prefix), quote);
108 ep = strchr((char *)*quote, ')');
109 if(ep)
110 *ep = 0;
111 suffix[0] = ')';
112 }
113 else {
114 String::set(prefix, sizeof(prefix), quote);
115 String::set(suffix, sizeof(suffix), quote);
116 }
117 }
118
119 if(is(rflag)) {
120 count = args();
121 while(count--) {
122 if(fsys::is_dir(args[count]) && (is(directory) || is(recursive) || is(follow)))
123 dirpath(middle, (String)args[count]);
124 else
125 output(middle, args[count]);
126 middle = true;
127 }
128 }
129 else while(count < args()) {
130 if(fsys::is_dir(args[count]) && (is(directory) || is(recursive) || is(follow)))
131 dirpath(middle, (String)args[count++]);
132 else
133 output(middle, (String)args[count++]);
134 middle = true;
135 }
136
137 if(!lines)
138 file::cout << "\n";
139
140 PROGRAM_EXIT(0);
141}
142