File: | libs/libteletone/src/libteletone_generate.c |
Location: | line 259, column 11 |
Description: | Division by zero |
1 | /* | |||
2 | * libteletone | |||
3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> | |||
4 | * | |||
5 | * Version: MPL 1.1 | |||
6 | * | |||
7 | * The contents of this file are subject to the Mozilla Public License Version | |||
8 | * 1.1 (the "License"); you may not use this file except in compliance with | |||
9 | * the License. You may obtain a copy of the License at | |||
10 | * http://www.mozilla.org/MPL/ | |||
11 | * | |||
12 | * Software distributed under the License is distributed on an "AS IS" basis, | |||
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||
14 | * for the specific language governing rights and limitations under the | |||
15 | * License. | |||
16 | * | |||
17 | * The Original Code is libteletone | |||
18 | * | |||
19 | * The Initial Developer of the Original Code is | |||
20 | * Anthony Minessale II <anthm@freeswitch.org> | |||
21 | * Portions created by the Initial Developer are Copyright (C) | |||
22 | * the Initial Developer. All Rights Reserved. | |||
23 | * | |||
24 | * Contributor(s): | |||
25 | * | |||
26 | * Anthony Minessale II <anthm@freeswitch.org> | |||
27 | * | |||
28 | * | |||
29 | * libteletone.c -- Tone Generator | |||
30 | * | |||
31 | * | |||
32 | * | |||
33 | * Exception: | |||
34 | * The author hereby grants the use of this source code under the | |||
35 | * following license if and only if the source code is distributed | |||
36 | * as part of the OpenZAP or FreeTDM library. Any use or distribution of this | |||
37 | * source code outside the scope of the OpenZAP or FreeTDM library will nullify the | |||
38 | * following license and reinact the MPL 1.1 as stated above. | |||
39 | * | |||
40 | * Copyright (c) 2007, Anthony Minessale II | |||
41 | * All rights reserved. | |||
42 | * | |||
43 | * Redistribution and use in source and binary forms, with or without | |||
44 | * modification, are permitted provided that the following conditions | |||
45 | * are met: | |||
46 | * | |||
47 | * * Redistributions of source code must retain the above copyright | |||
48 | * notice, this list of conditions and the following disclaimer. | |||
49 | * | |||
50 | * * Redistributions in binary form must reproduce the above copyright | |||
51 | * notice, this list of conditions and the following disclaimer in the | |||
52 | * documentation and/or other materials provided with the distribution. | |||
53 | * | |||
54 | * * Neither the name of the original author; nor the names of any contributors | |||
55 | * may be used to endorse or promote products derived from this software | |||
56 | * without specific prior written permission. | |||
57 | * | |||
58 | * | |||
59 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
60 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
61 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
62 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | |||
63 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
64 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
65 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
66 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
67 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
68 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
69 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
70 | */ | |||
71 | ||||
72 | #include <libteletone.h> | |||
73 | ||||
74 | #define SMAX32767 32767 | |||
75 | #define SMIN-32768 -32768 | |||
76 | #define normalize_to_16bit(n)if (n > 32767) n = 32767; else if (n < -32768) n = -32768 ; if (n > SMAX32767) n = SMAX32767; else if (n < SMIN-32768) n = SMIN-32768; | |||
77 | ||||
78 | #ifdef _MSC_VER | |||
79 | #pragma warning(disable:4706) | |||
80 | #endif | |||
81 | ||||
82 | TELETONE_API_DATA__attribute__((visibility("default"))) int16_t TELETONE_SINES[SINE_TABLE_MAX128] = { | |||
83 | 0x00c9, 0x025b, 0x03ed, 0x057f, 0x0711, 0x08a2, 0x0a33, 0x0bc4, | |||
84 | 0x0d54, 0x0ee4, 0x1073, 0x1201, 0x138f, 0x151c, 0x16a8, 0x1833, | |||
85 | 0x19be, 0x1b47, 0x1cd0, 0x1e57, 0x1fdd, 0x2162, 0x22e5, 0x2467, | |||
86 | 0x25e8, 0x2768, 0x28e5, 0x2a62, 0x2bdc, 0x2d55, 0x2ecc, 0x3042, | |||
87 | 0x31b5, 0x3327, 0x3497, 0x3604, 0x3770, 0x38d9, 0x3a40, 0x3ba5, | |||
88 | 0x3d08, 0x3e68, 0x3fc6, 0x4121, 0x427a, 0x43d1, 0x4524, 0x4675, | |||
89 | 0x47c4, 0x490f, 0x4a58, 0x4b9e, 0x4ce1, 0x4e21, 0x4f5e, 0x5098, | |||
90 | 0x51cf, 0x5303, 0x5433, 0x5560, 0x568a, 0x57b1, 0x58d4, 0x59f4, | |||
91 | 0x5b10, 0x5c29, 0x5d3e, 0x5e50, 0x5f5e, 0x6068, 0x616f, 0x6272, | |||
92 | 0x6371, 0x646c, 0x6564, 0x6657, 0x6747, 0x6832, 0x691a, 0x69fd, | |||
93 | 0x6add, 0x6bb8, 0x6c8f, 0x6d62, 0x6e31, 0x6efb, 0x6fc2, 0x7083, | |||
94 | 0x7141, 0x71fa, 0x72af, 0x735f, 0x740b, 0x74b3, 0x7556, 0x75f4, | |||
95 | 0x768e, 0x7723, 0x77b4, 0x7840, 0x78c8, 0x794a, 0x79c9, 0x7a42, | |||
96 | 0x7ab7, 0x7b27, 0x7b92, 0x7bf9, 0x7c5a, 0x7cb7, 0x7d0f, 0x7d63, | |||
97 | 0x7db1, 0x7dfb, 0x7e3f, 0x7e7f, 0x7eba, 0x7ef0, 0x7f22, 0x7f4e, | |||
98 | 0x7f75, 0x7f98, 0x7fb5, 0x7fce, 0x7fe2, 0x7ff1, 0x7ffa, 0x7fff | |||
99 | }; | |||
100 | ||||
101 | ||||
102 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_set_tone(teletone_generation_session_t *ts, int index, ...) | |||
103 | { | |||
104 | va_list ap; | |||
105 | int i = 0; | |||
106 | teletone_process_t x = 0; | |||
107 | ||||
108 | va_start(ap, index)__builtin_va_start(ap, index); | |||
109 | while (i < TELETONE_MAX_TONES18 && (x = va_arg(ap, teletone_process_t)__builtin_va_arg(ap, teletone_process_t))) { | |||
110 | ts->TONES[index].freqs[i++] = x; | |||
111 | } | |||
112 | va_end(ap)__builtin_va_end(ap); | |||
113 | ||||
114 | return (i > TELETONE_MAX_TONES18) ? -1 : 0; | |||
115 | ||||
116 | } | |||
117 | ||||
118 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_set_map(teletone_tone_map_t *map, ...) | |||
119 | { | |||
120 | va_list ap; | |||
121 | int i = 0; | |||
122 | teletone_process_t x = 0; | |||
123 | ||||
124 | va_start(ap, map)__builtin_va_start(ap, map); | |||
125 | while (i < TELETONE_MAX_TONES18 && (x = va_arg(ap, teletone_process_t)__builtin_va_arg(ap, teletone_process_t))) { | |||
126 | map->freqs[i++] = x; | |||
127 | } | |||
128 | va_end(ap)__builtin_va_end(ap); | |||
129 | ||||
130 | return (i > TELETONE_MAX_TONES18) ? -1 : 0; | |||
131 | ||||
132 | } | |||
133 | ||||
134 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data) | |||
135 | { | |||
136 | memset(ts, 0, sizeof(*ts)); | |||
137 | ts->rate = 8000; | |||
138 | ts->channels = 1; | |||
139 | ts->duration = 2000; | |||
140 | ts->wait = 500; | |||
141 | ts->tmp_duration = -1; | |||
142 | ts->tmp_wait = -1; | |||
143 | ts->handler = handler; | |||
144 | ts->user_data = user_data; | |||
145 | ts->volume = -7; | |||
146 | ts->decay_step = 0; | |||
147 | ts->decay_factor = 1; | |||
148 | if (buflen) { | |||
149 | if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) { | |||
150 | return -1; | |||
151 | } | |||
152 | ts->datalen = buflen; | |||
153 | } else { | |||
154 | ts->dynamic = 1024; | |||
155 | } | |||
156 | /* Add Standard DTMF Tones */ | |||
157 | teletone_set_tone(ts, '1', 697.0, 1209.0, 0.0); | |||
158 | teletone_set_tone(ts, '2', 697.0, 1336.0, 0.0); | |||
159 | teletone_set_tone(ts, '3', 697.0, 1477.0, 0.0); | |||
160 | teletone_set_tone(ts, 'A', 697.0, 1633.0, 0.0); | |||
161 | teletone_set_tone(ts, '4', 770.0, 1209.0, 0.0); | |||
162 | teletone_set_tone(ts, '5', 770.0, 1336.0, 0.0); | |||
163 | teletone_set_tone(ts, '6', 770.0, 1477.0, 0.0); | |||
164 | teletone_set_tone(ts, 'B', 770.0, 1633.0, 0.0); | |||
165 | teletone_set_tone(ts, '7', 859.0, 1209.0, 0.0); | |||
166 | teletone_set_tone(ts, '8', 859.0, 1336.0, 0.0); | |||
167 | teletone_set_tone(ts, '9', 859.0, 1477.0, 0.0); | |||
168 | teletone_set_tone(ts, 'C', 859.0, 1633.0, 0.0); | |||
169 | teletone_set_tone(ts, '*', 941.0, 1209.0, 0.0); | |||
170 | teletone_set_tone(ts, '0', 941.0, 1336.0, 0.0); | |||
171 | teletone_set_tone(ts, '#', 941.0, 1477.0, 0.0); | |||
172 | teletone_set_tone(ts, 'D', 941.0, 1633.0, 0.0); | |||
173 | ||||
174 | return 0; | |||
175 | } | |||
176 | ||||
177 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_destroy_session(teletone_generation_session_t *ts) | |||
178 | { | |||
179 | if (ts->buffer) { | |||
180 | free(ts->buffer); | |||
181 | ts->buffer = NULL((void*)0); | |||
182 | ts->samples = 0; | |||
183 | } | |||
184 | return 0; | |||
185 | } | |||
186 | ||||
187 | static int ensure_buffer(teletone_generation_session_t *ts, int need) | |||
188 | { | |||
189 | need += ts->samples; | |||
190 | need *= sizeof(teletone_audio_t); | |||
191 | need *= ts->channels; | |||
192 | ||||
193 | if (need > ts->datalen) { | |||
194 | teletone_audio_t *tmp; | |||
195 | ts->datalen = need + ts->dynamic; | |||
196 | tmp = realloc(ts->buffer, ts->datalen); | |||
197 | if (!tmp) { | |||
198 | return -1; | |||
199 | } | |||
200 | ts->buffer = tmp; | |||
201 | } | |||
202 | ||||
203 | return 0; | |||
204 | } | |||
205 | ||||
206 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map) | |||
207 | { | |||
208 | /*teletone_process_t period = (1.0 / ts->rate) / ts->channels;*/ | |||
209 | int i, c; | |||
210 | int freqlen = 0; | |||
211 | teletone_dds_state_t tones[TELETONE_MAX_TONES18+1]; | |||
212 | //int decay = 0; | |||
213 | int duration; | |||
214 | int wait = 0; | |||
215 | int32_t sample; | |||
216 | int32_t dc = 0; | |||
217 | float vol = ts->volume; | |||
218 | ts->samples = 0; | |||
219 | memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES18); | |||
220 | duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration; | |||
| ||||
221 | wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait; | |||
222 | ||||
223 | if (map->freqs[0] > 0) { | |||
224 | for (freqlen = 0; freqlen < TELETONE_MAX_TONES18 && map->freqs[freqlen]; freqlen++) { | |||
225 | teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0); | |||
226 | teletone_dds_state_set_tx_level(&tones[freqlen], vol); | |||
227 | } | |||
228 | ||||
229 | if (ts->channels > 1) { | |||
230 | duration *= ts->channels; | |||
231 | } | |||
232 | ||||
233 | if (ts->dynamic) { | |||
234 | if (ensure_buffer(ts, duration)) { | |||
235 | return -1; | |||
236 | } | |||
237 | } | |||
238 | ||||
239 | for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) { | |||
240 | if (ts->decay_direction && ++dc >= ts->decay_step) { | |||
241 | float nvol = vol + ts->decay_direction * ts->decay_factor; | |||
242 | int j; | |||
243 | ||||
244 | if (nvol <= TELETONE_VOL_DB_MAX0 && nvol >= TELETONE_VOL_DB_MIN-63) { | |||
245 | vol = nvol; | |||
246 | for (j = 0; j < TELETONE_MAX_TONES18 && map->freqs[j]; j++) { | |||
247 | teletone_dds_state_set_tx_level(&tones[j], vol); | |||
248 | } | |||
249 | dc = 0; | |||
250 | } | |||
251 | } | |||
252 | ||||
253 | sample = 128; | |||
254 | ||||
255 | for (i = 0; i < freqlen; i++) { | |||
256 | int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0); | |||
257 | sample += s; | |||
258 | } | |||
259 | sample /= freqlen; | |||
| ||||
260 | ts->buffer[ts->samples] = (teletone_audio_t)sample; | |||
261 | ||||
262 | for (c = 1; c < ts->channels; c++) { | |||
263 | ts->buffer[ts->samples+1] = ts->buffer[ts->samples]; | |||
264 | ts->samples++; | |||
265 | } | |||
266 | ||||
267 | } | |||
268 | } | |||
269 | if (ts->dynamic) { | |||
270 | if (ensure_buffer(ts, wait)) { | |||
271 | return -1; | |||
272 | } | |||
273 | } | |||
274 | for (c = 0; c < ts->channels; c++) { | |||
275 | for (i = 0; i < wait && ts->samples < ts->datalen; i++) { | |||
276 | ts->buffer[ts->samples++] = 0; | |||
277 | } | |||
278 | } | |||
279 | ||||
280 | if (ts->debug && ts->debug_stream) { | |||
281 | if (map->freqs[0] <= 0) { | |||
282 | fprintf(ts->debug_stream, "wait %d (%dms)\n", wait, wait / (ts->rate / 1000)); | |||
283 | } else { | |||
284 | fprintf(ts->debug_stream, "Generate: ("); | |||
285 | ||||
286 | for (i = 0; i < TELETONE_MAX_TONES18 && map->freqs[i]; i++) { | |||
287 | fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]); | |||
288 | } | |||
289 | ||||
290 | fprintf(ts->debug_stream, | |||
291 | ") [volume %0.2fdB; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %0.2fdB; decay_step %d(%dms); wrote %d bytes]\n", | |||
292 | ts->volume, | |||
293 | duration, | |||
294 | duration / (ts->rate / 1000), | |||
295 | ts->channels, | |||
296 | ts->channels == 1 ? "" : "s", | |||
297 | wait, | |||
298 | wait / (ts->rate / 1000), | |||
299 | ts->decay_factor, | |||
300 | ts->decay_step, | |||
301 | ts->decay_step / (ts->rate / 1000), | |||
302 | ts->samples * 2); | |||
303 | } | |||
304 | } | |||
305 | return ts->samples / ts->channels; | |||
306 | } | |||
307 | ||||
308 | /* don't ask */ | |||
309 | static char *my_strdup (const char *s) | |||
310 | { | |||
311 | size_t len = strlen (s) + 1; | |||
312 | void *new = malloc (len); | |||
313 | ||||
314 | if (new == NULL((void*)0)) { | |||
315 | return NULL((void*)0); | |||
316 | } | |||
317 | ||||
318 | return (char *) memcpy (new, s, len); | |||
319 | } | |||
320 | ||||
321 | TELETONE_API(int)__attribute__((visibility("default"))) int teletone_run(teletone_generation_session_t *ts, const char *cmd) | |||
322 | { | |||
323 | char *data = NULL((void*)0), *cur = NULL((void*)0), *end = NULL((void*)0); | |||
324 | int LOOPING = 0; | |||
325 | ||||
326 | if (!cmd) { | |||
327 | return -1; | |||
328 | } | |||
329 | ||||
330 | do { | |||
331 | if (!(data = my_strdup(cmd))) { | |||
332 | return -1; | |||
333 | } | |||
334 | ||||
335 | cur = data; | |||
336 | ||||
337 | while (*cur) { | |||
338 | if (*cur == ' ' || *cur == '\r' || *cur == '\n') { | |||
339 | cur++; | |||
340 | continue; | |||
341 | } | |||
342 | ||||
343 | if ((end = strchr(cur, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p (cur) && (';') == '\0' ? (char *) __rawmemchr (cur, ';' ) : __builtin_strchr (cur, ';')))) != 0) { | |||
344 | *end++ = '\0'; | |||
345 | } | |||
346 | ||||
347 | if (*(cur + 1) == '=') { | |||
348 | switch(*cur) { | |||
349 | case 'c': | |||
350 | ts->channels = atoi(cur + 2); | |||
351 | break; | |||
352 | case 'r': | |||
353 | ts->rate = atoi(cur + 2); | |||
354 | break; | |||
355 | case 'd': | |||
356 | ts->duration = atoi(cur + 2) * (ts->rate / 1000); | |||
357 | break; | |||
358 | case 'v': | |||
359 | { | |||
360 | float vol = (float)atof(cur + 2); | |||
361 | if (vol <= TELETONE_VOL_DB_MAX0 && vol >= TELETONE_VOL_DB_MIN-63) { | |||
362 | ts->volume = vol; | |||
363 | } | |||
364 | } | |||
365 | break; | |||
366 | case '>': | |||
367 | ts->decay_step = atoi(cur + 2) * (ts->rate / 1000); | |||
368 | ts->decay_direction = -1; | |||
369 | break; | |||
370 | case '<': | |||
371 | ts->decay_step = atoi(cur + 2) * (ts->rate / 1000); | |||
372 | ts->decay_direction = 1; | |||
373 | break; | |||
374 | case '+': | |||
375 | ts->decay_factor = (float)atof(cur + 2); | |||
376 | break; | |||
377 | case 'w': | |||
378 | ts->wait = atoi(cur + 2) * (ts->rate / 1000); | |||
379 | break; | |||
380 | case 'l': | |||
381 | ts->loops = atoi(cur + 2); | |||
382 | break; | |||
383 | case 'L': | |||
384 | if (!LOOPING) { | |||
385 | int L; | |||
386 | if ((L = atoi(cur + 2)) > 0) { | |||
387 | ts->LOOPS = L; | |||
388 | LOOPING++; | |||
389 | } | |||
390 | } | |||
391 | break; | |||
392 | } | |||
393 | } else { | |||
394 | while (*cur) { | |||
395 | char *p = NULL((void*)0), *e = NULL((void*)0); | |||
396 | teletone_tone_map_t mymap, *mapp = NULL((void*)0); | |||
397 | ||||
398 | if (*cur == ' ' || *cur == '\r' || *cur == '\n') { | |||
399 | cur++; | |||
400 | continue; | |||
401 | } | |||
402 | ||||
403 | ts->tmp_duration = -1; | |||
404 | ts->tmp_wait = -1; | |||
405 | ||||
406 | memset(&mymap, 0, sizeof(mymap)); | |||
407 | ||||
408 | if (*(cur + 1) == '(') { | |||
409 | p = cur + 2; | |||
410 | if (*cur) { | |||
411 | char *next; | |||
412 | int i = 0; | |||
413 | if ((e = strchr(p, ')')(__extension__ (__builtin_constant_p (')') && !__builtin_constant_p (p) && (')') == '\0' ? (char *) __rawmemchr (p, ')') : __builtin_strchr (p, ')')))) != 0) { | |||
414 | *e++ = '\0'; | |||
415 | } | |||
416 | do { | |||
417 | #if (_MSC_VER == 1600) | |||
418 | if (!p) { | |||
419 | break; | |||
420 | } | |||
421 | #endif | |||
422 | if ((next = strchr(p, ',')(__extension__ (__builtin_constant_p (',') && !__builtin_constant_p (p) && (',') == '\0' ? (char *) __rawmemchr (p, ',') : __builtin_strchr (p, ',')))) != 0) { | |||
423 | *next++ = '\0'; | |||
424 | } | |||
425 | if (i == 0) { | |||
426 | ts->tmp_duration = atoi(p) * (ts->rate / 1000); | |||
427 | i++; | |||
428 | } else if (i == 1) { | |||
429 | ts->tmp_wait = atoi(p) * (ts->rate / 1000); | |||
430 | i++; | |||
431 | } else { | |||
432 | mymap.freqs[i++ - 2] = atof(p); | |||
433 | } | |||
434 | p = next; | |||
435 | ||||
436 | } while (next && (i-2) < TELETONE_MAX_TONES18); | |||
437 | if (i > 2 && *cur == '%') { | |||
438 | mapp = &mymap; | |||
439 | } else if ((i != 2 || *cur == '%')) { | |||
440 | if (ts->debug && ts->debug_stream) { | |||
441 | fprintf(ts->debug_stream, "Syntax Error!\n"); | |||
442 | } | |||
443 | goto bottom; | |||
444 | } | |||
445 | } | |||
446 | } | |||
447 | ||||
448 | if (*cur && !mapp) { | |||
449 | if (*cur > 0 && *cur < TELETONE_TONE_RANGE127) { | |||
450 | mapp = &ts->TONES[(int)*cur]; | |||
451 | } else if (ts->debug && ts->debug_stream) { | |||
452 | fprintf(ts->debug_stream, "Map [%c] Out Of Range!\n", *cur); | |||
453 | } | |||
454 | } | |||
455 | ||||
456 | if (mapp) { | |||
457 | if (mapp->freqs[0]) { | |||
458 | if (ts->handler) { | |||
459 | do { | |||
460 | ts->handler(ts, mapp); | |||
461 | if (ts->loops > 0) { | |||
462 | ts->loops--; | |||
463 | } | |||
464 | } while (ts->loops); | |||
465 | } | |||
466 | } else if (ts->debug && ts->debug_stream) { | |||
467 | fprintf(ts->debug_stream, "Ignoring Empty Map [%c]!\n", *cur); | |||
468 | } | |||
469 | } | |||
470 | ||||
471 | if (e) { | |||
472 | cur = e; | |||
473 | } else { | |||
474 | cur++; | |||
475 | } | |||
476 | } | |||
477 | } | |||
478 | ||||
479 | if (end) { | |||
480 | cur = end; | |||
481 | } else if (*cur){ | |||
482 | cur++; | |||
483 | } | |||
484 | } | |||
485 | bottom: | |||
486 | free(data); | |||
487 | data = NULL((void*)0); | |||
488 | ||||
489 | if (ts->LOOPS > 0) { | |||
490 | ts->LOOPS--; | |||
491 | } | |||
492 | ||||
493 | } while (ts->LOOPS); | |||
494 | ||||
495 | return 0; | |||
496 | } | |||
497 | ||||
498 | /* For Emacs: | |||
499 | * Local Variables: | |||
500 | * mode:c | |||
501 | * indent-tabs-mode:t | |||
502 | * tab-width:4 | |||
503 | * c-basic-offset:4 | |||
504 | * End: | |||
505 | * For VIM: | |||
506 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: | |||
507 | */ |