(My apologies for mixing these two unrelated changes up.)
---
 lib/lib.c           |  9 +++++++
 lib/lib.h           |  1 +
 tests/diff.test     |  8 +++---
 toys/other/stat.c   |  6 +----
 toys/pending/diff.c | 66 ++++++++++++++++++++++++++++++---------------
 5 files changed, 60 insertions(+), 30 deletions(-)
From 7caed76e97b6a3167b24f65a6405faca90471611 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <e...@google.com>
Date: Thu, 28 Jun 2018 16:57:21 -0700
Subject: [PATCH] diff: add timestamps to the ---/+++ lines and --color.

(My apologies for mixing these two unrelated changes up.)
---
 lib/lib.c           |  9 +++++++
 lib/lib.h           |  1 +
 tests/diff.test     |  8 +++---
 toys/other/stat.c   |  6 +----
 toys/pending/diff.c | 66 ++++++++++++++++++++++++++++++---------------
 5 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/lib/lib.c b/lib/lib.c
index 77d8cc8..e69f12a 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -1386,3 +1386,12 @@ long long millitime(void)
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return ts.tv_sec*1000+ts.tv_nsec/1000000;
 }
+
+// Formats `ts` in ISO format ("2018-06-28 15:08:58.846386216 -0700").
+char *format_iso_time(char *buf, size_t len, struct timespec *ts)
+{
+  strftime(buf, len, "%F %T", localtime(&(ts->tv_sec)));
+  sprintf(buf+strlen(buf), ".%09ld ", ts->tv_nsec);
+  strftime(buf+strlen(buf), len-strlen(buf), "%z", localtime(&(ts->tv_sec)));
+  return buf;
+}
diff --git a/lib/lib.h b/lib/lib.h
index 353e262..61a33fa 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -250,6 +250,7 @@ char *getgroupname(gid_t gid);
 void do_lines(int fd, void (*call)(char **pline, long len));
 long environ_bytes();
 long long millitime(void);
+char *format_iso_time(char *buf, size_t len, struct timespec *ts);
 
 #define HR_SPACE 1 // Space between number and units
 #define HR_B     2 // Use "B" for single byte units
diff --git a/tests/diff.test b/tests/diff.test
index ca0b682..ce51f1e 100755
--- a/tests/diff.test
+++ b/tests/diff.test
@@ -5,8 +5,8 @@
 seq 10 > left
 seq 11 > right
 
-expected='--- left
-+++ right
+expected='--- lll
++++ rrr
 @@ -8,3 +8,4 @@
  8
  9
@@ -14,7 +14,7 @@ expected='--- left
 +11
 '
 # Hm this only gives unified diffs?
-testing "simple" "diff left right" "$expected" "" ""
+testing "simple" "diff -L lll -L rrr left right" "$expected" "" ""
 
 
 expected='--- tree1/file
@@ -27,4 +27,4 @@ mkdir -p tree1 tree2
 echo foo > tree1/file
 echo food > tree2/file
 
-testing "simple" "diff -r tree1 tree2 |tee out" "$expected" "" ""
+testing "simple" "diff -r -L tree1/file -L tree2/file tree1 tree2 |tee out" "$expected" "" ""
diff --git a/toys/other/stat.c b/toys/other/stat.c
index 9d64579..4fd1507 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -67,11 +67,7 @@ static void strout(char *val)
 
 static void date_stat_format(struct timespec *ts)
 {
-  char *s = toybuf+128;
-  strftime(s, sizeof(toybuf)-128, "%Y-%m-%d %H:%M:%S",
-    localtime(&(ts->tv_sec)));
-  sprintf(s+strlen(s), ".%09ld", ts->tv_nsec);
-  strout(s);
+  strout(format_iso_time(toybuf+128, sizeof(toybuf)-128, ts));
 }
 
 static void print_stat(char type)
diff --git a/toys/pending/diff.c b/toys/pending/diff.c
index b2177c4..2e0ff92 100644
--- a/toys/pending/diff.c
+++ b/toys/pending/diff.c
@@ -5,7 +5,7 @@
  *
  * See: http://cm.bell-labs.com/cm/cs/cstr/41.pdf
 
