xref: /Universal-ctags/parsers/pythonloggingconfig.c (revision 6b1a862e526d5017f9f212a321f59d67c859d521)
1 /*
2  *   pythonLoggingConfig.c
3  *
4  *   Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>
5  *   Copyright (c) 2016, Red Hat, K.K.
6  *
7  *   This source code is released for free distribution under the terms of the
8  *   GNU General Public License version 2 or (at your option) any later version.
9  *
10  *   This module contains functions for generating tags for config files of
11  *   python's logging.config module.
12  *
13  *   https://docs.python.org/2/library/logging.config.html
14  *
15  */
16 
17 /*
18 *   INCLUDE FILES
19 */
20 #include "general.h"  /* must always come first */
21 
22 #include "entry.h"
23 #include "iniconf.h"
24 #include "kind.h"
25 #include "parse.h"
26 #include "read.h"
27 #include "routines.h"
28 #include <string.h>
29 
30 /*
31 *   DATA DEFINITIONS
32 */
33 typedef enum {
34 	K_LOGGER_SECTION,
35 	K_LOGGER_QUALNAME,
36 } pythonLoggingConfigKind;
37 
38 static kindDefinition PythonLoggingConfigKinds [] = {
39 	{ true, 'L', "loggerSection", "logger sections" },
40 	{ true, 'q', "qualname",      "logger qualnames" },
41 };
42 
43 #define LOGGER_PREFIX "logger_"
44 #define LOGGER_LEN (sizeof("logger_") - 1)
45 
46 struct sPythonLoggingConfigSubparser {
47 	iniconfSubparser iniconf;
48 	int index;
49 };
50 
newDataCallback(iniconfSubparser * iniconf,const char * section,const char * key,const char * value)51 static void newDataCallback (iniconfSubparser *iniconf,
52 							 const char *section, const char *key, const char *value)
53 {
54 	tagEntryInfo e;
55 
56 	if (section && (strncmp (LOGGER_PREFIX, section, LOGGER_LEN) == 0))
57 	{
58 		if (key == NULL && value == NULL)
59 		{
60 			const char *logger = section + LOGGER_LEN;
61 			if (logger [0] == '\0')
62 				goto out;
63 
64 			initTagEntry (&e, logger, K_LOGGER_SECTION);
65 			((struct sPythonLoggingConfigSubparser *)iniconf)->index = makeTagEntry (&e);
66 		}
67 		else if (key && (strcmp (key, "qualname") == 0)
68 			 && value && value[0] != '\0')
69 		{
70 			initTagEntry (&e, value, K_LOGGER_QUALNAME);
71 			e.extensionFields.scopeIndex = ((struct sPythonLoggingConfigSubparser*)iniconf)->index;
72 			makeTagEntry (&e);
73 		}
74 	}
75 
76 out:
77 	return;
78 }
79 
probeLanguage(const char * section,const char * key CTAGS_ATTR_UNUSED,const char * value CTAGS_ATTR_UNUSED)80 static bool probeLanguage (const char *section, const char *key CTAGS_ATTR_UNUSED, const char *value CTAGS_ATTR_UNUSED)
81 {
82 	if (section && (strncmp (LOGGER_PREFIX, section, LOGGER_LEN) == 0))
83 		return true;
84 	else
85 		return false;
86 }
87 
88 
exclusiveSubparserChosenCallback(subparser * s,void * data CTAGS_ATTR_UNUSED)89 static void exclusiveSubparserChosenCallback (subparser *s, void *data CTAGS_ATTR_UNUSED)
90 {
91 	((struct sPythonLoggingConfigSubparser *)s)->index = CORK_NIL;
92 }
93 
findPythonLoggingConfigTags(void)94 static void findPythonLoggingConfigTags (void)
95 {
96 	scheduleRunningBaseparser (0);
97 }
98 
PythonLoggingConfigParser(void)99 extern parserDefinition* PythonLoggingConfigParser (void)
100 {
101 	static struct sPythonLoggingConfigSubparser pythonLoggingConfigSubparser = {
102 		.iniconf = {
103 			.subparser = {
104 				.direction = SUBPARSER_BI_DIRECTION,
105 				.exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,
106 			},
107 			.probeLanguage = probeLanguage,
108 			.newDataNotify = newDataCallback,
109 		},
110 	};
111 	static parserDependency dependencies [] = {
112 		[0] = { DEPTYPE_SUBPARSER, "Iniconf", &pythonLoggingConfigSubparser },
113 	};
114 
115 	parserDefinition* const def = parserNew ("PythonLoggingConfig");
116 	def->dependencies = dependencies;
117 	def->dependencyCount = ARRAY_SIZE (dependencies);
118 
119 	def->kindTable      = PythonLoggingConfigKinds;
120 	def->kindCount  = ARRAY_SIZE (PythonLoggingConfigKinds);
121 	def->parser     = findPythonLoggingConfigTags;
122 	def->useCork    = CORK_QUEUE;
123 
124 	return def;
125 }
126