I listened to Jiří's suggestion and started with the outer layers of 
the system. This is more suitable for a beginner. As I don't know much 
about servers, I started with a simple modification of bdsh's cat and 
added an option for numbering all output lines. With this patch you can 
do 'cat -n textdemo textdemo' or 'cat --number textdemo textdemo'. This 
might be useful when bdsh gets scripting support.

Martin, thank you for a detailed explanation and review. I will have it 
in mind when I work on that task in the future, if my knowledge of the 
system gets to that level. And also Jakub's comment, as I managed 
to cause failed assertions in kernel code from userspace code, which
was strange to me, besides the fact that the solution was too easy, as 
Jiří noticed. 

Anyway I think I properly tested this patch with all the cat's options. 
So, here it is. 
=== modified file 'uspace/app/bdsh/cmds/modules/cat/cat.c'
--- uspace/app/bdsh/cmds/modules/cat/cat.c	2013-04-12 09:01:10 +0000
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	2013-07-17 21:10:24 +0000
@@ -62,6 +62,8 @@
 static sysarg_t console_rows = 0;
 static bool should_quit = false;
 static bool dash_represents_stdin = false;
+static unsigned int lineno = 0;
+static bool number = false;
 
 static console_ctrl_t *console = NULL;
 
@@ -74,6 +76,7 @@
 	{ "more", no_argument, 0, 'm' },
 	{ "hex", no_argument, 0, 'x' },
 	{ "stdin", no_argument, 0, 's' },
+	{ "number", no_argument, 0, 'n' },
 	{ 0, 0, 0, 0 }
 };
 
@@ -94,7 +97,8 @@
 		"  -b, --buffer ##  Set the read buffer size to ##\n"
 		"  -m, --more       Pause after each screen full\n"
 		"  -x, --hex        Print bytes as hex values\n"
-		"  -s  --stdin      Treat `-' in file list as standard input\n"
+		"  -s, --stdin      Treat `-' in file list as standard input\n"
+		"  -n, --number     Number all output lines\n"
 		"Currently, %s is under development, some options don't work.\n",
 		cmdname, cmdname);
 	}
@@ -153,6 +157,10 @@
 static void paged_char(wchar_t c)
 {
 	putchar(c);
+	if (c == '\n' && number == true) {
+		lineno++;
+		printf("%6u  ", lineno);
+	}
 	if (paging_enabled) {
 		chars_remaining--;
 		if (c == '\n' || chars_remaining == 0) {
@@ -169,7 +177,7 @@
 }
 
 static unsigned int cat_file(const char *fname, size_t blen, bool hex,
-    off64_t head, off64_t tail, bool tail_first)
+    off64_t head, off64_t tail, bool tail_first, bool first_file)
 {
 	int fd, bytes = 0, count = 0, reads = 0;
 	char *buff = NULL;
@@ -178,6 +186,7 @@
 	off64_t file_size = 0, length = 0;
 
 	bool reading_stdin = dash_represents_stdin && (str_cmp(fname, "-") == 0);
+	bool first_line = true;
 	
 	if (reading_stdin) {
 		fd = fileno(stdin);
@@ -239,6 +248,12 @@
 		if (bytes > 0) {
 			buff[bytes] = '\0';
 			offset = 0;
+
+			if (number && first_file && first_line) {
+				lineno++;
+				printf("%6u  ", lineno);
+				first_line = false;
+			}
 			for (i = 0; i < bytes && !should_quit; i++) {
 				if (hex) {
 					paged_char(hexchars[((uint8_t)buff[i])/16]);
@@ -293,6 +308,7 @@
 	bool tailFirst = false;
 	sysarg_t rows, cols;
 	int rc;
+	bool first_file = false;
 	
 	/*
 	 * reset global state
@@ -305,11 +321,13 @@
 	console_rows = 0;
 	should_quit = false;
 	console = console_init(stdin, stdout);
+	number = false;
+	lineno = 0;
 
 	argc = cli_count_args(argv);
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind);
+		c = getopt_long(argc, argv, "xhvmH:t:b:s:n", long_options, &opt_ind);
 		switch (c) {
 		case 'h':
 			help_cmd_cat(HELP_LONG);
@@ -346,6 +364,9 @@
 		case 's':
 			dash_represents_stdin = true;
 			break;
+		case 'n':
+			number = true;
+			break;
 		}
 	}
 
@@ -372,8 +393,20 @@
 		newpage();
 	}
 
-	for (i = optind; argv[i] != NULL && !should_quit; i++)
-		ret += cat_file(argv[i], buffer, hex, head, tail, tailFirst);
+	for (i = optind; argv[i] != NULL && !should_quit; i++) {
+		if (i == (unsigned int)optind)
+			first_file = true;
+		ret += cat_file(argv[i], buffer, hex, head, tail, tailFirst, first_file);
+		/* Count the line without the newline character. */
+		if (number && (argv[i+1] != NULL)) {
+			lineno++;
+			printf("\n%6u  ", lineno);
+		}
+		first_file = false; 
+	}
+
+	if (number)
+		putchar('\n');
 
 	if (ret)
 		return CMD_FAILURE;

_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/listinfo/helenos-devel

Reply via email to