1#include <stdio.h> 2#include <string.h> 3#include <unistd.h> 4#include <stdarg.h> 5#include <time.h> 6#include <sys/stat.h> 7#include "lesstest.h" 8 9static FILE* logf = NULL; 10 11int log_open(const char* logfile) { 12 if (logf != NULL) fclose(logf); 13 logf = (strcmp(logfile, "-") == 0) ? stdout : fopen(logfile, "w"); 14 if (logf == NULL) { 15 fprintf(stderr, "cannot create %s\n", logfile); 16 return 0; 17 } 18 return 1; 19} 20 21void log_close(void) { 22 if (logf == NULL) return; 23 if (logf == stdout) return; 24 fclose(logf); 25 logf = NULL; 26} 27 28int log_file_header(void) { 29 if (logf == NULL) return 0; 30 time_t now = time(NULL); 31 struct tm* tm = gmtime(&now); 32 fprintf(logf, "!lesstest!\n!version %d\n!created %d-%02d-%02d %02d:%02d:%02d\n", 33 LESSTEST_VERSION, 34 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 35 tm->tm_hour, tm->tm_min, tm->tm_sec); 36 return 1; 37} 38 39int log_env(const char* name, int namelen, const char* value) { 40 if (logf == NULL) return 0; 41 fprintf(logf, "E \"%.*s\" \"%s\"\n", namelen, name, value); 42 return 1; 43} 44 45int log_tty_char(wchar ch) { 46 if (logf == NULL) return 0; 47 fprintf(logf, "+%lx\n", ch); 48 return 1; 49} 50 51int log_screen(const byte* img, int len) { 52 if (logf == NULL) return 0; 53 fwrite("=", 1, 1, logf); 54 fwrite(img, 1, len, logf); 55 fwrite("\n", 1, 1, logf); 56 return 1; 57} 58 59#if 0 60int log_debug(char const* fmt, ...) { 61 va_list ap; 62 va_start(ap, fmt); 63 fprintf(logf, "D "); 64 vfprintf(logf, fmt, ap); 65 fprintf(logf, "\n"); 66 va_end(ap); 67 fflush(logf); 68 return 1; 69} 70#endif 71 72int log_command(char* const* argv, int argc, const char* textfile) { 73 if (logf == NULL) return 0; 74 fprintf(logf, "A"); 75 int a; 76 for (a = 1; a < argc; ++a) 77 fprintf(logf, " \"%s\"", (a < argc-1) ? argv[a] : textfile); 78 fprintf(logf, "\n"); 79 return 1; 80} 81 82int log_textfile(const char* textfile) { 83 if (logf == NULL) return 0; 84 struct stat st; 85 if (stat(textfile, &st) < 0) { 86 fprintf(stderr, "cannot stat %s\n", textfile); 87 return 0; 88 } 89 FILE* fd = fopen(textfile, "r"); 90 if (fd == NULL) { 91 fprintf(stderr, "cannot open %s\n", textfile); 92 return 0; 93 } 94 fprintf(logf, "F \"%s\" %ld\n", textfile, (long) st.st_size); 95 off_t nread = 0; 96 while (nread < st.st_size) { 97 char buf[4096]; 98 size_t n = fread(buf, 1, sizeof(buf), fd); 99 if (n <= 0) { 100 fprintf(stderr, "read only %ld/%ld from %s\n", (long) nread, (long) st.st_size, textfile); 101 fclose(fd); 102 return 0; 103 } 104 nread += n; 105 fwrite(buf, 1, n, logf); 106 } 107 fclose(fd); 108 return 1; 109} 110 111int log_test_header(char* const* argv, int argc, const char* textfile) { 112 if (logf == NULL) return 0; 113 fprintf(logf, "T \"%s\"\n", textfile); 114 if (!log_command(argv, argc, textfile)) 115 return 0; 116 if (!log_textfile(textfile)) 117 return 0; 118 fprintf(logf, "R\n"); 119 return 1; 120} 121 122int log_test_footer(void) { 123 if (logf == NULL) return 0; 124 fprintf(logf, "Q\n"); 125 return 1; 126} 127