cleanup: Add and use macro MIN().
[cparser] / printer.c
1 /*
2  * This file is part of cparser.
3  * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
4  */
5 #include "config.h"
6
7 #include "adt/util.h"
8 #include "printer.h"
9
10 #include <stdio.h>
11 #include <stdarg.h>
12
13 static FILE* out;
14
15 static void print_char_file(const char c)
16 {
17         fputc(c, out);
18 }
19
20 static void print_string_file(const char *str)
21 {
22         fputs(str, out);
23 }
24
25 static void print_vformat_file(const char *format, va_list ap)
26 {
27         vfprintf(out, format, ap);
28 }
29
30 void print_to_file(FILE *new_out)
31 {
32         out = new_out;
33         print_string  = print_string_file;
34         print_vformat = print_vformat_file;
35         print_char    = print_char_file;
36 }
37
38
39
40 static struct obstack *obst;
41
42 static void print_char_obstack(const char c)
43 {
44         obstack_1grow(obst, c);
45 }
46
47 static void print_string_obstack(const char *str)
48 {
49         size_t len = strlen(str);
50         obstack_grow(obst, str, len);
51 }
52
53 static void print_vformat_obstack(const char *format, va_list ap)
54 {
55         obstack_vprintf(obst, format, ap);
56 }
57
58 void print_to_obstack(struct obstack *new_obst)
59 {
60         obst = new_obst;
61         print_string  = print_string_obstack;
62         print_vformat = print_vformat_obstack;
63         print_char    = print_char_obstack;
64 }
65
66
67
68 static char *buffer_pos;
69 static char *buffer_end;
70
71 static void print_char_buffer(const char c)
72 {
73         if (buffer_pos == buffer_end)
74                 return;
75         *buffer_pos++ = c;
76 }
77
78 static void print_string_buffer(const char *str)
79 {
80         for (const char *c = str; *c != '\0'; ++c) {
81                 print_char_buffer(*c);
82         }
83 }
84
85 static void print_vformat_buffer(const char *format, va_list ap)
86 {
87         size_t size    = buffer_end - buffer_pos;
88         size_t written = (size_t) vsnprintf(buffer_pos, size, format, ap);
89         buffer_pos    += MIN(written, size);
90 }
91
92 void print_to_buffer(char *buffer, size_t buffer_size)
93 {
94         buffer_pos = buffer;
95         buffer_end = buffer + buffer_size - 2;
96
97         print_string  = print_string_buffer;
98         print_vformat = print_vformat_buffer;
99         print_char    = print_char_buffer;
100 }
101
102 void finish_print_to_buffer(void)
103 {
104         *buffer_pos = '\0';
105         buffer_pos = NULL;
106         buffer_end = NULL;
107 }
108
109
110 void (*print_string)(const char *str) = print_string_file;
111 void (*print_vformat)(const char *format, va_list ap) = print_vformat_file;
112 void (*print_char)(const char c) = print_char_file;
113
114 void printer_push(void)
115 {
116         /* TODO */
117 }
118
119 void printer_pop(void)
120 {
121         /* TODO */
122 }