1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 using System.Os;
  9 using paths;
 10 
 11 int main(int argcconst char** argv)
 12 {
 13     try
 14     {
 15         bool hasColors = IOCtl(1IOControlItem.hasColorsnull0) == 1;
 16         int screenWidth = IOCtl(1IOControlItem.columnsnull0);
 17         Fields additionalFields;
 18         SortField sortField = SortField.name;
 19         Flags flags = Flags.none;
 20         if (hasColors)
 21         {
 22             flags = cast<Flags>(flags | Flags.hasColors);
 23         }
 24         List<string> files;
 25         for (int i = 1; i < argc; ++i;)
 26         {
 27             string arg = argv[i];
 28             if (arg.StartsWith("--"))
 29             {
 30                 if (arg.Find('=') != -1)
 31                 {
 32                     List<string> components = arg.Split('=');
 33                     if (components.Count() == 2)
 34                     {
 35                         if (components[0] == "--sort")
 36                         {
 37                             if (components[1] == "inode")
 38                             {
 39                                 sortField = SortField.inode;
 40                             }
 41                             else if (components[1] == "nlinks")
 42                             {
 43                                 sortField = SortField.nlinks;
 44                             }
 45                             else if (components[1] == "user")
 46                             {
 47                                 sortField = SortField.user;
 48                             }
 49                             else if (components[1] == "size")
 50                             {
 51                                 sortField = SortField.size;
 52                             }
 53                             else if (components[1] == "time")
 54                             {
 55                                 sortField = SortField.time;
 56                             }
 57                             else
 58                             {
 59                                 throw Exception("unknown argument '" + arg + "'");
 60                             }
 61                         }
 62                         else
 63                         {
 64                             throw Exception("unknown argument '" + arg + "'");
 65                         }
 66                     }
 67                     else
 68                     {
 69                         throw Exception("unknown argument '" + arg + "'");
 70                     }
 71                 }
 72                 else if (arg == "--help")
 73                 {
 74                     PrintHelp();
 75                     return 1;
 76                 }
 77                 else if (arg == "--all")
 78                 {
 79                     flags = cast<Flags>(flags | Flags.all);
 80                 }
 81                 else if (arg == "--long")
 82                 {
 83                     flags = cast<Flags>(flags | Flags.longFormat);
 84                 }
 85                 else if (arg == "--human-readable")
 86                 {
 87                     flags = cast<Flags>(flags | Flags.humanReadableSize);
 88                 }
 89                 else if (arg == "--reverse")
 90                 {
 91                     flags = cast<Flags>(flags | Flags.reverse);
 92                 }
 93                 else if (arg == "--fs")
 94                 {
 95                     additionalFields = cast<Fields>(additionalFields | Fields.fs);
 96                 }
 97                 else if (arg == "--inode")
 98                 {
 99                     additionalFields = cast<Fields>(additionalFields | Fields.inode);
100                 }
101                 else if (arg == "--access")
102                 {
103                     additionalFields = cast<Fields>(additionalFields | Fields.access);
104                 }
105                 else if (arg == "--nlinks")
106                 {
107                     additionalFields = cast<Fields>(additionalFields | Fields.nlinks);
108                 }
109                 else if (arg == "--user")
110                 {
111                     additionalFields = cast<Fields>(additionalFields | Fields.user);
112                 }
113                 else if (arg == "--uid")
114                 {
115                     additionalFields = cast<Fields>(additionalFields | Fields.uid);
116                 }
117                 else if (arg == "--group")
118                 {
119                     additionalFields = cast<Fields>(additionalFields | Fields.group);
120                 }
121                 else if (arg == "--gid")
122                 {
123                     additionalFields = cast<Fields>(additionalFields | Fields.gid);
124                 }
125                 else if (arg == "--size")
126                 {
127                     additionalFields = cast<Fields>(additionalFields | Fields.size);
128                 }
129                 else if (arg == "--ctime")
130                 {
131                     additionalFields = cast<Fields>(additionalFields | Fields.ctime);
132                 }
133                 else if (arg == "--mtime")
134                 {
135                     additionalFields = cast<Fields>(additionalFields | Fields.mtime);
136                 }
137                 else if (arg == "--atime")
138                 {
139                     additionalFields = cast<Fields>(additionalFields | Fields.atime);
140                 }
141                 else
142                 {
143                     throw Exception("unknown argument '" + arg + "'");
144                 }
145             }
146             else if (arg.StartsWith("-"))
147             {
148                 string options = arg.Substring(1);
149                 if (options.IsEmpty())
150                 {
151                     throw Exception("unknown argument '" + arg + "'");
152                 }
153                 for (char o : options)
154                 {
155                     bool unknown = false;
156                     string uo;
157                     switch (o)
158                     {
159                         case 'h':
160                         {
161                             PrintHelp();
162                             return 1;
163                         }
164                         case 'a':
165                         {
166                             flags = cast<Flags>(flags | Flags.all);
167                             break;
168                         }
169                         case 'l':
170                         {
171                             flags = cast<Flags>(flags | Flags.longFormat);
172                             break;
173                         }
174                         case 'm':
175                         {
176                             flags = cast<Flags>(flags | Flags.humanReadableSize);
177                             break;
178                         }
179                         case 'r':
180                         {
181                             flags = cast<Flags>(flags | Flags.reverse);
182                             break;
183                         }
184                         case 'f':
185                         {
186                             additionalFields = cast<Fields>(additionalFields | Fields.fs);
187                             break;
188                         }
189                         case 'i':
190                         {
191                             additionalFields = cast<Fields>(additionalFields | Fields.inode);
192                             break;
193                         }
194                         case 'n':
195                         {
196                             additionalFields = cast<Fields>(additionalFields | Fields.nlinks);
197                             break;
198                         }
199                         case 's':
200                         {
201                             additionalFields = cast<Fields>(additionalFields | Fields.size);
202                             break;
203                         }
204                         case 'u':
205                         {
206                             additionalFields = cast<Fields>(additionalFields | Fields.user);
207                             break;
208                         }
209                         case 'g':
210                         {
211                             additionalFields = cast<Fields>(additionalFields | Fields.group);
212                             break;
213                         }
214                         case 'c':
215                         {
216                             additionalFields = cast<Fields>(additionalFields | Fields.ctime);
217                             break;
218                         }
219                         case 't':
220                         {
221                             additionalFields = cast<Fields>(additionalFields | Fields.mtime);
222                             break;
223                         }
224                         case 'e':
225                         {
226                             additionalFields = cast<Fields>(additionalFields | Fields.atime);
227                             break;
228                         }
229                         case 'I':
230                         {
231                             sortField = SortField.inode;
232                             break;
233                         }
234                         case 'N':
235                         {
236                             sortField = SortField.nlinks;
237                             break;
238                         }
239                         case 'U':
240                         {
241                             sortField = SortField.user;
242                             break;
243                         }
244                         case 'S':
245                         {
246                             sortField = SortField.size;
247                             break;
248                         }
249                         case 'T':
250                         {
251                             sortField = SortField.time;
252                             break;
253                         }
254                         default:
255                         {
256                             unknown = true;
257                             uo.Append(o);
258                             break;
259                         }
260                     }
261                     if (unknown)
262                     {
263                         throw Exception("unknown argument '-" + uo + "'");
264                     }
265                 }
266             }
267             else
268             {
269                 files.Add(arg);
270             }
271         }
272         if (files.IsEmpty())
273         {
274             files.Add(".");
275         }
276         if (!HasEnv("SHELL"))
277         {
278             files = Expand(files);
279         }
280         ListFiles(filessortFieldadditionalFieldsflagsscreenWidth);
281     }
282     catch (const Exception& ex)
283     {
284         Console.Error() << ex.ToString() << endl();
285         return 1;
286     }
287     return 0;
288 }