Re: [OFF TOPIC] Perl Question

From: Daniel A. Koepke (
Date: 06/22/01

On Fri, 22 Jun 2001, Robert Masten wrote:

> what's that perl 'one liner' to search and replace through-out a
> directory?

Well, the regular expression for global search-and-replace is s/old/new/g,
so we get something like

  perl -p -i.bak -e 's/foo/bar/g' *.c

where 'foo' is any regular expression and 'bar' can contain references to
the text matched by the regular expressions.  So, to replace all
occurances of GET_NAME with CHAR_NAME you could do:

  perl -p -i.bak -e 's/GET_NAME\(/CHAR_NAME\(/g' *.[ch]

It's pretty simple to remember: the stuff in the s//g is all that'll be
changing for most uses.  (This creates backup files for you, BTW, each
named *.[ch].bak.)


A wonderfully hackish part of a scheme to automate loading XML database
files by the use of tables:

  #define OFFSET(_struct, _memb) ((off_t) &(((_struct *) 0x0)->_memb))
  #define MEMBER(_st, _of, _ty)  *((_ty *) ((off_t) (_st) + (_of)))

You can test the validity of this weirdness with a test program like:

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  #include "offset.h" /* above #defines, etc. */

  #define NINPUTS 3
  enum { T_INT, T_STR, T_REAL };

  struct foobar_data {
    int a;
    char *b;
    double c;

  const struct table_data {
    const char *input;
    off_t offset;
    int type;
  } intab[NINPUTS] = {
    { "12345678", OFFSET(struct foobar_data, a), T_INT  },
    { "testing1", OFFSET(struct foobar_data, b), T_STR  },
    { "3.141592", OFFSET(struct foobar_data, c), T_REAL }

  int main(void)
    struct foobar_data foo;
    register int i;

    for (i = 0; i < NINPUTS; i++) {
      switch (intab[i].type) {
      case T_INT:
        MEMBER(&foo, intab[i].offset, int) = atoi(intab[i].input);
      case T_STR:
        MEMBER(&foo, intab[i].offset, char *) = strdup(intab[i].input);
      case T_REAL:
        MEMBER(&foo, intab[i].offset, double) = strtod(intab[i].input, 0);

           "  a: %d\n"
           "  b: %s\n"
           "  c: %f\n", foo->a, foo->b, foo->c);
    return (0);

which should print

    a: 12345678
    b: testing1
    c: 3.141592

The eventual goal is to make it possible to simply specify the tags and
attributes that, say, a mobile record contains, pass that table to a
function which parses an XML tag tree in accord with the table, and does
the rest for us.  The only component I'm missing at present in this is the
table reader (I've already got a module using expat to generate an XML
tree [stack] for later parsing by these routines), which should be fairly
easy to write (pretty much the same as the above Mailer Code(tm)).

BTW, if anyone's familiar with expat (or other SAX-compliant parsers) and
wants to dictate to me about good parsing strategies, I'd absolutely love
it.  I don't know if just throwing together a stack and then parsing the
stack is the most elegant way to do things -- it's definitely not the most

Daniel A. Koepke (dak),
Caveat emptor: I say what I mean and mean what I say.  Listen well.
Caveat venditor: Say what you mean, mean what you say.  Say it well.

   | FAQ: |
   | Archives: |

This archive was generated by hypermail 2b30 : 12/05/01 PST