1 /*******************************************************************************
2 * Copyright (c) 2013-2021, Andrés Martinelli <andmarti@gmail.com> *
3 * All rights reserved. *
4 * *
5 * This file is a part of SC-IM *
6 * *
7 * SC-IM is a spreadsheet program that is based on SC. The original authors *
8 * of SC are James Gosling and Mark Weiser, and mods were later added by *
9 * Chuck Martin. *
10 * *
11 * Redistribution and use in source and binary forms, with or without *
12 * modification, are permitted provided that the following conditions are met: *
13 * 1. Redistributions of source code must retain the above copyright *
14 * notice, this list of conditions and the following disclaimer. *
15 * 2. Redistributions in binary form must reproduce the above copyright *
16 * notice, this list of conditions and the following disclaimer in the *
17 * documentation and/or other materials provided with the distribution. *
18 * 3. All advertising materials mentioning features or use of this software *
19 * must display the following acknowledgement: *
20 * This product includes software developed by Andrés Martinelli *
21 * <andmarti@gmail.com>. *
22 * 4. Neither the name of the Andrés Martinelli nor the *
23 * names of other contributors may be used to endorse or promote products *
24 * derived from this software without specific prior written permission. *
25 * *
26 * THIS SOFTWARE IS PROVIDED BY ANDRES MARTINELLI ''AS IS'' AND ANY *
27 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
29 * DISCLAIMED. IN NO EVENT SHALL ANDRES MARTINELLI BE LIABLE FOR ANY *
30 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;*
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
36 *******************************************************************************/
37
38 /**
39 * \file buffer.c
40 * \author Andrés Martinelli <andmarti@gmail.com>
41 * \date 2017-07-18
42 * \brief TODO Write a brief file description.
43 */
44
45 #include <stdlib.h>
46 #include <wchar.h>
47
48 #include "buffer.h"
49 #include "macros.h"
50 #include "utils/string.h"
51
52 /**
53 * \brief Create buffer as list of blocks
54 *
55 * \return b
56 */
57
create_buf()58 struct block * create_buf() {
59 struct block * b = (struct block *) malloc(sizeof(struct block));
60 b->value = '\0';
61 b->pnext = NULL;
62 return b;
63 }
64
65 /**
66 * \brief Add a wint_t to a buffer
67 *
68 * \param[in] buf
69 * \param[in] d
70 *
71 * \return none
72 */
73
addto_buf(struct block * buf,wint_t d)74 void addto_buf(struct block * buf, wint_t d) {
75 struct block * aux = buf;
76
77 if (buf->value == '\0') {
78 buf->value = d;
79 } else {
80 struct block * b = (struct block *) malloc(sizeof(struct block));
81 b->value = d;
82 b->pnext = NULL;
83
84 while (aux->pnext != NULL)
85 aux = aux->pnext;
86 aux->pnext = b;
87 }
88 return;
89 }
90
91 /**
92 * \brief Replace the elements of "origen" buffer to "destino" buffer
93 *
94 * \param[in] origen
95 * \param[in] destino
96 *
97 * \return none
98 */
99
copybuffer(struct block * origen,struct block * destino)100 void copybuffer(struct block * origen, struct block * destino) {
101 flush_buf(destino);
102 int len = get_bufsize(origen);
103 int i;
104 for (i=0; i < len; i++)
105 addto_buf(destino, get_bufval(origen, i));
106 return;
107 }
108
109
110 /**
111 * \brief Replace the element of a buffer at 'pos' with a '\0'
112 *
113 * \param[in] buf
114 * \param[in] pos
115 *
116 * \return none
117 */
118
119 // FIXME
del_buf(struct block * buf,int pos)120 void del_buf (struct block * buf, int pos) {
121 int i;
122 struct block * ant = buf;
123 struct block * cur = buf;
124 for (i = 0; i < pos; i++) {
125 ant = cur;
126 cur = cur->pnext;
127 }
128 if (ant == cur) {
129 cur->value = '\0';
130 //buf = cur->pnext; //FIXME
131 //free(cur);
132 } else {
133 ant->pnext = cur->pnext;
134 free(cur);
135 }
136 return;
137 }
138
139 /**
140 * \brief TODO Document flush_buf()
141 *
142 * \param[in] buf
143 *
144 * \return none
145 */
146
flush_buf(struct block * buf)147 void flush_buf (struct block * buf) {
148 if (buf == NULL) return;
149
150 struct block * aux, * np;
151 for (aux = buf->pnext; aux != NULL; aux = np) {
152 np = aux->pnext;
153 free(aux);
154 }
155 buf->value = '\0';
156 buf->pnext = NULL;
157
158 return;
159 }
160
161 /**
162 * \brief Delete all blocks of a buffer including the initial node
163 *
164 * \details Delete all blocks of a buffer including the initial node
165 *
166 * \param buf
167 *
168 * \return none
169 */
170
erase_buf(struct block * buf)171 void erase_buf (struct block * buf) {
172 flush_buf(buf);
173 free(buf);
174 return;
175 }
176
177 /**
178 * \brief Get size of buffer (included special chars)
179 *
180 * \param[in] buf
181 *
182 * \return c size of buffer
183 */
184
get_bufsize(struct block * buf)185 int get_bufsize(struct block * buf) {
186 struct block * b_aux = buf;
187 if (b_aux == NULL || b_aux->value == '\0') return 0;
188 int c = 0;
189 while (b_aux != NULL) {
190 c++;
191 b_aux = b_aux->pnext;
192 }
193 return c;
194 }
195
196 /**
197 * \brief Get printable buffer length (excluded special chars)
198 *
199 * \details Get printable bufferlength, which excludes special characters
200 * as they should never be printed to a screen.
201 *
202 * \param[in] buf
203 *
204 * \return c printable buffer length
205 */
206
get_pbuflen(struct block * buf)207 int get_pbuflen(struct block * buf) {
208 struct block * b_aux = buf;
209 if (b_aux == NULL || b_aux->value == '\0') return 0;
210 int c = 0;
211 while (b_aux != NULL) {
212 if ( !is_idchar(b_aux->value) ) c++;
213 b_aux = b_aux->pnext;
214 }
215 return c;
216 }
217
218 /**
219 * \brief Return the int value of n block
220 *
221 * \param[in] buf
222 * \param[in] d
223 *
224 * \return none
225 */
226
get_bufval(struct block * buf,int d)227 int get_bufval(struct block * buf, int d) {
228 int i;
229 struct block * b_aux = buf;
230 for (i = 0; i < d; i++) {
231 b_aux = b_aux->pnext;
232 }
233 return b_aux->value;
234 }
235
236 /**
237 * \brief Return an int value if found in a buffer
238 *
239 * \details Search a buffer for a given integer value.
240 *
241 * \return 0 if not found, 1 if found
242 */
243
find_val(struct block * buf,int value)244 int find_val(struct block * buf, int value) {
245 struct block * b_aux = buf;
246 while ( b_aux != NULL && b_aux->value != '\0' ) {
247 if (b_aux->value == value) return 1;
248 b_aux = b_aux->pnext;
249 }
250 return 0;
251 }
252
253 /**
254 * \brief Delete the first element in a buffer
255 *
256 * \param[in] buf
257 *
258 * \return none
259 */
260
dequeue(struct block * buf)261 struct block * dequeue (struct block * buf) {
262 if (buf == NULL) return buf;
263 struct block * sig;
264 if (buf->value == '\0') return buf;
265
266 if (buf->pnext == NULL) {
267 buf->value = '\0';
268 } else {
269 sig = buf->pnext;
270 //free(buf);
271 buf = sig;
272 }
273 return buf;
274 }
275