inih 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ddb0233107d7ad4ce1121c75fd29a94de7d5dc42
4
+ data.tar.gz: 42fc11b4b2f16e971e61c189b45ecf652ae71ffb
5
+ SHA512:
6
+ metadata.gz: 4727253857a6bdc0472b47792631ded48e2a125bfc0acfeb649b19f7869d92e4f02dded4f215e32d9dd8a307ecd29bd5c83c211ec6c404cc902f59afb7c00824
7
+ data.tar.gz: fcd4cd91b83fb9316a0366818c653e5f3c867f144ebb6c34761a7b904751c32f85251861c4f9f5e280affcdc523e76a6f06aebc053c15e9c4f9cde59ec906dfb
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private --markup-provider=redcarpet --markup=markdown - README.md LICENSE ext/inih/LICENSE
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 William Woodruff <william @ yossarian.net>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ ruby-inih
2
+ =========
3
+
4
+ A Ruby wrapper for [inih](https://github.com/benhoyt/inih), a simple INI parser.
5
+
6
+ ### Installation
7
+
8
+ ```ruby
9
+ $ gem install inih
10
+ ```
11
+
12
+ ### Example
13
+
14
+ Given the following INI data:
15
+
16
+ ```ini
17
+ ; example.ini
18
+ [example]
19
+ foo=bar
20
+ baz = quux
21
+ integer = 10
22
+ float = 3.14
23
+ bool = true
24
+ ```
25
+
26
+ ```ruby
27
+ # load directly from a file
28
+ INIH.load "example.ini"
29
+ # => {"example"=>{"foo"=>"bar", "baz"=>"quux", "integer"=>10, "float"=>3.14, "bool"=>true}}
30
+
31
+ # parse from a string
32
+ INIH.parse "[section]\nkey=value"
33
+ #=> {"section"=>{"key"=>"value"}}
34
+ ```
35
+
36
+ Integers, floating-point numbers, and booleans are coerced into their respective Ruby types.
37
+
38
+ ### TODO
39
+
40
+ * Unit tests
41
+ * Coerce scientific-notation?
42
+
43
+ ### License
44
+
45
+ inih itself is licensed under the BSD License.
46
+
47
+ For the exact terms, see the [LICENSE](ext/inih/LICENSE) file.
48
+
49
+ ruby-inih is licensed under the MIT License.
50
+
51
+ For the exact terms, see the [LICENSE](./LICENSE) file.
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+
5
+ $CFLAGS << " -DINI_MAX_LINE=1024 "
6
+
7
+ create_makefile "ext/inih"
data/ext/inih/ini.c ADDED
@@ -0,0 +1,244 @@
1
+ /* inih -- simple .INI file parser
2
+
3
+ inih is released under the New BSD license (see LICENSE.txt). Go to the project
4
+ home page for more info:
5
+
6
+ https://github.com/benhoyt/inih
7
+
8
+ */
9
+
10
+ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
11
+ #define _CRT_SECURE_NO_WARNINGS
12
+ #endif
13
+
14
+ #include <stdio.h>
15
+ #include <ctype.h>
16
+ #include <string.h>
17
+
18
+ #include "ini.h"
19
+
20
+ #if !INI_USE_STACK
21
+ #include <stdlib.h>
22
+ #endif
23
+
24
+ #define MAX_SECTION 50
25
+ #define MAX_NAME 50
26
+
27
+ /* Used by ini_parse_string() to keep track of string parsing state. */
28
+ typedef struct {
29
+ const char* ptr;
30
+ size_t num_left;
31
+ } ini_parse_string_ctx;
32
+
33
+ /* Strip whitespace chars off end of given string, in place. Return s. */
34
+ static char* rstrip(char* s)
35
+ {
36
+ char* p = s + strlen(s);
37
+ while (p > s && isspace((unsigned char)(*--p)))
38
+ *p = '\0';
39
+ return s;
40
+ }
41
+
42
+ /* Return pointer to first non-whitespace char in given string. */
43
+ static char* lskip(const char* s)
44
+ {
45
+ while (*s && isspace((unsigned char)(*s)))
46
+ s++;
47
+ return (char*)s;
48
+ }
49
+
50
+ /* Return pointer to first char (of chars) or inline comment in given string,
51
+ or pointer to null at end of string if neither found. Inline comment must
52
+ be prefixed by a whitespace character to register as a comment. */
53
+ static char* find_chars_or_comment(const char* s, const char* chars)
54
+ {
55
+ #if INI_ALLOW_INLINE_COMMENTS
56
+ int was_space = 0;
57
+ while (*s && (!chars || !strchr(chars, *s)) &&
58
+ !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
59
+ was_space = isspace((unsigned char)(*s));
60
+ s++;
61
+ }
62
+ #else
63
+ while (*s && (!chars || !strchr(chars, *s))) {
64
+ s++;
65
+ }
66
+ #endif
67
+ return (char*)s;
68
+ }
69
+
70
+ /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
71
+ static char* strncpy0(char* dest, const char* src, size_t size)
72
+ {
73
+ strncpy(dest, src, size);
74
+ dest[size - 1] = '\0';
75
+ return dest;
76
+ }
77
+
78
+ /* See documentation in header file. */
79
+ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
80
+ void* user)
81
+ {
82
+ /* Uses a fair bit of stack (use heap instead if you need to) */
83
+ #if INI_USE_STACK
84
+ char line[INI_MAX_LINE];
85
+ #else
86
+ char* line;
87
+ #endif
88
+ char section[MAX_SECTION] = "";
89
+ char prev_name[MAX_NAME] = "";
90
+
91
+ char* start;
92
+ char* end;
93
+ char* name;
94
+ char* value;
95
+ int lineno = 0;
96
+ int error = 0;
97
+
98
+ #if !INI_USE_STACK
99
+ line = (char*)malloc(INI_MAX_LINE);
100
+ if (!line) {
101
+ return -2;
102
+ }
103
+ #endif
104
+
105
+ #if INI_HANDLER_LINENO
106
+ #define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
107
+ #else
108
+ #define HANDLER(u, s, n, v) handler(u, s, n, v)
109
+ #endif
110
+
111
+ /* Scan through stream line by line */
112
+ while (reader(line, INI_MAX_LINE, stream) != NULL) {
113
+ lineno++;
114
+
115
+ start = line;
116
+ #if INI_ALLOW_BOM
117
+ if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
118
+ (unsigned char)start[1] == 0xBB &&
119
+ (unsigned char)start[2] == 0xBF) {
120
+ start += 3;
121
+ }
122
+ #endif
123
+ start = lskip(rstrip(start));
124
+
125
+ if (*start == ';' || *start == '#') {
126
+ /* Per Python configparser, allow both ; and # comments at the
127
+ start of a line */
128
+ }
129
+ #if INI_ALLOW_MULTILINE
130
+ else if (*prev_name && *start && start > line) {
131
+ /* Non-blank line with leading whitespace, treat as continuation
132
+ of previous name's value (as per Python configparser). */
133
+ if (!HANDLER(user, section, prev_name, start) && !error)
134
+ error = lineno;
135
+ }
136
+ #endif
137
+ else if (*start == '[') {
138
+ /* A "[section]" line */
139
+ end = find_chars_or_comment(start + 1, "]");
140
+ if (*end == ']') {
141
+ *end = '\0';
142
+ strncpy0(section, start + 1, sizeof(section));
143
+ *prev_name = '\0';
144
+ }
145
+ else if (!error) {
146
+ /* No ']' found on section line */
147
+ error = lineno;
148
+ }
149
+ }
150
+ else if (*start) {
151
+ /* Not a comment, must be a name[=:]value pair */
152
+ end = find_chars_or_comment(start, "=:");
153
+ if (*end == '=' || *end == ':') {
154
+ *end = '\0';
155
+ name = rstrip(start);
156
+ value = end + 1;
157
+ #if INI_ALLOW_INLINE_COMMENTS
158
+ end = find_chars_or_comment(value, NULL);
159
+ if (*end)
160
+ *end = '\0';
161
+ #endif
162
+ value = lskip(value);
163
+ rstrip(value);
164
+
165
+ /* Valid name[=:]value pair found, call handler */
166
+ strncpy0(prev_name, name, sizeof(prev_name));
167
+ if (!HANDLER(user, section, name, value) && !error)
168
+ error = lineno;
169
+ }
170
+ else if (!error) {
171
+ /* No '=' or ':' found on name[=:]value line */
172
+ error = lineno;
173
+ }
174
+ }
175
+
176
+ #if INI_STOP_ON_FIRST_ERROR
177
+ if (error)
178
+ break;
179
+ #endif
180
+ }
181
+
182
+ #if !INI_USE_STACK
183
+ free(line);
184
+ #endif
185
+
186
+ return error;
187
+ }
188
+
189
+ /* See documentation in header file. */
190
+ int ini_parse_file(FILE* file, ini_handler handler, void* user)
191
+ {
192
+ return ini_parse_stream((ini_reader)fgets, file, handler, user);
193
+ }
194
+
195
+ /* See documentation in header file. */
196
+ int ini_parse(const char* filename, ini_handler handler, void* user)
197
+ {
198
+ FILE* file;
199
+ int error;
200
+
201
+ file = fopen(filename, "r");
202
+ if (!file)
203
+ return -1;
204
+ error = ini_parse_file(file, handler, user);
205
+ fclose(file);
206
+ return error;
207
+ }
208
+
209
+ /* An ini_reader function to read the next line from a string buffer. This
210
+ is the fgets() equivalent used by ini_parse_string(). */
211
+ static char* ini_reader_string(char* str, int num, void* stream) {
212
+ ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
213
+ const char* ctx_ptr = ctx->ptr;
214
+ size_t ctx_num_left = ctx->num_left;
215
+ char* strp = str;
216
+ char c;
217
+
218
+ if (ctx_num_left == 0 || num < 2)
219
+ return NULL;
220
+
221
+ while (num > 1 && ctx_num_left != 0) {
222
+ c = *ctx_ptr++;
223
+ ctx_num_left--;
224
+ *strp++ = c;
225
+ if (c == '\n')
226
+ break;
227
+ num--;
228
+ }
229
+
230
+ *strp = '\0';
231
+ ctx->ptr = ctx_ptr;
232
+ ctx->num_left = ctx_num_left;
233
+ return str;
234
+ }
235
+
236
+ /* See documentation in header file. */
237
+ int ini_parse_string(const char* string, ini_handler handler, void* user) {
238
+ ini_parse_string_ctx ctx;
239
+
240
+ ctx.ptr = string;
241
+ ctx.num_left = strlen(string);
242
+ return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
243
+ user);
244
+ }
data/ext/inih/inih.c ADDED
@@ -0,0 +1,79 @@
1
+ #include "inih.h"
2
+
3
+ VALUE mINIH = Qnil;
4
+
5
+ static int mINIH_ini_handler(void *data, const char *sect, const char *name, const char *val);
6
+
7
+ /*
8
+ @overload parse(string)
9
+ Parse an INI-formatted string into a Hash.
10
+ @param string [String] the INI-formatted string to parse
11
+ @return [Hash] the resulting hash
12
+ @raise [RuntimeError] if a parse error occurs
13
+ */
14
+ static VALUE mINIH_parse(VALUE self, VALUE string);
15
+
16
+ /*
17
+ @overload load(filename)
18
+ Parse an INI-formatted file into a Hash.
19
+ @param filename [String] the INI-formatted file to parse
20
+ @return [Hash] the resulting hash
21
+ @raise [RuntimeError] if a parse or I/O error occurs
22
+ */
23
+ static VALUE mINIH_load(VALUE self, VALUE filename);
24
+
25
+ void Init_inih()
26
+ {
27
+ mINIH = rb_define_module("INIH");
28
+
29
+ rb_define_singleton_method(mINIH, "parse", mINIH_parse, 1);
30
+ rb_define_singleton_method(mINIH, "load", mINIH_load, 1);
31
+ }
32
+
33
+ static int mINIH_ini_handler(void *data, const char *sect, const char *name, const char *val)
34
+ {
35
+ VALUE sect_s = rb_str_new_cstr(sect);
36
+ VALUE name_s = rb_str_new_cstr(name);
37
+ VALUE hash = *((VALUE *) data);
38
+ VALUE subh = rb_hash_aref(hash, sect_s);
39
+
40
+ if (NIL_P(subh)) {
41
+ subh = rb_hash_new();
42
+ }
43
+
44
+ rb_hash_aset(subh, name_s, rb_str_new_cstr(val));
45
+ rb_hash_aset(hash, sect_s, subh);
46
+
47
+ return 1;
48
+ }
49
+
50
+ static VALUE mINIH_parse(VALUE self, VALUE string)
51
+ {
52
+ char *str = StringValueCStr(string);
53
+ VALUE hash = rb_hash_new();
54
+ int result;
55
+
56
+ if ((result = ini_parse_string(str, mINIH_ini_handler, &hash)) != 0) {
57
+ rb_raise(rb_eRuntimeError, "parse error, line %d", result);
58
+ }
59
+
60
+ return rb_funcall(mINIH, rb_intern("normalize"), 1, hash);
61
+ }
62
+
63
+ static VALUE mINIH_load(VALUE self, VALUE filename)
64
+ {
65
+ char *file = StringValueCStr(filename);
66
+ VALUE hash = rb_hash_new();
67
+ int result;
68
+
69
+ if ((result = ini_parse(file, mINIH_ini_handler, &hash)) != 0) {
70
+ if (result < 0) {
71
+ rb_raise(rb_eRuntimeError, "I/O error");
72
+ }
73
+ else {
74
+ rb_raise(rb_eRuntimeError, "parse error, line %d", result);
75
+ }
76
+ }
77
+
78
+ return rb_funcall(mINIH, rb_intern("normalize"), 1, hash);
79
+ }
data/lib/inih.rb ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../ext/inih/inih"
4
+
5
+ # The primary namespace for {INIH}.
6
+ module INIH
7
+ # The current version of ruby-inih.
8
+ VERSION = "0.0.1"
9
+
10
+ # Normalize a parsed INI file's values.
11
+ # @api private
12
+ def self.normalize(hsh)
13
+ hsh.map do |k, sect|
14
+ [k, normalize_sect(sect)]
15
+ end.to_h
16
+ end
17
+
18
+ # Normalize the values in a section of a parsed INI file.
19
+ # @api private
20
+ def self.normalize_sect(sect)
21
+ sect.map do |k, v|
22
+ nv = case v
23
+ when "true" then true
24
+ when "false" then false
25
+ when /\A\d+\Z/ then Integer v
26
+ when /\A\d+\.\d+\Z/ then Float v
27
+ else v
28
+ end
29
+
30
+ [k, nv]
31
+ end.to_h
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inih
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - William Woodruff
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A native library for parsing INI files.
14
+ email: william@tuffbizz.com
15
+ executables: []
16
+ extensions:
17
+ - ext/inih/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".yardopts"
21
+ - LICENSE
22
+ - README.md
23
+ - ext/inih/extconf.rb
24
+ - ext/inih/ini.c
25
+ - ext/inih/inih.c
26
+ - lib/inih.rb
27
+ homepage: https://github.com/woodruffw/ruby-ini
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.6.11
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: inih - a Ruby wrapper for a simple C INI parser
51
+ test_files: []