ruby-augeas 0.4.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +38 -46
- data/NEWS +26 -1
- data/README.md +86 -0
- data/Rakefile +12 -8
- data/ext/augeas/_augeas.c +238 -30
- data/ext/augeas/_augeas.h +48 -0
- data/ext/augeas/extconf.rb +4 -0
- data/lib/augeas/facade.rb +326 -0
- data/lib/augeas.rb +94 -0
- data/tests/tc_augeas.rb +85 -2
- data/tests/tc_facade.rb +554 -0
- metadata +32 -53
- data/README.rdoc +0 -34
data/ext/augeas/_augeas.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* augeas.c: Ruby bindings for augeas
|
3
3
|
*
|
4
|
-
* Copyright (C) 2008 Red Hat Inc.
|
4
|
+
* Copyright (C) 2008-2011 Red Hat Inc.
|
5
5
|
*
|
6
6
|
* This library is free software; you can redistribute it and/or
|
7
7
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -19,13 +19,13 @@
|
|
19
19
|
*
|
20
20
|
* Author: Bryan Kearney <bkearney@redhat.com>
|
21
21
|
*/
|
22
|
+
#include "_augeas.h"
|
23
|
+
|
22
24
|
#include <ruby.h>
|
23
25
|
#include <augeas.h>
|
24
26
|
|
25
27
|
static VALUE c_augeas;
|
26
|
-
|
27
|
-
#define StringValueCStrOrNull(v) \
|
28
|
-
NIL_P(v) ? NULL : StringValueCStr(v)
|
28
|
+
static VALUE c_facade;
|
29
29
|
|
30
30
|
static augeas *aug_handle(VALUE s) {
|
31
31
|
augeas *aug;
|
@@ -51,16 +51,39 @@ static void augeas_free(augeas *aug) {
|
|
51
51
|
VALUE augeas_get(VALUE s, VALUE path) {
|
52
52
|
augeas *aug = aug_handle(s);
|
53
53
|
const char *cpath = StringValueCStr(path);
|
54
|
-
const char *value;
|
54
|
+
const char *value = NULL;
|
55
55
|
|
56
|
-
aug_get(aug, cpath, &value);
|
57
|
-
|
56
|
+
int r = aug_get(aug, cpath, &value);
|
57
|
+
/* There used to be a bug in Augeas that would make it not properly set
|
58
|
+
* VALUE to NULL when PATH was invalid. We check RETVAL, too, to avoid
|
59
|
+
* running into that */
|
60
|
+
if (r == 1 && value != NULL) {
|
58
61
|
return rb_str_new(value, strlen(value)) ;
|
59
62
|
} else {
|
60
63
|
return Qnil;
|
61
64
|
}
|
62
65
|
}
|
63
66
|
|
67
|
+
/*
|
68
|
+
* call-seq:
|
69
|
+
* get(PATH) -> String
|
70
|
+
*
|
71
|
+
* Lookup the value associated with PATH
|
72
|
+
*/
|
73
|
+
VALUE facade_get(VALUE s, VALUE path) {
|
74
|
+
augeas *aug = aug_handle(s);
|
75
|
+
const char *cpath = StringValueCStr(path);
|
76
|
+
const char *value = NULL;
|
77
|
+
|
78
|
+
int retval = aug_get(aug, cpath, &value);
|
79
|
+
|
80
|
+
if (retval == 1 && value != NULL) {
|
81
|
+
return rb_str_new(value, strlen(value));
|
82
|
+
} else {
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
64
87
|
/*
|
65
88
|
* call-seq:
|
66
89
|
* exists(PATH) -> boolean
|
@@ -75,28 +98,30 @@ VALUE augeas_exists(VALUE s, VALUE path) {
|
|
75
98
|
return (ret == 1) ? Qtrue : Qfalse;
|
76
99
|
}
|
77
100
|
|
101
|
+
static int set(VALUE s, VALUE path, VALUE value) {
|
102
|
+
augeas *aug = aug_handle(s);
|
103
|
+
const char *cpath = StringValueCStr(path) ;
|
104
|
+
const char *cvalue = StringValueCStrOrNull(value) ;
|
105
|
+
|
106
|
+
return aug_set(aug, cpath, cvalue) ;
|
107
|
+
}
|
108
|
+
|
78
109
|
/*
|
79
110
|
* call-seq:
|
80
|
-
* set(PATH, VALUE) ->
|
111
|
+
* set(PATH, VALUE) -> int
|
81
112
|
*
|
82
113
|
* Set the value associated with PATH to VALUE. VALUE is copied into the
|
83
114
|
* internal data structure. Intermediate entries are created if they don't
|
84
115
|
* exist.
|
85
116
|
*/
|
86
117
|
VALUE augeas_set(VALUE s, VALUE path, VALUE value) {
|
87
|
-
|
88
|
-
const char *cpath = StringValueCStr(path) ;
|
89
|
-
const char *cvalue = StringValueCStrOrNull(value) ;
|
118
|
+
int callValue = set(s, path, value);
|
90
119
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
if (callValue == 0)
|
95
|
-
returnValue = Qtrue ;
|
96
|
-
else
|
97
|
-
returnValue = Qfalse ;
|
120
|
+
return (callValue == 0) ? Qtrue : Qfalse;
|
121
|
+
}
|
98
122
|
|
99
|
-
|
123
|
+
VALUE facade_set(VALUE s, VALUE path, VALUE value) {
|
124
|
+
return INT2FIX(set(s, path, value));
|
100
125
|
}
|
101
126
|
|
102
127
|
/*
|
@@ -159,7 +184,7 @@ VALUE augeas_mv(VALUE s, VALUE src, VALUE dst) {
|
|
159
184
|
*
|
160
185
|
* Remove path and all its children. Returns the number of entries removed
|
161
186
|
*/
|
162
|
-
VALUE augeas_rm(VALUE s, VALUE path
|
187
|
+
VALUE augeas_rm(VALUE s, VALUE path) {
|
163
188
|
augeas *aug = aug_handle(s);
|
164
189
|
const char *cpath = StringValueCStr(path) ;
|
165
190
|
|
@@ -177,6 +202,7 @@ VALUE augeas_rm(VALUE s, VALUE path, VALUE sibling) {
|
|
177
202
|
VALUE augeas_match(VALUE s, VALUE p) {
|
178
203
|
augeas *aug = aug_handle(s);
|
179
204
|
const char *path = StringValueCStr(p);
|
205
|
+
VALUE result;
|
180
206
|
char **matches = NULL;
|
181
207
|
int cnt, i;
|
182
208
|
|
@@ -185,7 +211,36 @@ VALUE augeas_match(VALUE s, VALUE p) {
|
|
185
211
|
rb_raise(rb_eSystemCallError, "Matching path expression '%s' failed",
|
186
212
|
path);
|
187
213
|
|
188
|
-
|
214
|
+
result = rb_ary_new();
|
215
|
+
for (i = 0; i < cnt; i++) {
|
216
|
+
rb_ary_push(result, rb_str_new(matches[i], strlen(matches[i])));
|
217
|
+
free(matches[i]) ;
|
218
|
+
}
|
219
|
+
free (matches) ;
|
220
|
+
|
221
|
+
return result ;
|
222
|
+
}
|
223
|
+
|
224
|
+
/*
|
225
|
+
* call-seq:
|
226
|
+
* match(PATH) -> an_array
|
227
|
+
*
|
228
|
+
* Return all the paths that match the path expression PATH as an aray of
|
229
|
+
* strings.
|
230
|
+
* Returns an empty array if no paths were found.
|
231
|
+
*/
|
232
|
+
VALUE facade_match(VALUE s, VALUE p) {
|
233
|
+
augeas *aug = aug_handle(s);
|
234
|
+
const char *path = StringValueCStr(p);
|
235
|
+
char **matches = NULL;
|
236
|
+
int cnt, i;
|
237
|
+
VALUE result;
|
238
|
+
|
239
|
+
cnt = aug_match(aug, path, &matches) ;
|
240
|
+
if (cnt < 0)
|
241
|
+
return -1;
|
242
|
+
|
243
|
+
result = rb_ary_new();
|
189
244
|
for (i = 0; i < cnt; i++) {
|
190
245
|
rb_ary_push(result, rb_str_new(matches[i], strlen(matches[i])));
|
191
246
|
free(matches[i]) ;
|
@@ -203,15 +258,19 @@ VALUE augeas_match(VALUE s, VALUE p) {
|
|
203
258
|
*/
|
204
259
|
VALUE augeas_save(VALUE s) {
|
205
260
|
augeas *aug = aug_handle(s);
|
206
|
-
int callValue = aug_save(aug) ;
|
207
|
-
VALUE returnValue ;
|
208
261
|
|
209
|
-
|
210
|
-
|
211
|
-
else
|
212
|
-
returnValue = Qfalse ;
|
262
|
+
return (aug_save(aug) == 0) ? Qtrue : Qfalse;
|
263
|
+
}
|
213
264
|
|
214
|
-
|
265
|
+
/*
|
266
|
+
* call-seq:
|
267
|
+
* save() -> int
|
268
|
+
*
|
269
|
+
* Write all pending changes to disk
|
270
|
+
*/
|
271
|
+
VALUE facade_save(VALUE s) {
|
272
|
+
augeas *aug = aug_handle(s);
|
273
|
+
return INT2FIX(aug_save(aug));
|
215
274
|
}
|
216
275
|
|
217
276
|
/*
|
@@ -283,7 +342,7 @@ VALUE augeas_defnode(VALUE s, VALUE name, VALUE expr, VALUE value) {
|
|
283
342
|
return (r < 0) ? Qfalse : INT2NUM(r);
|
284
343
|
}
|
285
344
|
|
286
|
-
VALUE
|
345
|
+
static VALUE init(VALUE class, VALUE m, VALUE r, VALUE l, VALUE f) {
|
287
346
|
unsigned int flags = NUM2UINT(f);
|
288
347
|
const char *root = StringValueCStrOrNull(r);
|
289
348
|
const char *loadpath = StringValueCStrOrNull(l);
|
@@ -293,7 +352,15 @@ VALUE augeas_init(VALUE m, VALUE r, VALUE l, VALUE f) {
|
|
293
352
|
if (aug == NULL) {
|
294
353
|
rb_raise(rb_eSystemCallError, "Failed to initialize Augeas");
|
295
354
|
}
|
296
|
-
return Data_Wrap_Struct(
|
355
|
+
return Data_Wrap_Struct(class, NULL, augeas_free, aug);
|
356
|
+
}
|
357
|
+
|
358
|
+
VALUE augeas_init(VALUE m, VALUE r, VALUE l, VALUE f) {
|
359
|
+
return init(c_augeas, m, r, l, f);
|
360
|
+
}
|
361
|
+
|
362
|
+
VALUE facade_init(VALUE m, VALUE r, VALUE l, VALUE f) {
|
363
|
+
return init(c_facade, m, r, l, f);
|
297
364
|
}
|
298
365
|
|
299
366
|
VALUE augeas_close (VALUE s) {
|
@@ -383,10 +450,117 @@ VALUE augeas_span(VALUE s, VALUE path) {
|
|
383
450
|
return result;
|
384
451
|
}
|
385
452
|
|
453
|
+
/*
|
454
|
+
* call-seq:
|
455
|
+
* srun(COMMANDS) -> [int, String]
|
456
|
+
*
|
457
|
+
* Run one or more newline-separated commands, returning their output.
|
458
|
+
*
|
459
|
+
* Returns:
|
460
|
+
* an array where the first element is the number of executed commands on
|
461
|
+
* success, -1 on failure, and -2 if a 'quit' command was encountered.
|
462
|
+
* The second element is a string of the output from all commands.
|
463
|
+
*/
|
464
|
+
VALUE augeas_srun(VALUE s, VALUE text) {
|
465
|
+
augeas *aug = aug_handle(s);
|
466
|
+
const char *ctext = StringValueCStr(text);
|
467
|
+
int r;
|
468
|
+
VALUE result;
|
469
|
+
struct memstream ms;
|
470
|
+
__aug_init_memstream(&ms);
|
471
|
+
|
472
|
+
r = aug_srun(aug, ms.stream, ctext);
|
473
|
+
__aug_close_memstream(&ms);
|
474
|
+
|
475
|
+
result = rb_ary_new();
|
476
|
+
rb_ary_push(result, INT2NUM(r));
|
477
|
+
rb_ary_push(result, rb_str_new2(ms.buf));
|
478
|
+
|
479
|
+
free(ms.buf);
|
480
|
+
return result;
|
481
|
+
}
|
482
|
+
|
483
|
+
/*
|
484
|
+
* call-seq:
|
485
|
+
* label(PATH) -> String
|
486
|
+
*
|
487
|
+
* Lookup the label associated with PATH
|
488
|
+
*/
|
489
|
+
VALUE augeas_label(VALUE s, VALUE path) {
|
490
|
+
augeas *aug = aug_handle(s);
|
491
|
+
const char *cpath = StringValueCStr(path);
|
492
|
+
const char *label;
|
493
|
+
|
494
|
+
aug_label(aug, cpath, &label);
|
495
|
+
if (label != NULL) {
|
496
|
+
return rb_str_new(label, strlen(label)) ;
|
497
|
+
} else {
|
498
|
+
return Qnil;
|
499
|
+
}
|
500
|
+
}
|
501
|
+
|
502
|
+
/*
|
503
|
+
* call-seq:
|
504
|
+
* rename(SRC, LABEL) -> int
|
505
|
+
*
|
506
|
+
* Rename the label of all nodes matching SRC to LABEL.
|
507
|
+
*
|
508
|
+
* Returns +false+ if +aug_rename+ fails, and the number of nodes renamed
|
509
|
+
* on success.
|
510
|
+
*/
|
511
|
+
VALUE augeas_rename(VALUE s, VALUE src, VALUE label) {
|
512
|
+
augeas *aug = aug_handle(s);
|
513
|
+
const char *csrc = StringValueCStr(src);
|
514
|
+
const char *clabel = StringValueCStr(label);
|
515
|
+
int r = aug_rename(aug, csrc, clabel);
|
516
|
+
|
517
|
+
return (r < 0) ? Qfalse : INT2NUM(r);
|
518
|
+
}
|
519
|
+
|
520
|
+
/*
|
521
|
+
* call-seq:
|
522
|
+
* text_store(LENS, NODE, PATH) -> boolean
|
523
|
+
*
|
524
|
+
* Use the value of node NODE as a string and transform it into a tree
|
525
|
+
* using the lens LENS and store it in the tree at PATH, which will be
|
526
|
+
* overwritten. PATH and NODE are path expressions.
|
527
|
+
*/
|
528
|
+
VALUE augeas_text_store(VALUE s, VALUE lens, VALUE node, VALUE path) {
|
529
|
+
augeas *aug = aug_handle(s);
|
530
|
+
const char *clens = StringValueCStr(lens);
|
531
|
+
const char *cnode = StringValueCStr(node);
|
532
|
+
const char *cpath = StringValueCStr(path);
|
533
|
+
int r = aug_text_store(aug, clens, cnode, cpath);
|
534
|
+
|
535
|
+
return (r < 0) ? Qfalse : Qtrue;
|
536
|
+
}
|
537
|
+
|
538
|
+
/*
|
539
|
+
* call-seq:
|
540
|
+
* text_retrieve(LENS, NODE_IN, PATH, NODE_OUT) -> boolean
|
541
|
+
*
|
542
|
+
* Transform the tree at PATH into a string using lens LENS and store it in
|
543
|
+
* the node NODE_OUT, assuming the tree was initially generated using the
|
544
|
+
* value of node NODE_IN. PATH, NODE_IN, and NODE_OUT are path expressions.
|
545
|
+
*/
|
546
|
+
VALUE augeas_text_retrieve(VALUE s, VALUE lens, VALUE node_in, VALUE path, VALUE node_out) {
|
547
|
+
augeas *aug = aug_handle(s);
|
548
|
+
const char *clens = StringValueCStr(lens);
|
549
|
+
const char *cnode_in = StringValueCStr(node_in);
|
550
|
+
const char *cpath = StringValueCStr(path);
|
551
|
+
const char *cnode_out = StringValueCStr(node_out);
|
552
|
+
int r = aug_text_retrieve(aug, clens, cnode_in, cpath, cnode_out);
|
553
|
+
|
554
|
+
return (r < 0) ? Qfalse : Qtrue;
|
555
|
+
}
|
556
|
+
|
386
557
|
void Init__augeas() {
|
387
558
|
|
388
559
|
/* Define the ruby class */
|
389
560
|
c_augeas = rb_define_class("Augeas", rb_cObject) ;
|
561
|
+
rb_undef_alloc_func(c_augeas);
|
562
|
+
c_facade = rb_define_class_under(c_augeas, "Facade", rb_cObject);
|
563
|
+
rb_undef_alloc_func(c_facade);
|
390
564
|
|
391
565
|
/* Constants for enum aug_flags */
|
392
566
|
#define DEF_AUG_FLAG(name) \
|
@@ -414,6 +588,11 @@ void Init__augeas() {
|
|
414
588
|
DEF_AUG_ERR(ESYNTAX);
|
415
589
|
DEF_AUG_ERR(ENOLENS);
|
416
590
|
DEF_AUG_ERR(EMXFM);
|
591
|
+
DEF_AUG_ERR(ENOSPAN);
|
592
|
+
DEF_AUG_ERR(EMVDESC);
|
593
|
+
DEF_AUG_ERR(ECMDRUN);
|
594
|
+
DEF_AUG_ERR(EBADARG);
|
595
|
+
DEF_AUG_ERR(ELABEL);
|
417
596
|
#undef DEF_AUG_ERR
|
418
597
|
|
419
598
|
/* Define the methods */
|
@@ -433,6 +612,35 @@ void Init__augeas() {
|
|
433
612
|
rb_define_method(c_augeas, "close", augeas_close, 0);
|
434
613
|
rb_define_method(c_augeas, "error", augeas_error, 0);
|
435
614
|
rb_define_method(c_augeas, "span", augeas_span, 1);
|
615
|
+
rb_define_method(c_augeas, "srun", augeas_srun, 1);
|
616
|
+
rb_define_method(c_augeas, "label", augeas_label, 1);
|
617
|
+
rb_define_method(c_augeas, "rename", augeas_rename, 2);
|
618
|
+
rb_define_method(c_augeas, "text_store", augeas_text_store, 3);
|
619
|
+
rb_define_method(c_augeas, "text_retrieve", augeas_text_retrieve, 4);
|
620
|
+
|
621
|
+
/* Define methods to support the 'new' API in Augeas::Facade */
|
622
|
+
rb_define_singleton_method(c_facade, "open3", facade_init, 3);
|
623
|
+
/* The `close` and `error` methods as used unchanged in the ruby bindings */
|
624
|
+
rb_define_method(c_facade, "close", augeas_close, 0);
|
625
|
+
rb_define_method(c_facade, "error", augeas_error, 0);
|
626
|
+
rb_define_method(c_facade, "augeas_defvar", augeas_defvar, 2);
|
627
|
+
rb_define_method(c_facade, "augeas_defnode", augeas_defnode, 3);
|
628
|
+
rb_define_method(c_facade, "augeas_get", augeas_get, 1);
|
629
|
+
rb_define_method(c_facade, "augeas_exists", augeas_exists, 1);
|
630
|
+
rb_define_method(c_facade, "augeas_insert", augeas_insert, 3);
|
631
|
+
rb_define_method(c_facade, "augeas_mv", augeas_mv, 2);
|
632
|
+
rb_define_method(c_facade, "augeas_rm", augeas_rm, 1);
|
633
|
+
rb_define_method(c_facade, "augeas_match", facade_match, 1);
|
634
|
+
rb_define_method(c_facade, "augeas_save", facade_save, 0);
|
635
|
+
rb_define_method(c_facade, "augeas_load", augeas_load, 0);
|
636
|
+
rb_define_method(c_facade, "augeas_set", facade_set, 2);
|
637
|
+
rb_define_method(c_facade, "augeas_setm", augeas_setm, 3);
|
638
|
+
rb_define_method(c_facade, "augeas_span", augeas_span, 1);
|
639
|
+
rb_define_method(c_facade, "augeas_srun", augeas_srun, 1);
|
640
|
+
rb_define_method(c_facade, "augeas_label", augeas_label, 1);
|
641
|
+
rb_define_method(c_facade, "augeas_rename", augeas_rename, 2);
|
642
|
+
rb_define_method(c_facade, "augeas_text_store", augeas_text_store, 3);
|
643
|
+
rb_define_method(c_facade, "augeas_text_retrieve", augeas_text_retrieve, 4);
|
436
644
|
}
|
437
645
|
|
438
646
|
/*
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/*
|
2
|
+
* augeas.h: internal headers for Augeas Ruby bindings
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2011 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
|
+
|
21
|
+
#include <ruby.h>
|
22
|
+
|
23
|
+
#ifndef _AUGEAS_H_
|
24
|
+
#define _AUGEAS_H_
|
25
|
+
|
26
|
+
#define StringValueCStrOrNull(v) \
|
27
|
+
NIL_P(v) ? NULL : StringValueCStr(v)
|
28
|
+
|
29
|
+
/* memstream support from Augeas internal.h */
|
30
|
+
struct memstream {
|
31
|
+
FILE *stream;
|
32
|
+
char *buf;
|
33
|
+
size_t size;
|
34
|
+
};
|
35
|
+
|
36
|
+
int __aug_init_memstream(struct memstream *ms);
|
37
|
+
int __aug_close_memstream(struct memstream *ms);
|
38
|
+
|
39
|
+
#endif
|
40
|
+
|
41
|
+
/*
|
42
|
+
* Local variables:
|
43
|
+
* indent-tabs-mode: nil
|
44
|
+
* c-indent-level: 4
|
45
|
+
* c-basic-offset: 4
|
46
|
+
* tab-width: 4
|
47
|
+
* End:
|
48
|
+
*/
|