7656375b7aad0668a41311a9477f7acffd7f3ab1
[libfirm] / ir / libcore / lc_appendable.c
1 /*
2   libcore: library for basic data structures and algorithms.
3   Copyright (C) 2005  IPD Goos, Universit"at Karlsruhe, Germany
4
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "lc_common_t.h"
25 #include "lc_defines.h"
26 #include "lc_printf.h"
27
28 /* Default appendable implementations */
29
30 int lc_appendable_snwadd(lc_appendable_t *app, const char *str, size_t len,
31                 unsigned int width, int left_just, char pad)
32 {
33         int res = 0;
34         int i;
35         int to_pad = width - len;
36
37         /* If not left justified, pad left */
38         for(i = 0; !left_just && i < to_pad; ++i)
39                 res += lc_appendable_chadd(app, pad);
40
41         /* Send the visible portion of the string to the output. */
42         res += lc_appendable_snadd(app, str, len);
43
44         /* If left justified, pad right. */
45         for(i = 0; left_just && i < to_pad; ++i)
46                 res += lc_appendable_chadd(app, pad);
47
48         return res;
49 }
50
51
52 void lc_appendable_init(lc_appendable_t *env, const lc_appendable_funcs_t *app,
53                 void *obj, size_t limit)
54 {
55         env->obj = obj;
56         env->limit = limit;
57         env->written = 0;
58         env->app =app;
59
60         app->init(env);
61 }
62
63 static void default_init(UNUSED(lc_appendable_t *env))
64 {
65 }
66
67 static void default_finish(UNUSED(lc_appendable_t *env))
68 {
69 }
70
71 /*
72  * File appendable.
73  */
74
75 static int file_snadd(lc_appendable_t *obj, const char *str, size_t n)
76 {
77         obj->written += n;
78         fwrite(str, sizeof(char), n, obj->obj);
79         return n;
80 }
81
82 static int file_chadd(lc_appendable_t *obj, int ch)
83 {
84         fputc(ch, obj->obj);
85         obj->written++;
86         return 1;
87 }
88
89 static lc_appendable_funcs_t app_file = {
90         default_init,
91         default_finish,
92         file_snadd,
93         file_chadd
94 };
95
96 const lc_appendable_funcs_t *lc_appendable_file = &app_file;
97
98
99 /*
100  * String appendable.
101  */
102
103 static void str_init(lc_appendable_t *obj)
104 {
105         strncpy(obj->obj, "", obj->limit);
106 }
107
108 static int str_snadd(lc_appendable_t *obj, const char *str, size_t n)
109 {
110         size_t to_write = LC_MIN(obj->limit - obj->written - 1, n);
111         char *tgt = obj->obj;
112         strncpy(tgt + obj->written, str, to_write);
113         obj->written += to_write;
114         return to_write;
115 }
116
117 static int str_chadd(lc_appendable_t *obj, int ch)
118 {
119         if(obj->limit - obj->written > 1) {
120                 char *tgt = obj->obj;
121                 tgt[obj->written++] = (char) ch;
122                 return 1;
123         }
124
125         return 0;
126 }
127
128 static void str_finish(lc_appendable_t *obj)
129 {
130         char *str = obj->obj;
131         str[obj->written] = '\0';
132 }
133
134 static lc_appendable_funcs_t app_string = {
135         str_init,
136         str_finish,
137         str_snadd,
138         str_chadd
139 };
140
141 const lc_appendable_funcs_t *lc_appendable_string = &app_string;
142
143 /*
144  * Obstack appendable
145  */
146
147 static int obst_snadd(lc_appendable_t *obj, const char *str, size_t n)
148 {
149         struct obstack *obst = obj->obj;
150         obj->written += n;
151         obstack_grow(obst, str, n);
152         return n;
153 }
154
155 static int obst_chadd(lc_appendable_t *obj, int ch)
156 {
157         struct obstack *obst = obj->obj;
158         obstack_1grow(obst, (char) ch);
159         obj->written++;
160         return 1;
161 }
162
163 static lc_appendable_funcs_t app_obstack = {
164         default_init,
165         default_finish,
166         obst_snadd,
167         obst_chadd
168 };
169
170 const lc_appendable_funcs_t *lc_appendable_obstack = &app_obstack;