ruby-augeas 0.4.1 → 0.6.0

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/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
- if (value != NULL) {
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) -> boolean
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
- augeas *aug = aug_handle(s);
88
- const char *cpath = StringValueCStr(path) ;
89
- const char *cvalue = StringValueCStrOrNull(value) ;
118
+ int callValue = set(s, path, value);
90
119
 
91
- int callValue = aug_set(aug, cpath, cvalue) ;
92
- VALUE returnValue ;
93
-
94
- if (callValue == 0)
95
- returnValue = Qtrue ;
96
- else
97
- returnValue = Qfalse ;
120
+ return (callValue == 0) ? Qtrue : Qfalse;
121
+ }
98
122
 
99
- return returnValue ;
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, VALUE sibling) {
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
- VALUE result = rb_ary_new();
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
- if (callValue == 0)
210
- returnValue = Qtrue ;
211
- else
212
- returnValue = Qfalse ;
262
+ return (aug_save(aug) == 0) ? Qtrue : Qfalse;
263
+ }
213
264
 
214
- return returnValue ;
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 augeas_init(VALUE m, VALUE r, VALUE l, VALUE f) {
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(c_augeas, NULL, augeas_free, aug);
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
+ */
@@ -27,4 +27,8 @@ unless pkg_config("augeas")
27
27
  raise "augeas-devel not installed"
28
28
  end
29
29
 
30
+ unless pkg_config("libxml-2.0")
31
+ raise "libxml2-devel not installed"
32
+ end
33
+
30
34
  create_makefile(extension_name)