ruby-augeas 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
*/
|