1bddf5c8aSMasatake YAMATO /*
2bddf5c8aSMasatake YAMATO *
3bddf5c8aSMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
4bddf5c8aSMasatake YAMATO * Copyright (c) 2016, Red Hat, K.K.
5bddf5c8aSMasatake YAMATO *
6bddf5c8aSMasatake YAMATO * This source code is released for free distribution under the terms of the
7bddf5c8aSMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
8bddf5c8aSMasatake YAMATO *
9bddf5c8aSMasatake YAMATO */
10bddf5c8aSMasatake YAMATO
11bddf5c8aSMasatake YAMATO #include "general.h" /* must always come first */
12e24c0d0eSMasatake YAMATO #include "debug.h"
13bddf5c8aSMasatake YAMATO #include "entry.h"
14bddf5c8aSMasatake YAMATO #include "kind.h"
1587214e15SMasatake YAMATO #include "yaml.h"
16bddf5c8aSMasatake YAMATO #include "parse.h"
170051d650SMasatake YAMATO #include "subparser.h"
18bddf5c8aSMasatake YAMATO
19bddf5c8aSMasatake YAMATO #include <stdio.h>
20bddf5c8aSMasatake YAMATO
21bddf5c8aSMasatake YAMATO typedef enum {
22bddf5c8aSMasatake YAMATO K_PLAY
23bddf5c8aSMasatake YAMATO } ansiblePlaybookKind;
24bddf5c8aSMasatake YAMATO
25e112e8abSMasatake YAMATO static kindDefinition AnsiblePlaybookKinds [] = {
26bddf5c8aSMasatake YAMATO { true, 'p', "play", "plays" },
27bddf5c8aSMasatake YAMATO };
28bddf5c8aSMasatake YAMATO
29bddf5c8aSMasatake YAMATO struct yamlBlockTypeStack {
30bddf5c8aSMasatake YAMATO yaml_token_type_t type;
31e24c0d0eSMasatake YAMATO int associatedCorkIndex;
32bddf5c8aSMasatake YAMATO struct yamlBlockTypeStack *next;
33bddf5c8aSMasatake YAMATO };
34bddf5c8aSMasatake YAMATO
35bddf5c8aSMasatake YAMATO /* - name: "THE NAME" */
36bddf5c8aSMasatake YAMATO enum ansiblePlaybookPlayDetectingState {
37bddf5c8aSMasatake YAMATO DSTAT_PLAY_NAME_INITIAL,
38bddf5c8aSMasatake YAMATO DSTAT_PLAY_NAME_KEY,
39bddf5c8aSMasatake YAMATO DSTAT_PLAY_NAME_KEY_SCALAR,
40bddf5c8aSMasatake YAMATO DSTAT_PLAY_NAME_VALUE,
41bddf5c8aSMasatake YAMATO };
42bddf5c8aSMasatake YAMATO
43bddf5c8aSMasatake YAMATO
440051d650SMasatake YAMATO struct sAnsiblePlaybookSubparser {
450051d650SMasatake YAMATO yamlSubparser yaml;
46bddf5c8aSMasatake YAMATO struct yamlBlockTypeStack *type_stack;
47bddf5c8aSMasatake YAMATO enum ansiblePlaybookPlayDetectingState play_detection_state;
48bddf5c8aSMasatake YAMATO };
49bddf5c8aSMasatake YAMATO
pushBlockType(struct sAnsiblePlaybookSubparser * ansible,yaml_token_type_t t)500051d650SMasatake YAMATO static void pushBlockType (struct sAnsiblePlaybookSubparser *ansible, yaml_token_type_t t)
51bddf5c8aSMasatake YAMATO {
52bddf5c8aSMasatake YAMATO struct yamlBlockTypeStack *s;
53bddf5c8aSMasatake YAMATO
54bddf5c8aSMasatake YAMATO s = xMalloc (1, struct yamlBlockTypeStack);
55bddf5c8aSMasatake YAMATO
560051d650SMasatake YAMATO s->next = ansible->type_stack;
570051d650SMasatake YAMATO ansible->type_stack = s;
58bddf5c8aSMasatake YAMATO
59bddf5c8aSMasatake YAMATO s->type = t;
60e24c0d0eSMasatake YAMATO s->associatedCorkIndex = CORK_NIL;
61bddf5c8aSMasatake YAMATO }
62bddf5c8aSMasatake YAMATO
popBlockType(struct sAnsiblePlaybookSubparser * ansible,yaml_token_t * token)630051d650SMasatake YAMATO static void popBlockType (struct sAnsiblePlaybookSubparser *ansible,
64e24c0d0eSMasatake YAMATO yaml_token_t *token)
65bddf5c8aSMasatake YAMATO {
66bddf5c8aSMasatake YAMATO struct yamlBlockTypeStack *s;
67bddf5c8aSMasatake YAMATO
680051d650SMasatake YAMATO s = ansible->type_stack;
690051d650SMasatake YAMATO ansible->type_stack = s->next;
70bddf5c8aSMasatake YAMATO
71bddf5c8aSMasatake YAMATO s->next = NULL;
723671ad72SMasatake YAMATO tagEntryInfo *tag = getEntryInCorkQueue (s->associatedCorkIndex);
73*9b034e2aSMasatake YAMATO if (tag && token)
74e24c0d0eSMasatake YAMATO attachYamlPosition (tag, token, true);
75e24c0d0eSMasatake YAMATO
76bddf5c8aSMasatake YAMATO eFree (s);
77bddf5c8aSMasatake YAMATO }
78bddf5c8aSMasatake YAMATO
popAllBlockType(struct sAnsiblePlaybookSubparser * ansible,yaml_token_t * token)790051d650SMasatake YAMATO static void popAllBlockType (struct sAnsiblePlaybookSubparser *ansible,
80e24c0d0eSMasatake YAMATO yaml_token_t *token)
81bddf5c8aSMasatake YAMATO {
820051d650SMasatake YAMATO while (ansible->type_stack)
830051d650SMasatake YAMATO popBlockType (ansible, token);
84bddf5c8aSMasatake YAMATO }
85bddf5c8aSMasatake YAMATO
stateStackMatch(struct yamlBlockTypeStack * stack,yaml_token_type_t * expectation,unsigned int length,bool partial)86bddf5c8aSMasatake YAMATO static bool stateStackMatch (struct yamlBlockTypeStack *stack,
87bddf5c8aSMasatake YAMATO yaml_token_type_t *expectation,
88bddf5c8aSMasatake YAMATO unsigned int length,
89bddf5c8aSMasatake YAMATO bool partial)
90bddf5c8aSMasatake YAMATO {
91bddf5c8aSMasatake YAMATO if (length == 0)
92bddf5c8aSMasatake YAMATO {
93bddf5c8aSMasatake YAMATO if (stack == NULL)
94bddf5c8aSMasatake YAMATO return true;
95bddf5c8aSMasatake YAMATO else if (partial)
96bddf5c8aSMasatake YAMATO return true;
97bddf5c8aSMasatake YAMATO else
98bddf5c8aSMasatake YAMATO return false;
99bddf5c8aSMasatake YAMATO }
100bddf5c8aSMasatake YAMATO
101bddf5c8aSMasatake YAMATO if (stack == NULL)
102bddf5c8aSMasatake YAMATO return false;
103bddf5c8aSMasatake YAMATO
104bddf5c8aSMasatake YAMATO if (stack->type == expectation[0])
105bddf5c8aSMasatake YAMATO return stateStackMatch (stack->next, expectation + 1, length - 1, partial);
106bddf5c8aSMasatake YAMATO else
107bddf5c8aSMasatake YAMATO return false;
108bddf5c8aSMasatake YAMATO }
109bddf5c8aSMasatake YAMATO
scalarNeq(yaml_token_t * token,unsigned int len,const char * val)110bddf5c8aSMasatake YAMATO static bool scalarNeq (yaml_token_t *token, unsigned int len, const char* val)
111bddf5c8aSMasatake YAMATO {
112bddf5c8aSMasatake YAMATO if ((token->data.scalar.length == len)
113bddf5c8aSMasatake YAMATO && (strncmp (val, (char *)token->data.scalar.value, len) == 0))
114bddf5c8aSMasatake YAMATO return true;
115bddf5c8aSMasatake YAMATO else
116bddf5c8aSMasatake YAMATO return false;
117bddf5c8aSMasatake YAMATO }
118bddf5c8aSMasatake YAMATO
ansiblePlaybookPlayStateMachine(struct sAnsiblePlaybookSubparser * ansible,yaml_token_t * token)1190051d650SMasatake YAMATO static void ansiblePlaybookPlayStateMachine (struct sAnsiblePlaybookSubparser *ansible,
120bddf5c8aSMasatake YAMATO yaml_token_t *token)
121bddf5c8aSMasatake YAMATO {
122bddf5c8aSMasatake YAMATO yaml_token_type_t play_expect[] = {
123bddf5c8aSMasatake YAMATO YAML_BLOCK_MAPPING_START_TOKEN,
124bddf5c8aSMasatake YAMATO YAML_BLOCK_SEQUENCE_START_TOKEN,
125bddf5c8aSMasatake YAMATO };
126bddf5c8aSMasatake YAMATO
127bddf5c8aSMasatake YAMATO switch (token->type)
128bddf5c8aSMasatake YAMATO {
129bddf5c8aSMasatake YAMATO case YAML_KEY_TOKEN:
1300051d650SMasatake YAMATO if (stateStackMatch (ansible->type_stack,
131bddf5c8aSMasatake YAMATO play_expect, ARRAY_SIZE (play_expect),
132bddf5c8aSMasatake YAMATO false))
1330051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_KEY;
134bddf5c8aSMasatake YAMATO else
1350051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
136bddf5c8aSMasatake YAMATO break;
137bddf5c8aSMasatake YAMATO case YAML_SCALAR_TOKEN:
1380051d650SMasatake YAMATO if ((ansible->play_detection_state == DSTAT_PLAY_NAME_KEY)
139bddf5c8aSMasatake YAMATO && scalarNeq (token, 4, "name"))
1400051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_KEY_SCALAR;
1410051d650SMasatake YAMATO else if (ansible->play_detection_state == DSTAT_PLAY_NAME_VALUE)
142bddf5c8aSMasatake YAMATO {
143bddf5c8aSMasatake YAMATO tagEntryInfo tag;
144bddf5c8aSMasatake YAMATO initTagEntry (&tag, (char *)token->data.scalar.value,
14516a2541cSMasatake YAMATO K_PLAY);
146f3fffd78SMasatake YAMATO attachYamlPosition (&tag, token, false);
147e24c0d0eSMasatake YAMATO
1480051d650SMasatake YAMATO Assert (ansible->type_stack->associatedCorkIndex == CORK_NIL);
1490051d650SMasatake YAMATO ansible->type_stack->associatedCorkIndex = makeTagEntry (&tag);
1500051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
151bddf5c8aSMasatake YAMATO }
152bddf5c8aSMasatake YAMATO else
1530051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
154bddf5c8aSMasatake YAMATO break;
155bddf5c8aSMasatake YAMATO case YAML_VALUE_TOKEN:
1560051d650SMasatake YAMATO if (ansible->play_detection_state == DSTAT_PLAY_NAME_KEY_SCALAR)
1570051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_VALUE;
158bddf5c8aSMasatake YAMATO else
1590051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
160bddf5c8aSMasatake YAMATO break;
161bddf5c8aSMasatake YAMATO default:
1620051d650SMasatake YAMATO ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
163bddf5c8aSMasatake YAMATO break;
164bddf5c8aSMasatake YAMATO }
165bddf5c8aSMasatake YAMATO }
166bddf5c8aSMasatake YAMATO
newTokenCallback(yamlSubparser * s,yaml_token_t * token)1670051d650SMasatake YAMATO static void newTokenCallback (yamlSubparser *s, yaml_token_t *token)
168bddf5c8aSMasatake YAMATO {
169bddf5c8aSMasatake YAMATO if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN
170bddf5c8aSMasatake YAMATO || token->type == YAML_BLOCK_MAPPING_START_TOKEN)
1710051d650SMasatake YAMATO pushBlockType ((struct sAnsiblePlaybookSubparser *)s, token->type);
172bddf5c8aSMasatake YAMATO
1730051d650SMasatake YAMATO ansiblePlaybookPlayStateMachine ((struct sAnsiblePlaybookSubparser *)s, token);
174bddf5c8aSMasatake YAMATO
175bddf5c8aSMasatake YAMATO if (token->type == YAML_BLOCK_END_TOKEN)
1760051d650SMasatake YAMATO popBlockType ((struct sAnsiblePlaybookSubparser *)s, token);
177e24c0d0eSMasatake YAMATO else if (token->type == YAML_STREAM_END_TOKEN)
1780051d650SMasatake YAMATO popAllBlockType ((struct sAnsiblePlaybookSubparser *)s, token);
179bddf5c8aSMasatake YAMATO }
180bddf5c8aSMasatake YAMATO
inputStart(subparser * s)1810051d650SMasatake YAMATO static void inputStart(subparser *s)
182bddf5c8aSMasatake YAMATO {
1830051d650SMasatake YAMATO ((struct sAnsiblePlaybookSubparser*)s)->play_detection_state = DSTAT_PLAY_NAME_INITIAL;
1840051d650SMasatake YAMATO ((struct sAnsiblePlaybookSubparser*)s)->type_stack = NULL;
185bddf5c8aSMasatake YAMATO }
186bddf5c8aSMasatake YAMATO
inputEnd(subparser * s)1870051d650SMasatake YAMATO static void inputEnd(subparser *s)
18889070b4aSMasatake YAMATO {
189*9b034e2aSMasatake YAMATO popAllBlockType ((struct sAnsiblePlaybookSubparser *)s, NULL);
1900051d650SMasatake YAMATO Assert (((struct sAnsiblePlaybookSubparser*)s)->type_stack == NULL);
19189070b4aSMasatake YAMATO }
19289070b4aSMasatake YAMATO
193bddf5c8aSMasatake YAMATO static void
findAnsiblePlaybookTags(void)194bddf5c8aSMasatake YAMATO findAnsiblePlaybookTags (void)
195bddf5c8aSMasatake YAMATO {
1960051d650SMasatake YAMATO scheduleRunningBaseparser (0);
197bddf5c8aSMasatake YAMATO }
198bddf5c8aSMasatake YAMATO
AnsiblePlaybookParser(void)199bddf5c8aSMasatake YAMATO extern parserDefinition* AnsiblePlaybookParser (void)
200bddf5c8aSMasatake YAMATO {
2010051d650SMasatake YAMATO static struct sAnsiblePlaybookSubparser ansiblePlaybookSubparser = {
2020051d650SMasatake YAMATO .yaml = {
2030051d650SMasatake YAMATO .subparser = {
2040051d650SMasatake YAMATO .direction = SUBPARSER_BI_DIRECTION,
2050051d650SMasatake YAMATO .inputStart = inputStart,
2060051d650SMasatake YAMATO .inputEnd = inputEnd,
2070051d650SMasatake YAMATO },
2080051d650SMasatake YAMATO .newTokenNotfify = newTokenCallback
2090051d650SMasatake YAMATO },
2100051d650SMasatake YAMATO };
2110051d650SMasatake YAMATO static parserDependency dependencies [] = {
2120051d650SMasatake YAMATO { DEPTYPE_SUBPARSER, "Yaml", &ansiblePlaybookSubparser },
2130051d650SMasatake YAMATO };
2140051d650SMasatake YAMATO
215bddf5c8aSMasatake YAMATO parserDefinition* const def = parserNew ("AnsiblePlaybook");
216bddf5c8aSMasatake YAMATO
217bddf5c8aSMasatake YAMATO
218bddf5c8aSMasatake YAMATO def->dependencies = dependencies;
219bddf5c8aSMasatake YAMATO def->dependencyCount = ARRAY_SIZE (dependencies);
220bddf5c8aSMasatake YAMATO
22109ae690fSMasatake YAMATO def->kindTable = AnsiblePlaybookKinds;
222bddf5c8aSMasatake YAMATO def->kindCount = ARRAY_SIZE (AnsiblePlaybookKinds);
223bddf5c8aSMasatake YAMATO def->parser = findAnsiblePlaybookTags;
2246b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
225bddf5c8aSMasatake YAMATO return def;
226bddf5c8aSMasatake YAMATO }
227bddf5c8aSMasatake YAMATO
228bddf5c8aSMasatake YAMATO /* vi:set tabstop=4 shiftwidth=4: */
229