beloopana: Remove duplicate comments.
[libfirm] / ir / libcore / lc_appendable.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 IPD Goos, Universit"at Karlsruhe, Germany
4  */
5 #include "config.h"
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "util.h"
12 #include "lc_printf.h"
13
14 /* Default appendable implementations */
15
16 int lc_appendable_snwadd(lc_appendable_t *app, const char *str, size_t len,
17                 unsigned int width, int left_just, char pad)
18 {
19         int res = 0;
20         size_t i;
21         size_t to_pad = width > len ? width - len : 0;
22
23         /* If not left justified, pad left */
24         for (i = 0; !left_just && i < to_pad; ++i)
25                 res += lc_appendable_chadd(app, pad);
26
27         /* Send the visible portion of the string to the output. */
28         res += lc_appendable_snadd(app, str, len);
29
30         /* If left justified, pad right. */
31         for (i = 0; left_just && i < to_pad; ++i)
32                 res += lc_appendable_chadd(app, pad);
33
34         return res;
35 }
36
37
38 void lc_appendable_init(lc_appendable_t *env, const lc_appendable_funcs_t *app,
39                 void *obj, size_t limit)
40 {
41         env->obj = obj;
42         env->limit = limit;
43         env->written = 0;
44         env->app =app;
45
46         app->init(env);
47 }
48
49 static void default_init(lc_appendable_t *env)
50 {
51         (void) env;
52 }
53
54 static void default_finish(lc_appendable_t *env)
55 {
56         (void) env;
57 }
58
59 /*
60  * File appendable.
61  */
62
63 static int file_snadd(lc_appendable_t *obj, const char *str, size_t n)
64 {
65         obj->written += n;
66         fwrite(str, sizeof(char), n, (FILE*)obj->obj);
67         return n;
68 }
69
70 static int file_chadd(lc_appendable_t *obj, int ch)
71 {
72         fputc(ch, (FILE*)obj->obj);
73         obj->written++;
74         return 1;
75 }
76
77 static lc_appendable_funcs_t app_file = {
78         default_init,
79         default_finish,
80         file_snadd,
81         file_chadd
82 };
83
84 const lc_appendable_funcs_t *lc_appendable_file = &app_file;
85
86
87 /*
88  * String appendable.
89  */
90
91 static void str_init(lc_appendable_t *obj)
92 {
93         strncpy((char*)obj->obj, "", obj->limit);
94 }
95
96 static int str_snadd(lc_appendable_t *obj, const char *str, size_t n)
97 {
98         size_t to_write = MIN(obj->limit - obj->written - 1, n);
99         char *tgt = (char*)obj->obj;
100         strncpy(tgt + obj->written, str, to_write);
101         obj->written += to_write;
102         return to_write;
103 }
104
105 static int str_chadd(lc_appendable_t *obj, int ch)
106 {
107         if (obj->limit - obj->written > 1) {
108                 char *tgt = (char*)obj->obj;
109                 tgt[obj->written++] = (char) ch;
110                 return 1;
111         }
112
113         return 0;
114 }
115
116 static void str_finish(lc_appendable_t *obj)
117 {
118         char *str = (char*)obj->obj;
119         str[obj->written] = '\0';
120 }
121
122 static lc_appendable_funcs_t app_string = {
123         str_init,
124         str_finish,
125         str_snadd,
126         str_chadd
127 };
128
129 const lc_appendable_funcs_t *lc_appendable_string = &app_string;
130
131 /*
132  * Obstack appendable
133  */
134
135 static int obst_snadd(lc_appendable_t *obj, const char *str, size_t n)
136 {
137         struct obstack *obst = (struct obstack*)obj->obj;
138         obj->written += n;
139         obstack_grow(obst, str, n);
140         return n;
141 }
142
143 static int obst_chadd(lc_appendable_t *obj, int ch)
144 {
145         struct obstack *obst = (struct obstack*)obj->obj;
146         obstack_1grow(obst, (char) ch);
147         obj->written++;
148         return 1;
149 }
150
151 static lc_appendable_funcs_t app_obstack = {
152         default_init,
153         default_finish,
154         obst_snadd,
155         obst_chadd
156 };
157
158 const lc_appendable_funcs_t *lc_appendable_obstack = &app_obstack;