LTSVパーサ(ltsview)をC言語で実装しました。

LTSVのログビューワーltsview (http://d.hatena.ne.jp/naoya/20130207/1360229220) のC言語版を作りました。

ソースコードはGithubにおいてあります。
https://github.com/DQNEO/c-ltsview

やる前は難しそうだと思っていたのですが、書いてみたら意外と簡単で、100行ほどでできました。
こんな感じです。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_MAX 10240
#define KEYS_MAX 100

struct item {
    char *key;
    char *value;
};

void parse_item(struct item *item, char *key_value);
int in_array(char *s, char **strings);

int main(int argc, char **argv)
{
    char *keys[KEYS_MAX];
    memset(keys, 0, sizeof(keys));
    int i;
    char *concate_keys;

    /* parse -k options */
    if (argc >= 2 && strcmp(argv[1],"-k") == 0) {
	if (argc == 2) {
	    fprintf(stderr, "no argument for -k option\n");
	    exit(1);
	}

	concate_keys = argv[2];

	keys[0] = strtok(concate_keys, ",");
	if (keys[0] != NULL) {
	    i = 1;
	    while((keys[i] = strtok(NULL, ",")) != NULL) {
		i++;
	    }
	}
    }

    char buf[BUF_MAX];
    struct item items[KEYS_MAX];
    char *tab;
    char *tmp;
    char *newline;

    while (fgets(buf, BUF_MAX, stdin) != NULL) {
	printf("=========\n");

	if (buf[BUF_MAX -2] != '\0') {
	    fprintf(stderr, "buffer over run!\n");
	    return 1;
	}

	tmp = buf;
	i = 0;
	memset(items,0, sizeof(items)); // is this right?
	while ((tab = strchr(tmp, '\t')) != NULL ) {
	    *tab = '\0';
	    parse_item(&items[i++], tmp);
	    tmp = tab + 1;
	}
	newline = strchr(tmp, '\n');
	*newline = '\0';
	parse_item(&items[i], tmp);

	for (i = 0;items[i].key != NULL;i++) {
	    if (keys[0] != NULL && ! in_array(items[i].key, keys)) {
		continue;
	    }
	    printf("%s: %s\n", items[i].key, items[i].value);
	}
    }

    return 0;
}

void parse_item(struct item *item, char *key_value)
{
    char *colon;
    colon = strchr(key_value, ':');
    if (colon == NULL) {
	fprintf(stderr, "invalid format:[%s]", key_value);
	exit(1);
    }
    *colon = '\0';
    item->key = key_value;
    item->value = colon + 1;
}

int in_array(char *s, char **strings)
{
    int j;
    for (j = 0; strings[j] != NULL; j++) {
	if (strcmp(s, strings[j]) == 0) {
	    return 1;  // found
	}
    }

    return 0; // not found
}
C言語はまだほんのド素人なので、この書き方はおかしいなどありましたらPull Requestをお待ちしております。
カテゴリ: