regex - Search and replace within a file using PCRE in C -


i want parse shell style key-value config file c , replace values needed. example file like

foo="test" some_key="some value here" another_key="here.we.go" something="0" foo_bar_baz="2" 

to find value, want use regular expressions. i'm beginner pcre library created code test around. application takes 2 arguments: first 1 key search for. second 1 value fill double quotes.

#include <pcre.h> #include <string.h> #include <stdio.h> #include <stdlib.h>  #define oveccount 30  int main(int argc, char **argv){     const char *error;     int   erroffset;     pcre *re;     int   rc;     int   i;     int   ovector[oveccount];      char regex[64];      sprintf(regex,"(?<=^%s=\\\").+(?<!\\\")", argv[1]);      char *str;     file *conf;     conf = fopen("test.conf", "rw");     fseek(conf, 0, seek_end);     int confsize = ftell(conf)+1;     rewind(conf);     str = malloc(confsize);     fread(str, 1, confsize, conf);     fclose(conf);     str[confsize-1] = '\n';      re = pcre_compile (          regex,       /* pattern */          pcre_caseless | pcre_multiline, /* default options */          &error,               /* error message */          &erroffset,           /* error offset */          0);                   /* use default character tables */      if (!re) {         printf("pcre_compile failed (offset: %d), %s\n", erroffset, error);         return -1;     }      rc = pcre_exec (         re,                   /* compiled pattern */         0,                    /* no data - pattern not studied */         str,                  /* string match */         confsize,          /* length of string */         0,                    /* start @ offset 0 in subject */         0,                    /* default options */         ovector,              /* output vector substring information */         oveccount);           /* number of elements in output vector */      if (rc < 0) {         switch (rc) {             case pcre_error_nomatch:                 printf("string didn't match");                 break;              default:                 printf("error while matching: %d\n", rc);                 break;         }         free(re);         return -1;     }      (i = 0; < rc; i++) {         printf("========\nlength of vector: %d\nvector[0..1]: %d %d\nchars @ start/end: %c %c\n", ovector[2*i+1] - ovector[2*i], ovector[0], ovector[1], str[ovector[0]], str[ovector[1]]);         printf("file content length %d\n========\n", strlen(str));     }     int newcontentlen = strlen(argv[2])+1;     char *newcontent = calloc(newcontentlen,1);     memcpy(newcontent, argv[2], newcontentlen);      char *before = malloc(ovector[0]);     memcpy(before, str, ovector[0]);      int afterlen = confsize-ovector[1];     char *after = malloc(afterlen);     memcpy(after, str+ovector[1],afterlen);      int newfilelen = newcontentlen+ovector[0]+afterlen;     char *newfile = calloc(newfilelen,1);      sprintf(newfile,"%s%s%s", before,newcontent, after);      printf("%s\n", newfile);     return 0; } 

this code working in cases if want replace foo or another_key theres fishy.

$ ./search_replace.out foo baz ======== length of vector: 5 vector[0..1]: 5 10 chars @ start/end: b " file content length 94 ======== foo="9@baz" some_key="some value here" another_key="here.we.go" something="0" foo_bar_baz="2"  $ ./search_replace.out another_key insert ======== length of vector: 10 vector[0..1]: 52 62 chars @ start/end: h " file content length 94 ======== foo="baaar" some_key="some value here" another_key=")insert" something="0" foo_bar_baz="2" 

now if change format of input file to

test="new inserted" foo="test" some_key="some value here"  another_key="here.we.go" something="0" foo_bar_baz="2" 

the code working fine. don't why code behaves differently here.

the characters before substituted text come not null-terminating before string. (just hadn't null-terminated whole buffer str, paul r has pointed out.) so:

char *before = malloc(ovector[0] + 1); memcpy(before, str, ovector[0]); before[ovector[0]] = '\0'; 

anyway, business of allocating substrings , copying contents seems needlessly complicated , prone errors. example, somethinglen variables count terminating null character or not? do, don't. i'd recommend pick 1 representation , use consistently. (and should free allocated buffers after no longer using them , clean compiled regex.)

you replacement 1 allocation target buffer using precision field of %s format specifier on "before" part:

int cutlen = ovector[1] - ovector[0]; int newfilelen = confsize + strlen(argv[2]) - cutlen; char *newfile = malloc(newfilelen + 1);  snprintf(newfile, newfilelen + 1, "%.*s%s%s",      ovector[0], str, argv[2], str + ovector[1]); 

or use fprintf ther target file if don't need temporary buffer.


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

python - Django-cities exits with "killed" -

python - How to get a widget position inside it's layout in Kivy? -