source: branches/stable/TOOLS/arb_replace.cxx

Last change on this file was 16374, checked in by westram, 7 years ago
  • reintegrates 'aci' into 'trunk'
    • refactored wide parts of ACI code (incl. SRT+REG)
      • added more test
      • ACI tracing
        • more complete and readable
        • automatically turned off when done with expression
      • improved error messages (esp. diagnostics)
      • documentation (updated, added missing)
      • fixed a bunch of bugs (incl. SEGV and deadlock)
      • ACI now runs inside execution environment
    • ACI language may be extended with custom commands (implements #756)
      • added ACI extension for group-batch-rename
  • adds:
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : arb_replace.cxx                                   //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <arb_strbuf.h>
12#include <arb_file.h>
13#include <arbdb.h>
14
15int ARB_main(int argc, char *argv[]) {
16    char       *data;
17    char       *ndata;
18    FILE       *out;
19    int         arg;
20    const char *eval;
21    const char *fname;
22    int         linemode           = false;
23    int         delete_empty_lines = false;
24    int         startarg;
25    int         patchmode          = false;
26
27    if (argc <= 1 || (argc >= 2 && strcmp(argv[1], "--help") == 0)) {
28        printf("syntax: arb_replace [-l/L/p] \"old=newdata\" [filepattern]\n");
29        printf("        -l      linemode, parse each line separately\n");
30        printf("        -L      linemode, parse each line separately, delete empty lines\n");
31        printf("        -p      patchmode, (no wildcards allowed, rightside<leftside)\n");
32        return -1;
33    }
34    if (!strcmp(argv[1], "-l")) {
35        eval               = argv[2];
36        linemode           = true;
37        startarg           = 3;
38    }
39    else if (!strcmp(argv[1], "-L")) {
40        eval               = argv[2];
41        linemode           = true;
42        delete_empty_lines = true;
43        startarg           = 3;
44    }
45    else if (!strcmp(argv[1], "-p")) {
46        eval      = argv[2];
47        patchmode = true;
48        startarg  = 3;
49    }
50    else {
51        eval     = argv[1];
52        startarg = 2;
53    }
54    int usestdin = false;
55    if (startarg==argc) {
56        usestdin = true;                            // stdin stdout
57        argc++;
58    }
59
60    for (arg = startarg; arg<argc; arg++) {
61        if (usestdin) {
62            fname = "-";
63        }
64        else {
65            fname = argv[arg];
66        }
67        data = GB_read_file(fname);
68        if (data) {
69            if (patchmode) {
70                char *evaldup = strdup(eval);
71                char *right   = strchr(evaldup, '=');
72
73                int result = 0;
74                if (!right) {
75                    fprintf(stderr, "'=' not found in replace string\n");
76                    result = -1;
77                }
78                else {
79                    if (strlen(right) > strlen(evaldup)) {
80                        fprintf(stderr, "You cannot replace a shorter string by a longer one!!!\n");
81                        result = -1;
82                    }
83                    else {
84                        *(right++) = 0;
85
86                        int           leftsize = strlen(evaldup);
87                        unsigned long size     = GB_size_of_file(fname)-leftsize;
88
89                        bool patched = false;
90                        for (unsigned long i=0; i<size; i++) {
91                            if (!strncmp(data+i, evaldup, leftsize)) {
92                                strcpy(data+i, right);
93                                patched = true;
94                            }
95                        }
96                        if (patched) {
97                            out = fopen(fname, "w");
98                            if (out) {
99                                if (fwrite(data, (unsigned int)size, 1, out) != 1) {
100                                    fprintf(stderr, "Write failed %s\n", fname);
101                                    result = -1;
102                                }
103                                else {
104                                    fprintf(out, "%s", data);
105                                    printf("File %s parsed\n", fname);
106                                }
107                                fclose(out);
108                            }
109                            else {
110                                fprintf(stderr, "Write failed %s\n", fname);
111                                result = -1;
112                            }
113                        }
114                    }
115                }
116                free(evaldup);
117                return result;
118            }
119
120            if (linemode) {
121                char          *p         = data;
122                char          *nextp;
123                char          *h;
124                GBS_strstruct *strstruct = GBS_stropen(1024);
125
126                while ((nextp = strchr(p, '\n'))) {
127                    nextp[0] = 0;                       // remove '\n'
128                    h = GBS_string_eval(p, eval);
129                    if (!h) {
130                        h = strdup (p);
131                        fprintf(stderr, "%s\n", GB_await_error());
132                    }
133
134                    if (usestdin) {
135                        fprintf(stdout, "%s", h);
136                        if (h[0] || !delete_empty_lines) {
137                            fprintf(stdout, "\n");
138                        }
139                    }
140                    else {
141                        GBS_strcat(strstruct, h);
142                        if (h[0] || !delete_empty_lines) {      // delete empty lines
143                            GBS_chrcat(strstruct, '\n');         // insert '\n'
144                        }
145                    }
146                    p = nextp+1;
147                    nextp[0] = '\n';            // reinsert '\n'
148                    free(h);
149                }
150                h = GBS_string_eval(p, eval);
151                GBS_strcat(strstruct, h);
152                ndata = GBS_strclose(strstruct);
153                free(h);
154
155            }
156            else {
157                ndata = GBS_string_eval(data, eval);
158            }
159
160            if (!ndata) {
161                fprintf(stderr, "%s\n", GB_await_error());
162                exit(-1);
163            }
164            if (strcmp(data, ndata)) {
165                if (usestdin) {
166                    fprintf(stdout, "%s", ndata);
167                }
168                else {
169                    out = fopen(fname, "w");
170                    if (out) {
171                        fprintf(out, "%s", ndata);
172                        fclose(out);
173                        printf("File %s parsed\n", fname);
174                    }
175                    else {
176                        printf("cannot write %s\n", fname);
177                    }
178                }
179            }
180            free(ndata);
181            free(data);
182        }
183    }
184    return 0;
185}
Note: See TracBrowser for help on using the repository browser.