Skip to content

Instantly share code, notes, and snippets.

@guilt
Last active December 13, 2023 14:02
Show Gist options
  • Save guilt/9e5ec112442a7a11f5ef1809f69aa387 to your computer and use it in GitHub Desktop.
Save guilt/9e5ec112442a7a11f5ef1809f69aa387 to your computer and use it in GitHub Desktop.
Binary Grep and Binary Pattern Replace
#include <stdio.h>
#include <string.h>
void usage(char* progname) {
fprintf(stderr, "%s pattern [files]\n", progname);
}
void search(char* pattern, FILE* in, char* prefix) {
int c;
unsigned long long offset = 0;
unsigned long long foundOffset = offset;
char* start = pattern;
if (!in) in = stdin;
c = fgetc(in);
while (c != EOF) {
if (c == *start) {
if (start == pattern) foundOffset = offset;
++start;
}
else {
start = pattern;
}
if (!*start) {
if (prefix && *prefix) printf("%s:", prefix);
printf("%llu\n", foundOffset);
start = pattern;
}
++offset;
c = fgetc(in);
}
}
int main(int argc, char* argv[]) {
char* pattern;
int i;
if (argc < 2) {
usage(argv[0]);
return -1;
}
pattern = argv[1];
for (i = 2; i < argc; ++i) {
FILE* in = NULL;
char* prefix = NULL;
if (strcmp(argv[i], "-") != 0) {
prefix = argv[i];
in = fopen(argv[i], "rb");
if (!in) {
fprintf(stderr, "Unable to open: %s\n", argv[i]);
return -1;
}
}
search(pattern, in, prefix);
if (in) fclose(in);
}
return 0;
}
#include <stdio.h>
#include <string.h>
void usage(char* progname) {
fprintf(stderr, "%s pattern modPattern [file] [fileOut]\n", progname);
fprintf(stderr,
"\tNOTE: modPattern and pattern must be of the same length\n");
}
void searchAndReplace(char* pattern, char* modPattern, FILE* in, FILE* out) {
int c;
unsigned long long offset = 0;
unsigned long long foundOffset = offset;
char* start = pattern;
if (!in) in = stdin;
if (!out) out = stdout;
c = fgetc(in);
while (c != EOF) {
if (c == *start) {
if (start == pattern) foundOffset = offset;
++start;
}
else {
if (start != pattern) {
fwrite(pattern, offset - foundOffset, sizeof(char), out);
}
fputc(c, out);
start = pattern;
}
if (!*start) {
fwrite(modPattern, offset - foundOffset + 1, sizeof(char), out);
start = pattern;
}
++offset;
c = fgetc(in);
}
}
int main(int argc, char* argv[]) {
char* pattern;
char* modPattern;
FILE* in = NULL;
FILE* out = NULL;
if (argc < 3) {
usage(argv[0]);
return -1;
}
pattern = argv[1];
modPattern = argv[2];
if (strlen(pattern) != strlen(modPattern)) {
usage(argv[0]);
return -1;
}
if (argc > 3 && strcmp(argv[3], "-") != 0) {
in = fopen(argv[3], "rb");
if (!in) {
fprintf(stderr, "Unable to open: %s\n", argv[3]);
return -1;
}
}
if (argc > 4 && strcmp(argv[4], "-") != 0) {
out = fopen(argv[4], "wb");
if (!out) {
fprintf(stderr, "Unable to open: %s\n", argv[4]);
return -1;
}
}
searchAndReplace(pattern, modPattern, in, out);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment