Skip to content

Instantly share code, notes, and snippets.

@jgrar
Last active December 25, 2015 19:29
Show Gist options
  • Save jgrar/7028548 to your computer and use it in GitHub Desktop.
Save jgrar/7028548 to your computer and use it in GitHub Desktop.
An rfc compliant irc parser in C.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
enum symbols { NEWLINE, SPACE, COLON };
#define SYMBOLS { '\n', ' ', ':', '\0'};
char line[32][256];
int delim(FILE *fp, char *dest, char *delims, char **pos) {
int c;
char *p;
while ((c = fgetc(fp)) != EOF) {
if ((p = strchr(delims, c)) != NULL) {
*pos = dest;
return p - delims;
}
*dest++ = c;
}
return -1;
}
int parse(FILE *fp) {
char sym[] = SYMBOLS
char *p;
int i;
i = 0;
p = line[0];
for (;;) {
switch (delim(fp, p, sym, &p)) {
case EOF:
goto FAIL;
break;
case NEWLINE:
if (p != line[i] && *(p - 1) == '\r') {
*(p - 1) = '\0';
goto DONE;
}
break;
case SPACE:
*p = '\0';
p = line[++i];
break;
case COLON:
*p = ':';
if (i != 0 && p == line[i]) {
sym[SPACE] = '\0'; /* truncate */
}
p++;
break;
}
}
DONE:
return i+1;
FAIL:
return EOF;
}
/*-\-\-----------------------------------------------------------------/-/-*/
/*-/-/-----------------------------------------------------------------\-\-*/
int main (int argc, char *argv[]) {
FILE *fp;
int t, i, j, n;
if (argc < 2) {
fputs("no arguments\n", stderr);
exit(EXIT_FAILURE);
}
for (t = 1; argv[t]; t++) {
fp = fopen(argv[t], "r");
if (!fp) {
fprintf(stderr, "failed to open file: %s\n", argv[t]);
continue;
}
printf("opened: %s\n", argv[t]);
for (; !feof(fp); puts("\n")) {
memset(line, '\0', sizeof line);
n = parse(fp);
if (n <= 0) {
continue;
}
printf("Message, %d parts:\n", n);
i = 0;
if (line[0][0] == ':') {
printf("prefix: %s\n", line[0]);
i++;
}
printf("command: %s\n", line[i++]);
n--;
for (j = 0; i+j < n; j++) {
printf("\t[%-.2d] => '%s'\n", j, line[i + j]);
}
if (line[n][0] == ':') {
printf("trailing: %s\n", line[n]);
} else {
printf("\t[%-.2d] => '%s'\n", j, line[n]);
}
}
}
exit(EXIT_SUCCESS);
}
$ ./a.out <(echo -en ':nick!user@net COMMAND a b:ds :b b adas lasda\r\n')
opened: /dev/fd/63
Message, 5 parts:
prefix: :nick!user@net
command: COMMAND
[00] => 'a'
[01] => 'b:ds'
trailing: :b b adas lasda
@jgrar
Copy link
Author

jgrar commented Oct 17, 2013

need to fix up the output
too lazy tho

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment