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.IO;
  9 using System.Os;
 10 
 11 void PrintHelp()
 12 {
 13     Console.WriteLine("Usage: head [options] [FILE]...");
 14     Console.WriteLine("Print first 10 lines of each file to standard output.");
 15     Console.WriteLine("Options:");
 16     Console.WriteLine("--help | -h");
 17     Console.WriteLine("  Print help and exit.");
 18     Console.WriteLine("--lines=[-]NUM | -n=[-]NUM");
 19     Console.WriteLine("  Print first NUM lines instead of first 10;");
 20     Console.WriteLine("  with the leading '-' print all but the last NUM lines.");
 21 }
 22 
 23 void PrintHead(const List<string>& filesint lineCount)
 24 {
 25     for (const string& file : files)
 26     {
 27         StreamReader reader(SharedPtr<Stream>());
 28         if (!file.IsEmpty())
 29         {
 30             reader = File.OpenRead(file);
 31         }
 32         else
 33         {
 34             if (IsConsole(0))
 35             {
 36                 reader = StreamReader(SharedPtr<Stream>(new FileStream(0)));
 37             }
 38             else
 39             {
 40                 reader = StreamReader(SharedPtr<Stream>(new BufferedStream(SharedPtr<Stream>(new FileStream(0)))));
 41             }
 42         }
 43         if (lineCount >= 0)
 44         {
 45             for (int i = 0; i < lineCount; ++i;)
 46             {
 47                 if (reader.EndOfStream()) break;
 48                 string line = reader.ReadLine();
 49                 Console.WriteLine(line);
 50             }
 51         }
 52         else
 53         {
 54             List<string> lines;
 55             while (!reader.EndOfStream())
 56             {
 57                 string line = reader.ReadLine();
 58                 lines.Add(line);
 59             }
 60             int n = cast<int>(lines.Count()) + lineCount;
 61             for (int i = 0; i < n; ++i;)
 62             {
 63                 Console.WriteLine(lines[i]);
 64             }
 65         }
 66     }
 67 }
 68 
 69 int main(int argcconst char** argv)
 70 {
 71     try
 72     {
 73         int lineCount = 10;
 74         List<string> files;
 75         for (int i = 1; i < argc; ++i;)
 76         {
 77             string arg = argv[i];
 78             if (arg.StartsWith("--"))
 79             {
 80                 if (arg == "--help")
 81                 {
 82                     PrintHelp();
 83                     return 1;
 84                 }
 85                 else if (arg.Find('=') != -1)
 86                 {
 87                     List<string> components = arg.Split('=');
 88                     if (components.Count() == 2)
 89                     {
 90                         if (components[0] == "--lines")
 91                         {
 92                             lineCount = ParseInt(components[1]);
 93                         }
 94                         else
 95                         {
 96                             throw Exception("unknown option '" + arg + "'");
 97                         }
 98                     }
 99                     else
100                     {
101                         throw Exception("unknown option '" + arg + "'");
102                     }
103                 }
104                 else
105                 {
106                     throw Exception("unknown option '" + arg + "'");
107                 }
108             }
109             else if (arg.StartsWith("-"))
110             {
111                 if (arg.Find('=') != -1)
112                 {
113                     List<string> components = arg.Split('=');
114                     if (components.Count() == 2)
115                     {
116                         if (components[0] == "-n")
117                         {
118                             lineCount = ParseInt(components[1]);
119                         }
120                         else
121                         {
122                             throw Exception("unknown option '" + arg + "'");
123                         }
124                     }
125                     else
126                     {
127                         throw Exception("unknown option '" + arg + "'");
128                     }
129                 }
130                 else
131                 {
132                     string options = arg.Substring(1);
133                     for (char o : options)
134                     {
135                         string uo;
136                         bool unknown = false;
137                         switch (o)
138                         {
139                             case 'h':
140                             {
141                                 PrintHelp();
142                                 return 1;
143                             }
144                             default:
145                             {
146                                 uo.Append(o);
147                                 unknown = true;
148                                 break;
149                             }
150                         }
151                         if (unknown)
152                         {
153                             throw Exception("unknown option '-" + uo + "'");
154                         }
155                     }
156                 }
157             }
158             else
159             {
160                 files.Add(arg);
161             }
162         }
163         if (files.IsEmpty())
164         {
165             files.Add(string());
166         }
167         PrintHead(fileslineCount);
168     }
169     catch (const Exception& ex)
170     {
171         Console.Error() << ex.ToString() << endl();
172         return 1;
173     }
174     return 0;
175 }