ruby-augeas 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +510 -0
- data/NEWS +18 -0
- data/README.rdoc +34 -0
- data/Rakefile +132 -0
- data/ext/augeas/_augeas.c +445 -0
- data/ext/augeas/extconf.rb +30 -0
- data/lib/augeas.rb +119 -0
- data/tests/root/etc/group +26 -0
- data/tests/root/etc/hosts +6 -0
- data/tests/root/etc/inittab +53 -0
- data/tests/root/etc/ssh/sshd_config +2 -0
- data/tests/tc_augeas.rb +208 -0
- metadata +80 -0
data/NEWS
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
0.4.0 - 2011-03-25
|
2
|
+
- set can now set multiple elements at once
|
3
|
+
- expose aug_setm as Augeas#setm
|
4
|
+
- expose error functions through Augeas#error
|
5
|
+
- expose aug_span as Augeas#span
|
6
|
+
|
7
|
+
0.3.0 - 2009-08-12
|
8
|
+
- Require augeas >= 0.5.1
|
9
|
+
- Bindings for aug_load, aug_defvar, and aug_defnode
|
10
|
+
- Map flags AUG_NO_STDINC, AUG_NO_LOAD, AUG_NO_MODL_AUTOLOAD
|
11
|
+
- Augeas::transform: convenience method for setting up transforms
|
12
|
+
- Augeas::set: allow passing in nil as the value
|
13
|
+
- Augeas::open: make args optional, accept block
|
14
|
+
- Exception raising versions of set, load, and save
|
15
|
+
|
16
|
+
0.2.0 - 2008-08-26
|
17
|
+
Details for this and earlier releases need to be extracted from the
|
18
|
+
history of the git repo
|
data/README.rdoc
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
= Ruby bindings for augeas
|
2
|
+
|
3
|
+
The class Augeas provides bindings to augeas [http://augeas.net] library.
|
4
|
+
|
5
|
+
== Usage: Setting Data
|
6
|
+
Augeas::open do |aug|
|
7
|
+
aug.set("/files/etc/sysconfig/firstboot/RUN_FIRSTBOOT", "YES")
|
8
|
+
unless aug.save
|
9
|
+
raise IOError, "Failed to save changes"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
== Usage: Accessing Data
|
14
|
+
firstboot = Augeas::open { |aug| aug.get("/files/etc/sysconfig/firstboot/RUN_FIRSTBOOT") }
|
15
|
+
|
16
|
+
== Usage: Removing Data
|
17
|
+
Augeas::open do |aug|
|
18
|
+
aug.rm("/files/etc/sysconfig/firstboot/RUN_FIRSTBOOT")
|
19
|
+
unless aug.save
|
20
|
+
raise IOError, "Failed to save changes"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
== Usage: Minimal Setup with a Custom Root
|
25
|
+
|
26
|
+
By passing +NO_MODL_AUTOLOAD+, no files are read on startup; that allows
|
27
|
+
setting up a custom transform.
|
28
|
+
|
29
|
+
Augeas::open("/var/tmp/augeas-root", "/usr/local/share/mylenses",
|
30
|
+
Augeas::NO_MODL_AUTOLOAD) do |aug|
|
31
|
+
aug.transform(:lens => "Aliases.lns", :incl => "/etc/aliases")
|
32
|
+
aug.load
|
33
|
+
aug.get("/files/etc/aliases/*[name = 'postmaster']/value")
|
34
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# Rakefile: build ruby auges bindings
|
3
|
+
#
|
4
|
+
# Copyright (C) 2008 Red Hat, Inc.
|
5
|
+
#
|
6
|
+
# Distributed under the GNU Lesser General Public License v2.1 or later.
|
7
|
+
# See COPYING for details
|
8
|
+
#
|
9
|
+
# Bryan Kearney <bkearney@redhat.com>
|
10
|
+
|
11
|
+
require 'rake/clean'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
require 'rake/testtask'
|
14
|
+
require 'rake/gempackagetask'
|
15
|
+
|
16
|
+
PKG_NAME='ruby-augeas'
|
17
|
+
GEM_NAME=PKG_NAME # we'd like 'augeas' but that makes RPM fail
|
18
|
+
PKG_VERSION='0.4.1'
|
19
|
+
EXT_CONF='ext/augeas/extconf.rb'
|
20
|
+
MAKEFILE="ext/augeas/Makefile"
|
21
|
+
AUGEAS_MODULE="ext/augeas/_augeas.so"
|
22
|
+
SPEC_FILE="ruby-augeas.spec"
|
23
|
+
AUGEAS_SRC=AUGEAS_MODULE.gsub(/.so$/, ".c")
|
24
|
+
|
25
|
+
#
|
26
|
+
# Building the actual bits
|
27
|
+
#
|
28
|
+
CLEAN.include [ "**/*~",
|
29
|
+
"ext/**/*.o", AUGEAS_MODULE,
|
30
|
+
"ext/**/depend" ]
|
31
|
+
|
32
|
+
CLOBBER.include [ "config.save",
|
33
|
+
"ext/**/mkmf.log",
|
34
|
+
MAKEFILE ]
|
35
|
+
|
36
|
+
file MAKEFILE => EXT_CONF do |t|
|
37
|
+
Dir::chdir(File::dirname(EXT_CONF)) do
|
38
|
+
unless sh "ruby #{File::basename(EXT_CONF)}"
|
39
|
+
$stderr.puts "Failed to run extconf"
|
40
|
+
break
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
file AUGEAS_MODULE => [ MAKEFILE, AUGEAS_SRC ] do |t|
|
45
|
+
Dir::chdir(File::dirname(EXT_CONF)) do
|
46
|
+
unless sh "make"
|
47
|
+
$stderr.puts "make failed"
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
desc "Build the native library"
|
53
|
+
task :build => AUGEAS_MODULE
|
54
|
+
|
55
|
+
#
|
56
|
+
# Testing
|
57
|
+
#
|
58
|
+
Rake::TestTask.new(:test) do |t|
|
59
|
+
t.test_files = FileList['tests/tc_*.rb']
|
60
|
+
t.libs = [ 'lib', 'ext/augeas' ]
|
61
|
+
end
|
62
|
+
task :test => :build
|
63
|
+
|
64
|
+
|
65
|
+
#
|
66
|
+
# Generate the documentation
|
67
|
+
#
|
68
|
+
Rake::RDocTask.new do |rd|
|
69
|
+
rd.main = "README.rdoc"
|
70
|
+
rd.rdoc_dir = "doc/site/api"
|
71
|
+
rd.rdoc_files.include("README.rdoc", "ext/**/*.[ch]","lib/**/*.rb")
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Packaging
|
76
|
+
#
|
77
|
+
PKG_FILES = FileList[
|
78
|
+
"Rakefile", "COPYING","README.rdoc", "NEWS",
|
79
|
+
"ext/**/*.[ch]", "lib/**/*.rb", "ext/**/MANIFEST", "ext/**/extconf.rb",
|
80
|
+
"tests/**/*",
|
81
|
+
"spec/**/*"
|
82
|
+
]
|
83
|
+
|
84
|
+
DIST_FILES = FileList[
|
85
|
+
"pkg/*.tgz", "pkg/*.gem"
|
86
|
+
]
|
87
|
+
|
88
|
+
SPEC = Gem::Specification.new do |s|
|
89
|
+
s.name = GEM_NAME
|
90
|
+
s.version = PKG_VERSION
|
91
|
+
s.email = "augeas-devel@redhat.com"
|
92
|
+
s.homepage = "http://augeas.net/"
|
93
|
+
s.summary = "Ruby bindings for augeas"
|
94
|
+
s.files = PKG_FILES
|
95
|
+
s.autorequire = "augeas"
|
96
|
+
s.required_ruby_version = '>= 1.8.1'
|
97
|
+
s.extensions = "ext/augeas/extconf.rb"
|
98
|
+
s.description = "Provides bindings for augeas."
|
99
|
+
end
|
100
|
+
|
101
|
+
Rake::GemPackageTask.new(SPEC) do |pkg|
|
102
|
+
pkg.need_tar = true
|
103
|
+
pkg.need_zip = true
|
104
|
+
end
|
105
|
+
|
106
|
+
desc "Build (S)RPM for #{PKG_NAME}"
|
107
|
+
task :rpm => [ :package ] do |t|
|
108
|
+
system("sed -e 's/@VERSION@/#{PKG_VERSION}/' #{SPEC_FILE} > pkg/#{SPEC_FILE}")
|
109
|
+
Dir::chdir("pkg") do |dir|
|
110
|
+
dir = File::expand_path(".")
|
111
|
+
system("rpmbuild --define '_topdir #{dir}' --define '_sourcedir #{dir}' --define '_srcrpmdir #{dir}' --define '_rpmdir #{dir}' --define '_builddir #{dir}' -ba #{SPEC_FILE} > rpmbuild.log 2>&1")
|
112
|
+
if $? != 0
|
113
|
+
raise "rpmbuild failed"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
desc "Release a version to the site"
|
119
|
+
task :dist => [ :rpm ] do |t|
|
120
|
+
puts "Copying files"
|
121
|
+
unless sh "scp -p #{DIST_FILES.to_s} et:/var/www/sites/augeas.et.redhat.com/download/ruby"
|
122
|
+
$stderr.puts "Copy to et failed"
|
123
|
+
break
|
124
|
+
end
|
125
|
+
puts "Commit and tag #{PKG_VERSION}"
|
126
|
+
system "git commit -a -m 'Released version #{PKG_VERSION}'"
|
127
|
+
system "git tag -s -m 'Tag release #{PKG_VERSION}' release-#{PKG_VERSION}"
|
128
|
+
end
|
129
|
+
|
130
|
+
task :sync do |t|
|
131
|
+
system "rsync -rav doc/site/ et:/var/www/sites/augeas.et.redhat.com/docs/ruby/"
|
132
|
+
end
|
@@ -0,0 +1,445 @@
|
|
1
|
+
/*
|
2
|
+
* augeas.c: Ruby bindings for augeas
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008 Red Hat Inc.
|
5
|
+
*
|
6
|
+
* This library is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with this library; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
*
|
20
|
+
* Author: Bryan Kearney <bkearney@redhat.com>
|
21
|
+
*/
|
22
|
+
#include <ruby.h>
|
23
|
+
#include <augeas.h>
|
24
|
+
|
25
|
+
static VALUE c_augeas;
|
26
|
+
|
27
|
+
#define StringValueCStrOrNull(v) \
|
28
|
+
NIL_P(v) ? NULL : StringValueCStr(v)
|
29
|
+
|
30
|
+
static augeas *aug_handle(VALUE s) {
|
31
|
+
augeas *aug;
|
32
|
+
|
33
|
+
Data_Get_Struct(s, struct augeas, aug);
|
34
|
+
if (aug == NULL) {
|
35
|
+
rb_raise(rb_eSystemCallError, "Failed to retrieve connection");
|
36
|
+
}
|
37
|
+
return aug;
|
38
|
+
}
|
39
|
+
|
40
|
+
static void augeas_free(augeas *aug) {
|
41
|
+
if (aug != NULL)
|
42
|
+
aug_close(aug);
|
43
|
+
}
|
44
|
+
|
45
|
+
/*
|
46
|
+
* call-seq:
|
47
|
+
* get(PATH) -> String
|
48
|
+
*
|
49
|
+
* Lookup the value associated with PATH
|
50
|
+
*/
|
51
|
+
VALUE augeas_get(VALUE s, VALUE path) {
|
52
|
+
augeas *aug = aug_handle(s);
|
53
|
+
const char *cpath = StringValueCStr(path);
|
54
|
+
const char *value;
|
55
|
+
|
56
|
+
aug_get(aug, cpath, &value);
|
57
|
+
if (value != NULL) {
|
58
|
+
return rb_str_new(value, strlen(value)) ;
|
59
|
+
} else {
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
/*
|
65
|
+
* call-seq:
|
66
|
+
* exists(PATH) -> boolean
|
67
|
+
*
|
68
|
+
* Return true if there is an entry for this path, false otherwise
|
69
|
+
*/
|
70
|
+
VALUE augeas_exists(VALUE s, VALUE path) {
|
71
|
+
augeas *aug = aug_handle(s);
|
72
|
+
const char *cpath = StringValueCStr(path);
|
73
|
+
int ret = aug_get(aug, cpath, NULL);
|
74
|
+
|
75
|
+
return (ret == 1) ? Qtrue : Qfalse;
|
76
|
+
}
|
77
|
+
|
78
|
+
/*
|
79
|
+
* call-seq:
|
80
|
+
* set(PATH, VALUE) -> boolean
|
81
|
+
*
|
82
|
+
* Set the value associated with PATH to VALUE. VALUE is copied into the
|
83
|
+
* internal data structure. Intermediate entries are created if they don't
|
84
|
+
* exist.
|
85
|
+
*/
|
86
|
+
VALUE augeas_set(VALUE s, VALUE path, VALUE value) {
|
87
|
+
augeas *aug = aug_handle(s);
|
88
|
+
const char *cpath = StringValueCStr(path) ;
|
89
|
+
const char *cvalue = StringValueCStrOrNull(value) ;
|
90
|
+
|
91
|
+
int callValue = aug_set(aug, cpath, cvalue) ;
|
92
|
+
VALUE returnValue ;
|
93
|
+
|
94
|
+
if (callValue == 0)
|
95
|
+
returnValue = Qtrue ;
|
96
|
+
else
|
97
|
+
returnValue = Qfalse ;
|
98
|
+
|
99
|
+
return returnValue ;
|
100
|
+
}
|
101
|
+
|
102
|
+
/*
|
103
|
+
* call-seq:
|
104
|
+
* setm(BASE, SUB, VALUE) -> boolean
|
105
|
+
*
|
106
|
+
* Set multiple nodes in one operation. Find or create a node matching
|
107
|
+
* SUB by interpreting SUB as a path expression relative to each node
|
108
|
+
* matching BASE. SUB may be NULL, in which case all the nodes matching
|
109
|
+
* BASE will be modified.
|
110
|
+
*/
|
111
|
+
VALUE augeas_setm(VALUE s, VALUE base, VALUE sub, VALUE value) {
|
112
|
+
augeas *aug = aug_handle(s);
|
113
|
+
const char *cbase = StringValueCStr(base) ;
|
114
|
+
const char *csub = StringValueCStrOrNull(sub) ;
|
115
|
+
const char *cvalue = StringValueCStrOrNull(value) ;
|
116
|
+
|
117
|
+
int callValue = aug_setm(aug, cbase, csub, cvalue) ;
|
118
|
+
return INT2FIX(callValue);
|
119
|
+
}
|
120
|
+
|
121
|
+
/*
|
122
|
+
* call-seq:
|
123
|
+
* insert(PATH, LABEL, BEFORE) -> int
|
124
|
+
*
|
125
|
+
* Make LABEL a sibling of PATH by inserting it directly before or after PATH.
|
126
|
+
* The boolean BEFORE determines if LABEL is inserted before or after PATH.
|
127
|
+
*/
|
128
|
+
VALUE augeas_insert(VALUE s, VALUE path, VALUE label, VALUE before) {
|
129
|
+
augeas *aug = aug_handle(s);
|
130
|
+
const char *cpath = StringValueCStr(path) ;
|
131
|
+
const char *clabel = StringValueCStr(label) ;
|
132
|
+
|
133
|
+
int callValue = aug_insert(aug, cpath, clabel, RTEST(before));
|
134
|
+
return INT2FIX(callValue) ;
|
135
|
+
}
|
136
|
+
|
137
|
+
/*
|
138
|
+
* call-seq:
|
139
|
+
* mv(SRC, DST) -> int
|
140
|
+
*
|
141
|
+
* Move the node SRC to DST. SRC must match exactly one node in the
|
142
|
+
* tree. DST must either match exactly one node in the tree, or may not
|
143
|
+
* exist yet. If DST exists already, it and all its descendants are
|
144
|
+
* deleted. If DST does not exist yet, it and all its missing ancestors are
|
145
|
+
* created.
|
146
|
+
*/
|
147
|
+
VALUE augeas_mv(VALUE s, VALUE src, VALUE dst) {
|
148
|
+
augeas *aug = aug_handle(s);
|
149
|
+
const char *csrc = StringValueCStr(src);
|
150
|
+
const char *cdst = StringValueCStr(dst);
|
151
|
+
int r = aug_mv(aug, csrc, cdst);
|
152
|
+
|
153
|
+
return INT2FIX(r);
|
154
|
+
}
|
155
|
+
|
156
|
+
/*
|
157
|
+
* call-seq:
|
158
|
+
* rm(PATH) -> int
|
159
|
+
*
|
160
|
+
* Remove path and all its children. Returns the number of entries removed
|
161
|
+
*/
|
162
|
+
VALUE augeas_rm(VALUE s, VALUE path, VALUE sibling) {
|
163
|
+
augeas *aug = aug_handle(s);
|
164
|
+
const char *cpath = StringValueCStr(path) ;
|
165
|
+
|
166
|
+
int callValue = aug_rm(aug, cpath) ;
|
167
|
+
return INT2FIX(callValue) ;
|
168
|
+
}
|
169
|
+
|
170
|
+
/*
|
171
|
+
* call-seq:
|
172
|
+
* match(PATH) -> an_array
|
173
|
+
*
|
174
|
+
* Return all the paths that match the path expression PATH as an aray of
|
175
|
+
* strings.
|
176
|
+
*/
|
177
|
+
VALUE augeas_match(VALUE s, VALUE p) {
|
178
|
+
augeas *aug = aug_handle(s);
|
179
|
+
const char *path = StringValueCStr(p);
|
180
|
+
char **matches = NULL;
|
181
|
+
int cnt, i;
|
182
|
+
|
183
|
+
cnt = aug_match(aug, path, &matches) ;
|
184
|
+
if (cnt < 0)
|
185
|
+
rb_raise(rb_eSystemCallError, "Matching path expression '%s' failed",
|
186
|
+
path);
|
187
|
+
|
188
|
+
VALUE result = rb_ary_new();
|
189
|
+
for (i = 0; i < cnt; i++) {
|
190
|
+
rb_ary_push(result, rb_str_new(matches[i], strlen(matches[i])));
|
191
|
+
free(matches[i]) ;
|
192
|
+
}
|
193
|
+
free (matches) ;
|
194
|
+
|
195
|
+
return result ;
|
196
|
+
}
|
197
|
+
|
198
|
+
/*
|
199
|
+
* call-seq:
|
200
|
+
* save() -> boolean
|
201
|
+
*
|
202
|
+
* Write all pending changes to disk
|
203
|
+
*/
|
204
|
+
VALUE augeas_save(VALUE s) {
|
205
|
+
augeas *aug = aug_handle(s);
|
206
|
+
int callValue = aug_save(aug) ;
|
207
|
+
VALUE returnValue ;
|
208
|
+
|
209
|
+
if (callValue == 0)
|
210
|
+
returnValue = Qtrue ;
|
211
|
+
else
|
212
|
+
returnValue = Qfalse ;
|
213
|
+
|
214
|
+
return returnValue ;
|
215
|
+
}
|
216
|
+
|
217
|
+
/*
|
218
|
+
* call-seq:
|
219
|
+
* load() -> boolean
|
220
|
+
*
|
221
|
+
* Load files from disk according to the transforms under +/augeas/load+
|
222
|
+
*/
|
223
|
+
VALUE augeas_load(VALUE s) {
|
224
|
+
augeas *aug = aug_handle(s);
|
225
|
+
int callValue = aug_load(aug);
|
226
|
+
VALUE returnValue ;
|
227
|
+
|
228
|
+
if (callValue == 0)
|
229
|
+
returnValue = Qtrue ;
|
230
|
+
else
|
231
|
+
returnValue = Qfalse ;
|
232
|
+
|
233
|
+
return returnValue ;
|
234
|
+
}
|
235
|
+
|
236
|
+
/*
|
237
|
+
* call-seq:
|
238
|
+
* defvar(NAME, EXPR) -> boolean
|
239
|
+
*
|
240
|
+
* Define a variable NAME whose value is the result of evaluating EXPR. If
|
241
|
+
* a variable NAME already exists, its name will be replaced with the
|
242
|
+
* result of evaluating EXPR.
|
243
|
+
*
|
244
|
+
* If EXPR is NULL, the variable NAME will be removed if it is defined.
|
245
|
+
*
|
246
|
+
*/
|
247
|
+
VALUE augeas_defvar(VALUE s, VALUE name, VALUE expr) {
|
248
|
+
augeas *aug = aug_handle(s);
|
249
|
+
const char *cname = StringValueCStr(name);
|
250
|
+
const char *cexpr = StringValueCStrOrNull(expr);
|
251
|
+
|
252
|
+
int r = aug_defvar(aug, cname, cexpr);
|
253
|
+
|
254
|
+
return (r < 0) ? Qfalse : Qtrue;
|
255
|
+
}
|
256
|
+
|
257
|
+
/*
|
258
|
+
* call-seq:
|
259
|
+
* defnode(NAME, EXPR, VALUE) -> boolean
|
260
|
+
*
|
261
|
+
* Define a variable NAME whose value is the result of evaluating EXPR,
|
262
|
+
* which must be non-NULL and evaluate to a nodeset. If a variable NAME
|
263
|
+
* already exists, its name will be replaced with the result of evaluating
|
264
|
+
* EXPR.
|
265
|
+
*
|
266
|
+
* If EXPR evaluates to an empty nodeset, a node is created, equivalent to
|
267
|
+
* calling AUG_SET(AUG, EXPR, VALUE) and NAME will be the nodeset containing
|
268
|
+
* that single node.
|
269
|
+
*
|
270
|
+
* Returns +false+ if +aug_defnode+ fails, and the number of nodes in the
|
271
|
+
* nodeset on success.
|
272
|
+
*/
|
273
|
+
VALUE augeas_defnode(VALUE s, VALUE name, VALUE expr, VALUE value) {
|
274
|
+
augeas *aug = aug_handle(s);
|
275
|
+
const char *cname = StringValueCStr(name);
|
276
|
+
const char *cexpr = StringValueCStrOrNull(expr);
|
277
|
+
const char *cvalue = StringValueCStrOrNull(value);
|
278
|
+
|
279
|
+
/* FIXME: Figure out a way to return created, maybe accept a block
|
280
|
+
that gets run when created == 1 ? */
|
281
|
+
int r = aug_defnode(aug, cname, cexpr, cvalue, NULL);
|
282
|
+
|
283
|
+
return (r < 0) ? Qfalse : INT2NUM(r);
|
284
|
+
}
|
285
|
+
|
286
|
+
VALUE augeas_init(VALUE m, VALUE r, VALUE l, VALUE f) {
|
287
|
+
unsigned int flags = NUM2UINT(f);
|
288
|
+
const char *root = StringValueCStrOrNull(r);
|
289
|
+
const char *loadpath = StringValueCStrOrNull(l);
|
290
|
+
augeas *aug = NULL;
|
291
|
+
|
292
|
+
aug = aug_init(root, loadpath, flags);
|
293
|
+
if (aug == NULL) {
|
294
|
+
rb_raise(rb_eSystemCallError, "Failed to initialize Augeas");
|
295
|
+
}
|
296
|
+
return Data_Wrap_Struct(c_augeas, NULL, augeas_free, aug);
|
297
|
+
}
|
298
|
+
|
299
|
+
VALUE augeas_close (VALUE s) {
|
300
|
+
augeas *aug = aug_handle(s);
|
301
|
+
|
302
|
+
aug_close(aug);
|
303
|
+
DATA_PTR(s) = NULL;
|
304
|
+
|
305
|
+
return Qnil;
|
306
|
+
}
|
307
|
+
|
308
|
+
static void hash_set(VALUE hash, const char *sym, VALUE v) {
|
309
|
+
rb_hash_aset(hash, ID2SYM(rb_intern(sym)), v);
|
310
|
+
}
|
311
|
+
|
312
|
+
/*
|
313
|
+
* call-seq:
|
314
|
+
* error -> HASH
|
315
|
+
*
|
316
|
+
* Retrieve details about the last error encountered and return those
|
317
|
+
* details in a HASH with the following entries:
|
318
|
+
* - :code error code from +aug_error+
|
319
|
+
* - :message error message from +aug_error_message+
|
320
|
+
* - :minor minor error message from +aug_minor_error_message+
|
321
|
+
* - :details error details from +aug_error_details+
|
322
|
+
*/
|
323
|
+
VALUE augeas_error(VALUE s) {
|
324
|
+
augeas *aug = aug_handle(s);
|
325
|
+
int code;
|
326
|
+
const char *msg;
|
327
|
+
VALUE result;
|
328
|
+
|
329
|
+
result = rb_hash_new();
|
330
|
+
|
331
|
+
code = aug_error(aug);
|
332
|
+
hash_set(result, "code", INT2NUM(code));
|
333
|
+
|
334
|
+
msg = aug_error_message(aug);
|
335
|
+
if (msg != NULL)
|
336
|
+
hash_set(result, "message", rb_str_new2(msg));
|
337
|
+
|
338
|
+
msg = aug_error_minor_message(aug);
|
339
|
+
if (msg != NULL)
|
340
|
+
hash_set(result, "minor", rb_str_new2(msg));
|
341
|
+
|
342
|
+
msg = aug_error_details(aug);
|
343
|
+
if (msg != NULL)
|
344
|
+
hash_set(result, "details", rb_str_new2(msg));
|
345
|
+
|
346
|
+
return result;
|
347
|
+
}
|
348
|
+
|
349
|
+
static void hash_set_range(VALUE hash, const char *sym,
|
350
|
+
unsigned int start, unsigned int end) {
|
351
|
+
VALUE r;
|
352
|
+
|
353
|
+
r = rb_range_new(INT2NUM(start), INT2NUM(end), 0);
|
354
|
+
hash_set(hash, sym, r);
|
355
|
+
}
|
356
|
+
|
357
|
+
VALUE augeas_span(VALUE s, VALUE path) {
|
358
|
+
augeas *aug = aug_handle(s);
|
359
|
+
char *cpath = StringValueCStr(path);
|
360
|
+
char *filename = NULL;
|
361
|
+
unsigned int label_start, label_end, value_start, value_end,
|
362
|
+
span_start, span_end;
|
363
|
+
int r;
|
364
|
+
VALUE result;
|
365
|
+
|
366
|
+
r = aug_span(aug, cpath,
|
367
|
+
&filename,
|
368
|
+
&label_start, &label_end,
|
369
|
+
&value_start, &value_end,
|
370
|
+
&span_start, &span_end);
|
371
|
+
|
372
|
+
result = rb_hash_new();
|
373
|
+
|
374
|
+
if (r == 0) {
|
375
|
+
hash_set(result, "filename", rb_str_new2(filename));
|
376
|
+
hash_set_range(result, "label", label_start, label_end);
|
377
|
+
hash_set_range(result, "value", value_start, value_end);
|
378
|
+
hash_set_range(result, "span", span_start, span_end);
|
379
|
+
}
|
380
|
+
|
381
|
+
free(filename);
|
382
|
+
|
383
|
+
return result;
|
384
|
+
}
|
385
|
+
|
386
|
+
void Init__augeas() {
|
387
|
+
|
388
|
+
/* Define the ruby class */
|
389
|
+
c_augeas = rb_define_class("Augeas", rb_cObject) ;
|
390
|
+
|
391
|
+
/* Constants for enum aug_flags */
|
392
|
+
#define DEF_AUG_FLAG(name) \
|
393
|
+
rb_define_const(c_augeas, #name, INT2NUM(AUG_##name))
|
394
|
+
DEF_AUG_FLAG(NONE);
|
395
|
+
DEF_AUG_FLAG(SAVE_BACKUP);
|
396
|
+
DEF_AUG_FLAG(SAVE_NEWFILE);
|
397
|
+
DEF_AUG_FLAG(TYPE_CHECK);
|
398
|
+
DEF_AUG_FLAG(NO_STDINC);
|
399
|
+
DEF_AUG_FLAG(SAVE_NOOP);
|
400
|
+
DEF_AUG_FLAG(NO_LOAD);
|
401
|
+
DEF_AUG_FLAG(NO_MODL_AUTOLOAD);
|
402
|
+
DEF_AUG_FLAG(ENABLE_SPAN);
|
403
|
+
#undef DEF_AUG_FLAG
|
404
|
+
|
405
|
+
/* Constants for enum aug_errcode_t */
|
406
|
+
#define DEF_AUG_ERR(name) \
|
407
|
+
rb_define_const(c_augeas, #name, INT2NUM(AUG_##name))
|
408
|
+
DEF_AUG_ERR(NOERROR);
|
409
|
+
DEF_AUG_ERR(ENOMEM);
|
410
|
+
DEF_AUG_ERR(EINTERNAL);
|
411
|
+
DEF_AUG_ERR(EPATHX);
|
412
|
+
DEF_AUG_ERR(ENOMATCH);
|
413
|
+
DEF_AUG_ERR(EMMATCH);
|
414
|
+
DEF_AUG_ERR(ESYNTAX);
|
415
|
+
DEF_AUG_ERR(ENOLENS);
|
416
|
+
DEF_AUG_ERR(EMXFM);
|
417
|
+
#undef DEF_AUG_ERR
|
418
|
+
|
419
|
+
/* Define the methods */
|
420
|
+
rb_define_singleton_method(c_augeas, "open3", augeas_init, 3);
|
421
|
+
rb_define_method(c_augeas, "defvar", augeas_defvar, 2);
|
422
|
+
rb_define_method(c_augeas, "defnode", augeas_defnode, 3);
|
423
|
+
rb_define_method(c_augeas, "get", augeas_get, 1);
|
424
|
+
rb_define_method(c_augeas, "exists", augeas_exists, 1);
|
425
|
+
rb_define_method(c_augeas, "insert", augeas_insert, 3);
|
426
|
+
rb_define_method(c_augeas, "mv", augeas_mv, 2);
|
427
|
+
rb_define_method(c_augeas, "rm", augeas_rm, 1);
|
428
|
+
rb_define_method(c_augeas, "match", augeas_match, 1);
|
429
|
+
rb_define_method(c_augeas, "save", augeas_save, 0);
|
430
|
+
rb_define_method(c_augeas, "load", augeas_load, 0);
|
431
|
+
rb_define_method(c_augeas, "set_internal", augeas_set, 2);
|
432
|
+
rb_define_method(c_augeas, "setm", augeas_setm, 3);
|
433
|
+
rb_define_method(c_augeas, "close", augeas_close, 0);
|
434
|
+
rb_define_method(c_augeas, "error", augeas_error, 0);
|
435
|
+
rb_define_method(c_augeas, "span", augeas_span, 1);
|
436
|
+
}
|
437
|
+
|
438
|
+
/*
|
439
|
+
* Local variables:
|
440
|
+
* indent-tabs-mode: nil
|
441
|
+
* c-indent-level: 4
|
442
|
+
* c-basic-offset: 4
|
443
|
+
* tab-width: 4
|
444
|
+
* End:
|
445
|
+
*/
|