-USE_DIFF(NEWTOY(diff, "<2>2B(ignore-blank-lines)d(minimal)b(ignore-space-change)ut(expand-tabs)w(ignore-all-space)i(ignore-case)T(initial-tab)s(report-identical-files)q(brief)a(text)L(label)*S(starting-file):N(new-file)r(recursive)U(unified)#<0=3", TOYFLAG_USR|TOYFLAG_BIN))
+USE_DIFF(NEWTOY(diff, "<2>2(color)B(ignore-blank-lines)d(minimal)b(ignore-space-change)ut(expand-tabs)w(ignore-all-space)i(ignore-case)T(initial-tab)s(report-identical-files)q(brief)a(text)L(label)*S(starting-file):N(new-file)r(recursive)U(unified)#<0=3", TOYFLAG_USR|TOYFLAG_BIN))
 
 config DIFF
   bool "diff"
@@ -28,6 +28,8 @@ config DIFF
   -t  Expand tabs to spaces in output
   -U  Output LINES lines of context
   -w  Ignore all whitespace
+
+  --color  Colored output
 */
 
 #define FOR_diff
@@ -40,6 +42,7 @@ GLOBALS(
 
   int dir_num, size, is_binary, status, change, len[2];
   int *offset[2];
+  struct stat st[2];
 )
 
 #define MIN(x,y) ((x) < (y) ? (x) : (y))
@@ -416,6 +419,12 @@ static int *diff(char **files)
 static void print_diff(int a, int b, char c, int *off_set, FILE *fp)
 {
   int i, j, cc, cl;
+  char *reset = NULL;
+
+  if (c != ' ' && (toys.optflags & FLAG_color)) {
+    printf("\033[%dm", c == '+' ? 32 : 31);
+    reset = "\033[0m";
+  }
 
   for (i = a; i <= b; i++) {
     fseek(fp, off_set[i - 1], SEEK_SET);
@@ -424,7 +433,7 @@ static void print_diff(int a, int b, char c, int *off_set, FILE *fp)
     for (j = 0, cl = 0; j <  (off_set[i] - off_set[i - 1]); j++) {
       cc = fgetc(fp);
       if (cc == EOF) {
-        printf("\n\\ No newline at end of file\n");
+        printf("%s\n\\ No newline at end of file\n", reset ? reset : "");
         return;
       }
       if ((cc == '\t') && (toys.optflags & FLAG_t))
@@ -435,6 +444,7 @@ static void print_diff(int a, int b, char c, int *off_set, FILE *fp)
       }
     }
   }
+  if (reset) printf(reset);
 }
 
 static char *concat_file_path(char *path, char *default_path)
@@ -509,6 +519,14 @@ static int cmp(const void *p1, const void *p2)
    return strcmp(* (char * const *)p1, * (char * const *)p2);
 }
 
