aboutsummaryrefslogtreecommitdiff
path: root/src/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output.c')
-rw-r--r--src/output.c135
1 files changed, 122 insertions, 13 deletions
diff --git a/src/output.c b/src/output.c
index 45f04a6..3cf68af 100644
--- a/src/output.c
+++ b/src/output.c
@@ -5,6 +5,7 @@
* vim:ts=4:sw=4:expandtab
*/
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
@@ -27,7 +28,13 @@
#define DM_OUT_FORMAT_MAX_LEN 80
-#define out_vsep fputc('|', stdout)
+#define box_cross '+'
+#define box_hsep '-'
+#define box_vsep '|'
+
+#define out_cross() fputc(box_cross, stdout)
+#define out_hsep() fputc(box_hsep, stdout)
+#define out_vsep() fputc(box_vsep, stdout)
#define out_print_newline() fputc('\n', stdout)
#define out_print_fname(x) printf(" %s ", x->fname)
@@ -42,7 +49,12 @@ void out_print_time_by_option(struct list_node *ptr);
void out_print_type(struct list_node *ptr);
void out_print_user_name(struct list_node *ptr);
-void out_print_format_string_header(const char *format);
+void out_print_format_string_header(const char *format, size_t longest_fname);
+
+size_t get_longest_filename(struct list_head *list);
+
+
+char *global_sep_line = NULL;
/* === IMPLEMENTATION === */
@@ -85,6 +97,19 @@ inline int fputc_width_x(char c, size_t x, FILE *fdout) {
return 1;
}
+/* basic 4 due to formatted output */
+inline size_t get_longest_filename(struct list_head *list) {
+ size_t rc = 4, tmp = 0;
+ struct list_node *ptr = NULL;
+ if (list == NULL) { return 0; }
+ ptr = list->first;
+ while (ptr != NULL) {
+ tmp = strlen(ptr->fname);
+ if (tmp>rc) { rc = tmp; }
+ ptr = ptr->next;
+ }
+ return rc;
+}
/* === FORMATTING RELATED FUNCTIONS === */
@@ -289,24 +314,44 @@ inline void out_print_permissions(struct list_node *ptr) {
printf(" %4o ", mode);
}
-inline void out_print_format_string_header(const char *format) {
- size_t i=0, format_len=0;
- char header[4096] = "";
+inline void out_print_format_string_header(const char *format, size_t longest_fname) {
+ size_t i=0, j=0, k=0, format_len=0, tmp = 0;
+ char header[4096] = "", sep_line[4096] = "";
char *pos = header;
- if (format == NULL) return;
+ if (format == NULL || longest_fname == 0) return;
DBGTRC("DEBUG: format string: \"%s\"\n", format);
format_len = strnlen(format, DM_OUT_FORMAT_MAX_LEN);
+
+ if (option_print_boxed_table) {
+ if (global_sep_line != NULL) { free(global_sep_line); }
+ pos[0] = box_vsep;
+ pos++;
+ sep_line[j++] = box_cross;
+ }
+
+#define LOCAL_EXTEND_SEP_LINE() { \
+ if (option_print_boxed_table) { \
+ tmp = strlen(pos); \
+ for (k=0; k<tmp; k++) { sep_line[j++] = box_hsep; } \
+ sep_line[j++] = box_cross; pos[tmp] = box_vsep; } }
+
/* Prevent buffer overflow, with the header string 32 byte buffer */
for (i=0; (i < format_len) && (strlen(header) < 4064); i++) {
switch (format[i]) {
case 'n':
sprintf(pos, " FILE ");
+ tmp = strlen(pos);
+ for (k=0; k<longest_fname-4; k++) {
+ pos[tmp+k] = ' ';
+ }
+ LOCAL_EXTEND_SEP_LINE();
break;
case 's':
sprintf(pos, " %11s ", "SIZE ");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 't':
if (option_timestamp_long) {
@@ -314,6 +359,7 @@ inline void out_print_format_string_header(const char *format) {
} else {
sprintf(pos, " %c%-7s ", toupper(option_time_field), "TIME");
}
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'A':
if (option_timestamp_long) {
@@ -321,6 +367,7 @@ inline void out_print_format_string_header(const char *format) {
} else {
sprintf(pos, " %-8s ", "ATIME");
}
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'C':
if (option_timestamp_long) {
@@ -328,6 +375,7 @@ inline void out_print_format_string_header(const char *format) {
} else {
sprintf(pos, " %-8s ", "CTIME");
}
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'M':
if (option_timestamp_long) {
@@ -335,24 +383,31 @@ inline void out_print_format_string_header(const char *format) {
} else {
sprintf(pos, " %-8s ", "MTIME");
}
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'T':
sprintf(pos, " %-12s ", "TYPE");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'u':
sprintf(pos, " %-4s ", "UID");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'g':
sprintf(pos, " %-4s ", "GID");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'U':
sprintf(pos, " %-10s ", "USER");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'G':
sprintf(pos, " %-10s ", "GROUP");
+ LOCAL_EXTEND_SEP_LINE();
break;
case 'p':
sprintf(pos, " %-4s ", "PERM");
+ LOCAL_EXTEND_SEP_LINE();
break;
case ' ':
break;
@@ -362,9 +417,24 @@ inline void out_print_format_string_header(const char *format) {
};
pos = &header[strlen(header)];
}
- printf("%s\n", header);
- fputc_width_x('-', strlen(header), stdout);
+ /* Output to stdout */
+ if (option_print_boxed_table) {
+ fputs(sep_line, stdout);
+ out_print_newline();
+ }
+ fputs(header, stdout);
out_print_newline();
+ if (option_print_boxed_table) {
+ tmp = strlen(sep_line);
+ fputs(sep_line, stdout);
+ if ((global_sep_line = calloc(tmp+1, sizeof(char))) != NULL) {
+ memcpy(global_sep_line, sep_line, tmp);
+ }
+ } else {
+ fputc_width_x('-', strlen(header), stdout);
+ }
+ out_print_newline();
+#undef LOCAL_EXTEND_SEP_LINE
}
/* === END OF FORMATTING FUNCTIONS === */
@@ -375,6 +445,7 @@ void print_list(struct list_head *list) {
struct list_head *lh = list;
struct list_node *ptr;
size_t total_size = 0;
+ size_t longest_fname = 0, i = 0;
if (list == NULL) return;
if (option_sort_reverse_order) {
@@ -385,15 +456,24 @@ void print_list(struct list_head *list) {
}
}
+ longest_fname = get_longest_filename(list);
+
if (option_print_header) {
- out_print_format_string_header("stn");
+ out_print_format_string_header("stn", longest_fname);
}
ptr = lh->first;
while (ptr != NULL) {
+ if (option_print_boxed_table) out_vsep();
out_print_size(ptr);
+ if (option_print_boxed_table) out_vsep();
out_print_time_by_option(ptr);
+ if (option_print_boxed_table) out_vsep();
out_print_fname(ptr);
+ if (option_print_boxed_table) {
+ for (i=0; i<(longest_fname-strlen(ptr->fname)); i++) fputc(' ', stdout);
+ out_vsep();
+ }
out_print_newline();
/* Linux: Neither man stat(2) nor stat(3type) declare why struct stat field st_size
@@ -405,7 +485,12 @@ void print_list(struct list_head *list) {
total_size += (ptr->ln_stat.st_size>0) ? (unsigned long int)ptr->ln_stat.st_size : 0;
ptr = ptr->next;
}
- fputc_all_cols('=', stdout);
+ if (option_print_boxed_table && global_sep_line != NULL) {
+ fputs(global_sep_line, stdout);
+ } else {
+ fputc_all_cols('=', stdout);
+ }
+ out_print_newline();
printf("\nTotal size: %lu %s\n", ((total_size>1024) ? total_size/1024 : total_size),
((total_size >= 1024) ? "kB" : ""));
@@ -432,7 +517,8 @@ void print_list(struct list_head *list) {
void print_list_formatted(const char *format, struct list_head *list) {
struct list_head *lh = list;
struct list_node *ptr;
- size_t format_len = 0, i = 0;
+ size_t format_len = 0, i = 0, j = 0;
+ size_t longest_fname = 0;
size_t total_size = 0;
if (format == NULL || format[0] == '\0') {
@@ -458,49 +544,67 @@ void print_list_formatted(const char *format, struct list_head *list) {
format_len = strnlen(format, DM_OUT_FORMAT_MAX_LEN);
DBGTRC("DEBUG: format_len = %lu\n", format_len);
+ longest_fname = get_longest_filename(list);
+
if (option_print_header) {
- out_print_format_string_header(format);
+ out_print_format_string_header(format, longest_fname);
}
ptr = lh->first;
while (ptr != NULL) {
+ if (option_print_boxed_table) { out_vsep(); }
for (i=0; i < format_len; i++) {
switch (format[i]) {
case 'n':
out_print_fname(ptr);
+ for (j=0; j<(longest_fname - strlen(ptr->fname)); j++) {
+ fputc(' ', stdout);
+ }
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 's':
out_print_size(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 't':
out_print_time_by_option(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'A':
out_print_time(ptr->ln_stat.st_atim.tv_sec);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'C':
out_print_time(ptr->ln_stat.st_ctim.tv_sec);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'M':
out_print_time(ptr->ln_stat.st_mtim.tv_sec);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'T':
out_print_type(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'u':
out_print_uid(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'g':
out_print_gid(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'U':
out_print_user_name(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'G':
out_print_group_name(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case 'p':
out_print_permissions(ptr);
+ if (option_print_boxed_table) { out_vsep(); }
break;
case ' ': /* just ignore this without warning */
break;
@@ -513,7 +617,12 @@ void print_list_formatted(const char *format, struct list_head *list) {
total_size += (ptr->ln_stat.st_size>0) ? (unsigned long int)ptr->ln_stat.st_size : 0;
ptr = ptr->next;
}
- fputc_all_cols('=', stdout);
+ if (option_print_boxed_table && global_sep_line != NULL) {
+ fputs(global_sep_line, stdout);
+ } else {
+ fputc_all_cols('=', stdout);
+ }
+ out_print_newline();
printf("\nTotal size: %lu %s\n", ((total_size>1024) ? total_size/1024 : total_size),
((total_size >= 1024) ? "kB" : ""));
if (lh != list) destroy_list(lh);