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.
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)