commit c12a9d015ed92c1b16b6e8ffaef2f0cd132860bc
parent cf1a6751aaca3dbb6c8acd16c3d24e917788ee5c
Author: Nathaniel Chappelle <nathaniel@chappelle.dev>
Date: Sat, 24 Jan 2026 14:47:57 -0800
made parser into callback machine
Diffstat:
4 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile
@@ -17,5 +17,8 @@ json.o: json.c json.h jsmn.h
clean:
rm -f $(OBJ) $(BIN)
+messages:
+ notmuch show --format=json '*' | ./stamail
+
.PHONY: all clean
diff --git a/json.c b/json.c
@@ -9,7 +9,8 @@ static int tok_streq(const char *js, jsmntok_t *t, const char *s) {
strncmp(js + t->start, s, t->end - t->start) == 0);
}
-static void scan(const char *js, jsmntok_t *t, int *i, int ntok) {
+static void scan(const char *js, jsmntok_t *t, int *i, int ntok,
+ message_cb cb, void *ud) {
if (*i >= ntok) return;
if (t[*i].type == JSMN_OBJECT) {
@@ -95,14 +96,22 @@ static void scan(const char *js, jsmntok_t *t, int *i, int ntok) {
/* If this object looks like a message, print it */
if (id && subject && from && date) {
- printf("Message-ID: %.*s\n", id_len, id);
- printf("From: %.*s\n", from_len, from);
- printf("Subject: %.*s\n", subject_len, subject);
- printf("Date: %.*s\n", date_len, date);
- if (body) {
- printf("Body:\n%.*s\n", body_len, body);
- }
- printf("--------------------------------------------------\n");
+ struct message m = {
+ .id = id, .id_len = id_len,
+ .from = from, .from_len = from_len,
+ .subject = subject, .subject_len = subject_len,
+ .date = date, .date_len = date_len,
+ .body = body, .body_len = body_len
+ };
+ cb(&m, ud);
+ // printf("Message-ID: %.*s\n", id_len, id);
+ // printf("From: %.*s\n", from_len, from);
+ // printf("Subject: %.*s\n", subject_len, subject);
+ // printf("Date: %.*s\n", date_len, date);
+ // if (body) {
+ // printf("Body:\n%.*s\n", body_len, body);
+ // }
+ // printf("--------------------------------------------------\n");
}
return;
}
@@ -112,7 +121,7 @@ static void scan(const char *js, jsmntok_t *t, int *i, int ntok) {
int n = t[*i].size;
(*i)++;
for (int k = 0; k < n; k++) {
- scan(js, t, i, ntok);
+ scan(js, t, i, ntok, cb, ud);
}
return;
}
@@ -120,7 +129,7 @@ static void scan(const char *js, jsmntok_t *t, int *i, int ntok) {
(*i)++;
}
-void parse_mail_json(const char *json, int len) {
+void parse_mail_json(const char *json, int len, message_cb cb, void* userdata) {
jsmn_parser p;
jsmn_init(&p);
@@ -132,6 +141,6 @@ void parse_mail_json(const char *json, int len) {
}
int i = 0;
- scan(json, tokens, &i, ntok);
+ scan(json, tokens, &i, ntok, cb, userdata);
}
diff --git a/json.h b/json.h
@@ -1,8 +1,19 @@
#ifndef JSON_H
#define JSON_H
+struct message {
+ const char *id; int id_len;
+ const char *from; int from_len;
+ const char *subject;int subject_len;
+ const char *date; int date_len;
+ const char *body; int body_len;
+};
+
+/* Called for every message found */
+typedef void (*message_cb)(struct message *m, void *userdata);
+
/* Parse JSON buffer and print extracted mail fields */
-void parse_mail_json(const char *json, int len);
+void parse_mail_json(const char *json, int len, message_cb cb, void *userdata);
#endif
diff --git a/stamail.c b/stamail.c
@@ -2,6 +2,20 @@
#include <stdlib.h>
#include "json.h"
+/* Current callback handler */
+static void print_message(struct message *m, void *ud) {
+ (void)ud;
+
+ printf("Message-ID: %.*s\n", m->id_len, m->id);
+ printf("From: %.*s\n", m->from_len, m->from);
+ printf("Subject: %.*s\n", m->subject_len, m->subject);
+ printf("Date: %.*s\n", m->date_len, m->date);
+ if (m->body) {
+ printf("Body:\n%.*s\n", m->body_len, m->body);
+ }
+ printf("--------------------------------------------------\n");
+}
+
int main(void) {
/* Slurp stdin */
char *buf = NULL;
@@ -22,7 +36,7 @@ int main(void) {
if (!buf) return 0;
- parse_mail_json(buf, len);
+ parse_mail_json(buf, len, print_message, NULL);
free(buf);
return 0;