+static void show_label(char *prefix, char *filename, struct stat *sb)
+{
+  char date[36];
+
+  printf("%s %s\t%s\n", prefix, filename,
+    format_iso_time(date, sizeof(date), &sb->st_mtim));
+}
+
 static void do_diff(char **files)
 {
 
@@ -564,14 +582,16 @@ static void do_diff(char **files)
   TT.status = change; //update status, may change bcoz of -w etc.
 
   if (!(toys.optflags & FLAG_q) && change) {  //start of !FLAG_q
-
-      xprintf("--- %s\n", (toys.optflags & FLAG_L) ? llist->arg : files[0]);
-      if (((toys.optflags & FLAG_L) && !llist->next) || !(toys.optflags & FLAG_L))
-        xprintf("+++ %s\n", files[1]);
-      else {
-        while (llist->next) llist = llist->next;
-        xprintf("+++ %s\n", llist->arg);
-      }
+    if (toys.optflags & FLAG_color) printf("\033[1m");
+    if (toys.optflags & FLAG_L) printf("--- %s\n", llist->arg);
+    else show_label("---", files[0], &(TT).st[0]);
+    if (((toys.optflags & FLAG_L) && !llist->next) || !(toys.optflags & FLAG_L))
+      show_label("+++", files[1], &(TT).st[1]);
+    else {
+      while (llist->next) llist = llist->next;
+      printf("+++ %s\n", llist->arg);
+    }
+    if (toys.optflags & FLAG_color) printf("\033[0m");
 
     struct diff *t, *ptr1 = d, *ptr2 = d;
     while (i) {
@@ -606,6 +626,7 @@ calc_ct:
       start2 = MAX(1, ptr1->c - (ptr1->a - ptr1->suff));
       end2 = ptr2->prev - ptr2->b + ptr2->d;
 
+      if (toys.optflags & FLAG_color) printf("\033[36m");
       printf("@@ -%ld", start1 ? ptr1->suff: (ptr1->suff -1));
       if (end1 != -1) printf(",%ld ", ptr2->prev-ptr1->suff + 1);
       else putchar(' ');
@@ -613,7 +634,9 @@ calc_ct:
       printf("+%ld", (end2 - start2 + 1) ? start2: (start2 -1));
       if ((end2 - start2 +1) != 1) printf(",%ld ", (end2 - start2 +1));
       else putchar(' ');
-      printf("@@\n");
+      printf("@@");
+      if (toys.optflags & FLAG_color) printf("\033[0m");
+      putchar('\n');
 
       for (t = ptr1; t <= ptr2; t++) {
         if (t== ptr1) print_diff(t->suff, t->a-1, ' ', TT.offset[0], file[0].fp);
@@ -765,17 +788,18 @@ static void diff_dir(int *start)
 
 void diff_main(void)
 {
-  struct stat st[2];
   int j = 0, k = 1, start[2] = {1, 1};
   char *files[2];
 
+  if ((toys.optflags & FLAG_color) && !isatty(1)) toys.optflags ^= FLAG_color;
+
   for (j = 0; j < 2; j++) {
     files[j] = toys.optargs[j];
     if (IS_STDIN(files[j])) {
-      if (fstat(0, &st[j]) == -1)
+      if (fstat(0, &TT.st[j]) == -1)
         perror_exit("can fstat %s", files[j]);
     } else {
-      if (stat(files[j], &st[j]) == -1)
+      if (stat(files[j], &TT.st[j]) == -1)
         perror_exit("can't stat %s", files[j]);
     }
   }
@@ -786,16 +810,16 @@ void diff_main(void)
   }
 
   if ((IS_STDIN(files[0]) || IS_STDIN(files[1]))
-      && (S_ISDIR(st[0].st_mode) || S_ISDIR(st[1].st_mode)))
+      && (S_ISDIR(TT.st[0].st_mode) || S_ISDIR(TT.st[1].st_mode)))
     error_exit("can't compare stdin to directory");
 
-  if ((st[0].st_ino == st[1].st_ino) //physicaly same device
-      &&(st[0].st_dev == st[1].st_dev)) {
+  if ((TT.st[0].st_ino == TT.st[1].st_ino) //physicaly same device
+      && (TT.st[0].st_dev == TT.st[1].st_dev)) {
     show_status(files);
     return ;
   }
 
-  if (S_ISDIR(st[0].st_mode) && S_ISDIR(st[1].st_mode)) {
+  if (S_ISDIR(TT.st[0].st_mode) && S_ISDIR(TT.st[1].st_mode)) {
     for (j = 0; j < 2; j++) {
       memset(&dir[j], 0, sizeof(struct dir_t));
       dirtree_flagread(files[j], DIRTREE_SYMFOLLOW, list_dir);
@@ -820,12 +844,12 @@ void diff_main(void)
     free(dir[0].list); //free array
     free(dir[1].list);
   } else {
-    if (S_ISDIR(st[0].st_mode) || S_ISDIR(st[1].st_mode)) {
-      int d = S_ISDIR(st[0].st_mode);
+    if (S_ISDIR(TT.st[0].st_mode) || S_ISDIR(TT.st[1].st_mode)) {
+      int d = S_ISDIR(TT.st[0].st_mode);
       char *slash = strrchr(files[d], '/');
 
       files[1 - d] = concat_file_path(files[1 - d], slash ? slash + 1 : files[d]);
-      if ((stat(files[1 - d], &st[1 - d])) == -1)
+      if ((stat(files[1 - d], &TT.st[1 - d])) == -1)
         perror_exit("%s", files[1 - d]);
     }
     do_diff(files);
-- 
2.18.0.rc2.346.g013aa6912e-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to