xref: /Universal-ctags/parsers/jprop.c (revision 16a2541c0698bd8ee03c1be8172ef3191f6e695a)
1 /*
2 *
3 *   Copyright (c) 2016, Masatake YAMATO
4 *   Copyright (c) 2016, Red Hat, K.K.
5 *
6 *   This source code is released for free distribution under the terms of the
7 *   GNU General Public License version 2 or (at your option) any later version.
8 *
9 *   This module contains functions for generating tags for java properties
10 *   https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html
11 */
12 
13 #include "general.h"	/* must always come first */
14 #include "parse.h"
15 #include "read.h"
16 #include "vstring.h"
17 
18 typedef enum {
19 	K_KEY
20 } javaPropertiesKind;
21 
22 static kindDefinition JavaPropertiesKinds [] = {
23 	{ true, 'k', "key", "keys" },
24 };
25 
skipWhiteSpace(const unsigned char * line)26 static const unsigned char *skipWhiteSpace (const unsigned char *line)
27 {
28 	while (*line == ' '
29 	       || *line == '\t'
30 	       || *line == '\f')
31 		line++;
32 	return line;
33 }
34 
doesValueContinue(const unsigned char * line)35 static bool doesValueContinue (const unsigned char *line)
36 {
37 	bool in_escaping = false;
38 	while (*line != '\0')
39 	{
40 		if (in_escaping)
41 			in_escaping = false;
42 		else if (*line == '\\')
43 			in_escaping = true;
44 		line++;
45 	}
46 	return in_escaping;
47 }
48 
extractKey(const unsigned char * line,vString * key)49 static const unsigned char * extractKey (const unsigned char *line, vString *key)
50 {
51 	bool in_escaping = false;
52 
53 	while (*line != '\0')
54 	{
55 		if (in_escaping)
56 		{
57 			vStringPut (key, *line);
58 			in_escaping = false;
59 		}
60 		else if (*line == ':' || *line == '='
61 			 || *line == ' ' || *line == '\t' || *line == '\f')
62 		{
63 			line++;
64 			break;
65 		}
66 		else if (*line == '\\')
67 		{
68 			vStringPut (key, *line);
69 			in_escaping = true;
70 		}
71 		else
72 			vStringPut (key, *line);
73 		line++;
74 	}
75 	return line;
76 }
77 
findJavaPropertiesTags(void)78 static void findJavaPropertiesTags (void)
79 {
80 	const unsigned char *line;
81 	bool in_value = false;
82 	bool value_continues;
83 	static vString *key;
84 
85 	if (key == NULL)
86 		key = vStringNew ();
87 	else
88 		vStringClear (key);
89 
90 	while ((line = readLineFromInputFile ()) != NULL)
91 	{
92 		if (in_value)
93 		{
94 			value_continues = doesValueContinue (line);
95 			if (!value_continues)
96 				in_value = false;
97 			continue;
98 		}
99 
100 		line = skipWhiteSpace (line);
101 		if (*line == '\0'
102 		    || *line == '!' || *line == '#')
103 			continue;
104 
105 		line = extractKey (line, key);
106 		makeSimpleTag (key, K_KEY);
107 		vStringClear (key);
108 
109 		value_continues = doesValueContinue (line);
110 		if (value_continues)
111 			in_value = true;
112 	}
113 }
114 
115 extern parserDefinition*
JavaPropertiesParser(void)116 JavaPropertiesParser (void)
117 {
118 	static const char *const extensions [] = { "properties", NULL };
119 	parserDefinition* const def = parserNew ("JavaProperties");
120 
121 	def->kindTable = JavaPropertiesKinds;
122 	def->kindCount = ARRAY_SIZE (JavaPropertiesKinds);
123 	def->extensions = extensions;
124 	def->parser = findJavaPropertiesTags;
125 	return def;
126 }
127