14fa68e36SMasatake YAMATO /*
24fa68e36SMasatake YAMATO *
34fa68e36SMasatake YAMATO * Copyright (c) 2016, Red Hat, Inc.
44fa68e36SMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
54fa68e36SMasatake YAMATO *
64fa68e36SMasatake YAMATO * Author: Masatake YAMATO <yamato@redhat.com>
74fa68e36SMasatake YAMATO *
84fa68e36SMasatake YAMATO * This source code is released for free distribution under the terms of the
94fa68e36SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
104fa68e36SMasatake YAMATO *
114fa68e36SMasatake YAMATO */
124fa68e36SMasatake YAMATO
134fa68e36SMasatake YAMATO #include "general.h"
140d502ef0SMasatake YAMATO #include "parse_p.h"
154fa68e36SMasatake YAMATO #include "promise.h"
166014fe81SColomban Wendling #include "promise_p.h"
1711e58e48SMasatake YAMATO #include "ptrarray.h"
184fa68e36SMasatake YAMATO #include "debug.h"
19b5df137eSMasatake YAMATO #include "read_p.h"
20be62b73fSMasatake YAMATO #include "trashbox.h"
21090d5581SMasatake YAMATO #include "xtag.h"
22db20bea4SMasatake YAMATO #include "numarray.h"
2329e40fb6SMasatake YAMATO #include "routines.h"
24*5066e2feSMasatake YAMATO #include "options.h"
254fa68e36SMasatake YAMATO
26db20bea4SMasatake YAMATO #include <string.h>
274fa68e36SMasatake YAMATO
284fa68e36SMasatake YAMATO struct promise {
294fa68e36SMasatake YAMATO langType lang;
304fa68e36SMasatake YAMATO unsigned long startLine;
31ef722b09SMasatake YAMATO long startCharOffset;
324fa68e36SMasatake YAMATO unsigned long endLine;
33ef722b09SMasatake YAMATO long endCharOffset;
344fa68e36SMasatake YAMATO unsigned long sourceLineOffset;
35631d6aa6SMasatake YAMATO int parent_promise;
3611e58e48SMasatake YAMATO ptrArray *modifiers;
3711e58e48SMasatake YAMATO };
3811e58e48SMasatake YAMATO
3911e58e48SMasatake YAMATO typedef void ( *promiseInputModifier) (unsigned char * input,
4011e58e48SMasatake YAMATO size_t size,
4111e58e48SMasatake YAMATO unsigned long startLine, long startCharOffset,
4211e58e48SMasatake YAMATO unsigned long endLine, long endCharOffset,
4311e58e48SMasatake YAMATO void *data);
4411e58e48SMasatake YAMATO typedef void ( *promiseDestroyAttachedData) (void *data);
4511e58e48SMasatake YAMATO
4611e58e48SMasatake YAMATO struct modifier {
4711e58e48SMasatake YAMATO promiseInputModifier modifier;
4811e58e48SMasatake YAMATO promiseDestroyAttachedData destroyData;
4911e58e48SMasatake YAMATO void *data;
504fa68e36SMasatake YAMATO };
514fa68e36SMasatake YAMATO
524fa68e36SMasatake YAMATO static struct promise *promises;
534fa68e36SMasatake YAMATO static int promise_count;
544fa68e36SMasatake YAMATO static int promise_allocated;
554fa68e36SMasatake YAMATO
56631d6aa6SMasatake YAMATO #define NO_PROMISE -1
57631d6aa6SMasatake YAMATO static int current_promise = NO_PROMISE;
58631d6aa6SMasatake YAMATO
5911e58e48SMasatake YAMATO static void attachPromiseModifier (int promise,
6011e58e48SMasatake YAMATO promiseInputModifier modifier,
6111e58e48SMasatake YAMATO promiseDestroyAttachedData destroyData,
6211e58e48SMasatake YAMATO void *data);
6311e58e48SMasatake YAMATO
6411e58e48SMasatake YAMATO
makePromise(const char * parser,unsigned long startLine,long startCharOffset,unsigned long endLine,long endCharOffset,unsigned long sourceLineOffset)654fa68e36SMasatake YAMATO int makePromise (const char *parser,
66ef722b09SMasatake YAMATO unsigned long startLine, long startCharOffset,
67ef722b09SMasatake YAMATO unsigned long endLine, long endCharOffset,
684fa68e36SMasatake YAMATO unsigned long sourceLineOffset)
694fa68e36SMasatake YAMATO {
704fa68e36SMasatake YAMATO struct promise *p;
714fa68e36SMasatake YAMATO int r;
7289a71f3bSMasatake YAMATO langType lang = LANG_IGNORE;
734fa68e36SMasatake YAMATO
74*5066e2feSMasatake YAMATO verbose("makePromise: %s start(line: %lu, offset: %lu, srcline: %lu), end(line: %lu, offset: %lu)\n",
75*5066e2feSMasatake YAMATO parser? parser: "*", startLine, startCharOffset, sourceLineOffset,
76*5066e2feSMasatake YAMATO endLine, endCharOffset);
77*5066e2feSMasatake YAMATO
782fa69c1bSMasatake YAMATO if ((!isThinStreamSpec(startLine,
792fa69c1bSMasatake YAMATO startCharOffset,
802fa69c1bSMasatake YAMATO endLine,
812fa69c1bSMasatake YAMATO endCharOffset,
822fa69c1bSMasatake YAMATO sourceLineOffset))
8346a698ceSMasatake YAMATO && ( !isXtagEnabled (XTAG_GUEST)))
84090d5581SMasatake YAMATO return -1;
85090d5581SMasatake YAMATO
8689a71f3bSMasatake YAMATO if (parser)
8789a71f3bSMasatake YAMATO {
884fa68e36SMasatake YAMATO lang = getNamedLanguage (parser, 0);
894fa68e36SMasatake YAMATO if (lang == LANG_IGNORE)
904fa68e36SMasatake YAMATO return -1;
9189a71f3bSMasatake YAMATO }
924fa68e36SMasatake YAMATO
934fa68e36SMasatake YAMATO if ( promise_count == promise_allocated)
944fa68e36SMasatake YAMATO {
954fa68e36SMasatake YAMATO size_t c = promise_allocated? (promise_allocated * 2): 8;
96be62b73fSMasatake YAMATO if (promises)
97be62b73fSMasatake YAMATO DEFAULT_TRASH_BOX_TAKE_BACK(promises);
984fa68e36SMasatake YAMATO promises = xRealloc (promises, c, struct promise);
99be62b73fSMasatake YAMATO DEFAULT_TRASH_BOX(promises, eFree);
1004fa68e36SMasatake YAMATO promise_allocated = c;
1014fa68e36SMasatake YAMATO }
1024fa68e36SMasatake YAMATO
1034fa68e36SMasatake YAMATO p = promises + promise_count;
104631d6aa6SMasatake YAMATO p->parent_promise = current_promise;
1054fa68e36SMasatake YAMATO p->lang = lang;
1064fa68e36SMasatake YAMATO p->startLine = startLine;
1074fa68e36SMasatake YAMATO p->startCharOffset = startCharOffset;
1084fa68e36SMasatake YAMATO p->endLine = endLine;
1094fa68e36SMasatake YAMATO p->endCharOffset = endCharOffset;
1104fa68e36SMasatake YAMATO p->sourceLineOffset = sourceLineOffset;
11111e58e48SMasatake YAMATO p->modifiers = NULL;
1124fa68e36SMasatake YAMATO
1134fa68e36SMasatake YAMATO r = promise_count;
1144fa68e36SMasatake YAMATO promise_count++;
1154fa68e36SMasatake YAMATO return r;
1164fa68e36SMasatake YAMATO }
1174fa68e36SMasatake YAMATO
freeModifier(void * data)11811e58e48SMasatake YAMATO static void freeModifier (void *data)
11911e58e48SMasatake YAMATO {
12011e58e48SMasatake YAMATO struct modifier *m = data;
12111e58e48SMasatake YAMATO m->destroyData(m->data);
12211e58e48SMasatake YAMATO eFree (m);
12311e58e48SMasatake YAMATO }
12411e58e48SMasatake YAMATO
attachPromiseModifier(int promise,promiseInputModifier modifier,promiseDestroyAttachedData destroyData,void * data)12511e58e48SMasatake YAMATO static void attachPromiseModifier (int promise,
12611e58e48SMasatake YAMATO promiseInputModifier modifier,
12711e58e48SMasatake YAMATO promiseDestroyAttachedData destroyData,
12811e58e48SMasatake YAMATO void *data)
12911e58e48SMasatake YAMATO {
13011e58e48SMasatake YAMATO struct modifier *m = xMalloc (1, struct modifier);
13111e58e48SMasatake YAMATO
13211e58e48SMasatake YAMATO m->modifier = modifier;
13311e58e48SMasatake YAMATO m->destroyData = destroyData;
13411e58e48SMasatake YAMATO m->data = data;
13511e58e48SMasatake YAMATO
13611e58e48SMasatake YAMATO struct promise *p = promises + promise;
13711e58e48SMasatake YAMATO if (!p->modifiers)
13811e58e48SMasatake YAMATO p->modifiers = ptrArrayNew(freeModifier);
13911e58e48SMasatake YAMATO
14011e58e48SMasatake YAMATO ptrArrayAdd (p->modifiers, m);
14111e58e48SMasatake YAMATO }
14211e58e48SMasatake YAMATO
freeModifiers(int promise)14311e58e48SMasatake YAMATO static void freeModifiers(int promise)
14411e58e48SMasatake YAMATO {
14511e58e48SMasatake YAMATO for (int i = promise; i < promise_count; i++)
14611e58e48SMasatake YAMATO {
14711e58e48SMasatake YAMATO struct promise *p = promises + promise;
14811e58e48SMasatake YAMATO if (p->modifiers)
14911e58e48SMasatake YAMATO {
15011e58e48SMasatake YAMATO ptrArrayDelete (p->modifiers);
15111e58e48SMasatake YAMATO p->modifiers = NULL;
15211e58e48SMasatake YAMATO }
15311e58e48SMasatake YAMATO }
15411e58e48SMasatake YAMATO }
15511e58e48SMasatake YAMATO
breakPromisesAfter(int promise)1564fa68e36SMasatake YAMATO void breakPromisesAfter (int promise)
1574fa68e36SMasatake YAMATO {
1584fa68e36SMasatake YAMATO Assert (promise_count >= promise);
15911e58e48SMasatake YAMATO if (promise == NO_PROMISE)
16011e58e48SMasatake YAMATO promise = 0;
1614fa68e36SMasatake YAMATO
16211e58e48SMasatake YAMATO freeModifiers(promise);
1634fa68e36SMasatake YAMATO promise_count = promise;
1644fa68e36SMasatake YAMATO }
1654fa68e36SMasatake YAMATO
forcePromises(void)166ce990805SThomas Braun bool forcePromises (void)
1674fa68e36SMasatake YAMATO {
1684fa68e36SMasatake YAMATO int i;
169ce990805SThomas Braun bool tagFileResized = false;
170090d5581SMasatake YAMATO
1714fa68e36SMasatake YAMATO for (i = 0; i < promise_count; ++i)
1724fa68e36SMasatake YAMATO {
173631d6aa6SMasatake YAMATO current_promise = i;
1744fa68e36SMasatake YAMATO struct promise *p = promises + i;
17589a71f3bSMasatake YAMATO
17689a71f3bSMasatake YAMATO if (p->lang != LANG_IGNORE && isLanguageEnabled (p->lang))
1774fa68e36SMasatake YAMATO tagFileResized = runParserInNarrowedInputStream (p->lang,
1784fa68e36SMasatake YAMATO p->startLine,
1794fa68e36SMasatake YAMATO p->startCharOffset,
1804fa68e36SMasatake YAMATO p->endLine,
1814fa68e36SMasatake YAMATO p->endCharOffset,
18211e58e48SMasatake YAMATO p->sourceLineOffset,
18311e58e48SMasatake YAMATO i)
184ce990805SThomas Braun ? true
1854fa68e36SMasatake YAMATO : tagFileResized;
1864fa68e36SMasatake YAMATO }
1874fa68e36SMasatake YAMATO
18811e58e48SMasatake YAMATO freeModifiers (0);
189631d6aa6SMasatake YAMATO current_promise = NO_PROMISE;
1904fa68e36SMasatake YAMATO promise_count = 0;
1914fa68e36SMasatake YAMATO return tagFileResized;
1924fa68e36SMasatake YAMATO }
1934fa68e36SMasatake YAMATO
1944fa68e36SMasatake YAMATO
getLastPromise(void)1954fa68e36SMasatake YAMATO int getLastPromise (void)
1964fa68e36SMasatake YAMATO {
1974fa68e36SMasatake YAMATO return promise_count - 1;
1984fa68e36SMasatake YAMATO }
19911e58e48SMasatake YAMATO
fill_or_skip(unsigned char * input,unsigned char * input_end,bool filling)200db20bea4SMasatake YAMATO static unsigned char* fill_or_skip (unsigned char *input, unsigned char *input_end, bool filling)
201db20bea4SMasatake YAMATO {
202db20bea4SMasatake YAMATO if ( !(input < input_end))
203db20bea4SMasatake YAMATO return NULL;
204db20bea4SMasatake YAMATO
205db20bea4SMasatake YAMATO unsigned char *next = memchr(input, '\n', input_end - input);
206db20bea4SMasatake YAMATO if (next)
207db20bea4SMasatake YAMATO {
208db20bea4SMasatake YAMATO if (filling)
209db20bea4SMasatake YAMATO memset(input, ' ', next - input);
210db20bea4SMasatake YAMATO input = next + 1;
211db20bea4SMasatake YAMATO if (input == input_end)
212db20bea4SMasatake YAMATO return NULL;
213db20bea4SMasatake YAMATO else
214db20bea4SMasatake YAMATO return input;
215db20bea4SMasatake YAMATO }
216db20bea4SMasatake YAMATO else
217db20bea4SMasatake YAMATO {
218db20bea4SMasatake YAMATO if (filling)
219db20bea4SMasatake YAMATO memset(input, ' ', input_end - input);
220db20bea4SMasatake YAMATO return NULL;
221db20bea4SMasatake YAMATO }
222db20bea4SMasatake YAMATO }
223db20bea4SMasatake YAMATO
line_filler(unsigned char * input,size_t size,unsigned long startLine,long startCharOffset,unsigned long endLine,long endCharOffset,void * data)224db20bea4SMasatake YAMATO static void line_filler (unsigned char *input, size_t size,
225db20bea4SMasatake YAMATO unsigned long startLine, long startCharOffset,
226db20bea4SMasatake YAMATO unsigned long endLine, long endCharOffset,
227db20bea4SMasatake YAMATO void *data)
228db20bea4SMasatake YAMATO {
229db20bea4SMasatake YAMATO ulongArray *lines = data;
230db20bea4SMasatake YAMATO unsigned int start_index, end_index;
2314c64e833SMasatake YAMATO unsigned int i;
232db20bea4SMasatake YAMATO
233db20bea4SMasatake YAMATO for (i = 0; i < ulongArrayCount (lines); i++)
234db20bea4SMasatake YAMATO {
235db20bea4SMasatake YAMATO unsigned long line = ulongArrayItem (lines, i);
236db20bea4SMasatake YAMATO if (line >= startLine)
237db20bea4SMasatake YAMATO break;
238db20bea4SMasatake YAMATO }
239db20bea4SMasatake YAMATO if (i == ulongArrayCount (lines))
240db20bea4SMasatake YAMATO return;
241db20bea4SMasatake YAMATO if (i > endLine)
242db20bea4SMasatake YAMATO return;
243db20bea4SMasatake YAMATO start_index = i;
244db20bea4SMasatake YAMATO
245db20bea4SMasatake YAMATO for (; i < ulongArrayCount (lines); i++)
246db20bea4SMasatake YAMATO {
247db20bea4SMasatake YAMATO unsigned long line = ulongArrayItem (lines, i);
248db20bea4SMasatake YAMATO if (line > endLine)
249db20bea4SMasatake YAMATO break;
250db20bea4SMasatake YAMATO }
251db20bea4SMasatake YAMATO end_index = i;
252db20bea4SMasatake YAMATO
253db20bea4SMasatake YAMATO unsigned long input_line = startLine;
254db20bea4SMasatake YAMATO for (i = start_index; i < end_index; i++)
255db20bea4SMasatake YAMATO {
256db20bea4SMasatake YAMATO unsigned long line = ulongArrayItem (lines, i);
257db20bea4SMasatake YAMATO
258db20bea4SMasatake YAMATO while (1)
259db20bea4SMasatake YAMATO {
260db20bea4SMasatake YAMATO if (input_line == line)
261db20bea4SMasatake YAMATO {
262db20bea4SMasatake YAMATO input = fill_or_skip (input, input + size, true);
263db20bea4SMasatake YAMATO input_line++;
264db20bea4SMasatake YAMATO break;
265db20bea4SMasatake YAMATO }
266db20bea4SMasatake YAMATO else
267db20bea4SMasatake YAMATO {
268db20bea4SMasatake YAMATO input = fill_or_skip (input, input + size, false);
269db20bea4SMasatake YAMATO input_line++;
270db20bea4SMasatake YAMATO }
271db20bea4SMasatake YAMATO }
272db20bea4SMasatake YAMATO }
273db20bea4SMasatake YAMATO }
274db20bea4SMasatake YAMATO
promiseAttachLineFiller(int promise,ulongArray * lines)275db20bea4SMasatake YAMATO void promiseAttachLineFiller (int promise, ulongArray *lines)
276db20bea4SMasatake YAMATO {
277db20bea4SMasatake YAMATO attachPromiseModifier (promise, line_filler,
278db20bea4SMasatake YAMATO (promiseDestroyAttachedData)ulongArrayDelete,
279db20bea4SMasatake YAMATO lines);
280db20bea4SMasatake YAMATO }
281db20bea4SMasatake YAMATO
282db20bea4SMasatake YAMATO
collectModifiers(int promise,ptrArray * modifiers)28311e58e48SMasatake YAMATO static void collectModifiers(int promise, ptrArray *modifiers)
28411e58e48SMasatake YAMATO {
28511e58e48SMasatake YAMATO while (promise != NO_PROMISE)
28611e58e48SMasatake YAMATO {
28711e58e48SMasatake YAMATO struct promise *p = promises + promise;
28811e58e48SMasatake YAMATO if (p->modifiers)
28911e58e48SMasatake YAMATO {
29011e58e48SMasatake YAMATO for (int i = ptrArrayCount(p->modifiers); i > 0; i--)
29111e58e48SMasatake YAMATO {
29211e58e48SMasatake YAMATO struct modifier *m = ptrArrayItem(p->modifiers, i - 1);
29311e58e48SMasatake YAMATO ptrArrayAdd (modifiers, m);
29411e58e48SMasatake YAMATO }
29511e58e48SMasatake YAMATO }
29611e58e48SMasatake YAMATO promise = p->parent_promise;
29711e58e48SMasatake YAMATO }
29811e58e48SMasatake YAMATO }
29911e58e48SMasatake YAMATO
runModifiers(int promise,unsigned long startLine,long startCharOffset,unsigned long endLine,long endCharOffset,unsigned char * input,size_t size)30011e58e48SMasatake YAMATO void runModifiers (int promise,
30111e58e48SMasatake YAMATO unsigned long startLine, long startCharOffset,
30211e58e48SMasatake YAMATO unsigned long endLine, long endCharOffset,
30311e58e48SMasatake YAMATO unsigned char *input,
30411e58e48SMasatake YAMATO size_t size)
30511e58e48SMasatake YAMATO {
30611e58e48SMasatake YAMATO ptrArray *modifiers = ptrArrayNew (NULL);
30711e58e48SMasatake YAMATO
30811e58e48SMasatake YAMATO collectModifiers (promise, modifiers);
30911e58e48SMasatake YAMATO for (int i = ptrArrayCount (modifiers); i > 0 ; i--)
31011e58e48SMasatake YAMATO {
31111e58e48SMasatake YAMATO struct modifier *m = ptrArrayItem (modifiers, i - 1);
31211e58e48SMasatake YAMATO m->modifier (input, size,
31311e58e48SMasatake YAMATO startLine, startCharOffset,
31411e58e48SMasatake YAMATO endLine, endCharOffset,
31511e58e48SMasatake YAMATO m->data);
31611e58e48SMasatake YAMATO }
31711e58e48SMasatake YAMATO ptrArrayDelete (modifiers);
31811e58e48SMasatake YAMATO }
31989a71f3bSMasatake YAMATO
promiseUpdateLanguage(int promise,langType lang)32089a71f3bSMasatake YAMATO void promiseUpdateLanguage (int promise, langType lang)
32189a71f3bSMasatake YAMATO {
32289a71f3bSMasatake YAMATO Assert (promise >= 0);
32389a71f3bSMasatake YAMATO
32489a71f3bSMasatake YAMATO struct promise *p = promises + promise;
32589a71f3bSMasatake YAMATO
32689a71f3bSMasatake YAMATO p->lang = lang;
32789a71f3bSMasatake YAMATO }
328