changeset 1070:16167a7c1b5a

Fix -t c0 and -J as reported by heehooman at gmail on the list. Also fix up help text, and hook up -c.
author Rob Landley <rob@landley.net>
date Mon, 16 Sep 2013 23:41:51 -0500
parents 940dbcc1f8ed
children e7454bb7af5a
files lib/lib.c toys/posix/od.c
diffstat 2 files changed, 33 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Wed Sep 18 10:50:38 2013 -0500
+++ b/lib/lib.c	Mon Sep 16 23:41:51 2013 -0500
@@ -89,24 +89,31 @@
   return count;
 }
 
+// skip this many bytes of input. Return 0 for success, >0 means this much
+// left after input skipped.
 off_t lskip(int fd, off_t offset)
 {
-  off_t and = lseek(fd, offset, SEEK_CUR);
+  off_t cur = lseek(fd, 0, SEEK_CUR);
 
-  if (and != -1 && offset >= lseek(fd, offset, SEEK_END)
-    && offset+and == lseek(fd, offset+and, SEEK_SET)) return 0;
-  else {
-    while (offset>0) {
-      int try = offset>sizeof(libbuf) ? sizeof(libbuf) : offset, or;
+  if (cur != -1) {
+    off_t end = lseek(fd, 0, SEEK_END) - cur;
 
-      or = readall(fd, libbuf, try);
-      if (or < 0) perror_msg("lskip to %lld", (long long)offset);
-      else offset -= try;
-      if (or < try) break;
-    }
+    if (end > 0 && end < offset) return offset - end;
+    end = offset+cur;
+    if (end == lseek(fd, end, SEEK_SET)) return 0;
+    perror_exit("lseek");
+  }
 
-    return offset;
+  while (offset>0) {
+    int try = offset>sizeof(libbuf) ? sizeof(libbuf) : offset, or;
+
+    or = readall(fd, libbuf, try);
+    if (or < 0) perror_exit("lskip to %lld", (long long)offset);
+    else offset -= try;
+    if (or < try) break;
   }
+
+  return offset;
 }
 
 // Split a path into linked list of components, tracking head and tail of list.
--- a/toys/posix/od.c	Wed Sep 18 10:50:38 2013 -0500
+++ b/toys/posix/od.c	Mon Sep 16 23:41:51 2013 -0500
@@ -11,10 +11,15 @@
   bool "od"
   default y
   help
-    usage: od [-bdosxv] [-j #] [-N #] [-A doxn] [-t arg]
+    usage: od [-bcdosxv] [-j #] [-N #] [-A doxn] [-t acdfoux[#]]
 
     -A	Address base (decimal, octal, hexdecimal, none)
-    -t	output type(s) a (ascii) c (char) d (decimal) foux
+    -j	Skip this many bytes of input
+    -N	Stop dumping after this many bytes
+    -t	output type a(scii) c(har) d(ecimal) f(loat) o(ctal) u(nsigned) (he)x
+    	plus optional size in bytes
+    	aliases: -b=-t o1, -c=-t c, -d=-t u2, -o=-t o2, -s=-t d2, -x=-t x2
+    -v	Don't collapse repeated lines together
 */
 
 #define FOR_od
@@ -164,10 +169,11 @@
 static void do_od(int fd, char *name)
 {
   // Skip input, possibly more than one entire file.
-  if (TT.jump_bytes < TT.pos) {
-    off_t off = lskip(fd, TT.jump_bytes);
-    if (off > 0) TT.pos += off;
-    if (TT.jump_bytes < TT.pos) return;
+  if (TT.jump_bytes > TT.pos) {
+    off_t pos = TT.jump_bytes-TT.pos, off = lskip(fd, pos);
+
+    if (off >= 0) TT.pos += pos-off;
+    if (TT.jump_bytes > TT.pos) return;
   }
 
   for(;;) {
@@ -209,7 +215,7 @@
       size = strtol(s, &s, 10);
       if (type < 2 && size != 1) break;
       if (CFG_TOYBOX_FLOAT && type == 6 && size == sizeof(long double));
-      else if (size < 0 || size > 8) break;
+      else if (size < 1 || size > 8) break;
     } else if (CFG_TOYBOX_FLOAT && type == 6) {
       int sizes[] = {sizeof(float), sizeof(double), sizeof(long double)};
       if (-1 == (size = stridx("FDL", *s))) size = sizeof(double);
@@ -247,6 +253,7 @@
 
   for (arg = TT.output_base; arg; arg = arg->next) append_base(arg->arg);
   if (toys.optflags & FLAG_b) append_base("o1");
+  if (toys.optflags & FLAG_c) append_base("c");
   if (toys.optflags & FLAG_d) append_base("u2");
   if (toys.optflags & FLAG_o) append_base("o2");
   if (toys.optflags & FLAG_s) append_base("d2");