coroutine: Remove on-stack buffers from testcases
[ccan] / junkcode / henryeshbaugh@gmail.com-log / log.c
1 #include <log.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <stdarg.h>
6 #include <time.h>
7
8 // escape codes for different colors on the terminal
9 #define FG_RED          "\033[31m"
10 #define FG_YELLOW       "\033[33m"
11 #define FG_BLUE         "\033[34m"
12 #define FG_PURPLE       "\033[35m"
13 #define TEXT_BOLD       "\033[1m"
14 #define COLOR_END       "\033[0m" // reset colors to default
15
16 static FILE *_logging_files[16] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
17                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
18 static int  _log_current_mode, _current_log_file = 1;
19
20 FILE *set_log_file(char *filename)
21 {
22         if (_current_log_file+1 > 16) return NULL; // we only support 16 different files
23         _logging_files[_current_log_file++] = fopen(filename, "a+");
24         return _logging_files[_current_log_file];
25 }
26
27 void set_log_mode(int mode)
28 {
29         _log_current_mode = mode;
30 }
31
32 void get_log_mode()
33 {
34         return _log_current_mode;
35 }
36
37 // this function is headache-inducing.
38 void _print_log(int loglevel, char *file, const char *func, char *clock, int line, char *msg, ...)
39 {
40         _logging_files[0] = stdout;
41         va_list args;
42         va_start(args, msg);
43         
44         // append the varargs to the buffer we want to print.
45         // this is so that our pipe chars don't get fucked later.
46         // also, make sure we don't get an invalid loglevel.
47         char buffer[strlen(msg) + 1024];
48         vsnprintf(buffer, strlen(msg)+1024, msg, args); 
49         if (loglevel < 0 || loglevel > 3) loglevel = LOG_INVALID;
50
51         // set console color for printing the tag
52         switch (loglevel) {
53                 case LOG_CRITICAL:
54                         printf(TEXT_BOLD FG_RED);
55                         break;
56                 case LOG_ERROR:
57                         printf(FG_RED);
58                         break;
59                 case LOG_WARNING:
60                         printf(FG_YELLOW);
61                         break;
62                 case LOG_INFO:
63                         printf(FG_BLUE);
64                         break;
65                 case LOG_INVALID:
66                         printf(FG_PURPLE);
67                         break;
68         }
69         // print the log tag
70         int i;
71         for (i=0; i < 16; i++)
72                 if (_logging_files[i])
73                         fprintf(_logging_files[i], "%s", log_tags[_log_current_mode][loglevel]);
74                 else break;
75         printf(COLOR_END);
76         
77         if (_log_current_mode == LOG_VERBOSE) {
78                 for (i=0; i < 16; i++)
79                         if (_logging_files[i])
80                                 fprintf(_logging_files[i],
81                                         "%s() (%s:%d) at %s |\t",
82                                         func, file, line, clock);
83                         else break;
84         }
85
86         // print the first line
87          char *to_print = strtok(buffer, "\n");
88          for (i = 0; i < 16; i++)
89                 if (_logging_files[i])
90                         fprintf(_logging_files[i], "%s\n", to_print);
91                 else break;
92
93         // for these next lines, add a pipe and tab once.
94         while (to_print = strtok(NULL, "\n")) {
95                 for (i = 0; i < 16; i++)
96                         if (_logging_files[i])
97                                 fprintf(_logging_files[i], "%s\n", to_print);
98                         else break;
99         }
100 }