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