Skip to content

Instantly share code, notes, and snippets.

@jgrar
Last active December 25, 2015 19:29
Show Gist options
  • Select an option

  • Save jgrar/7028548 to your computer and use it in GitHub Desktop.

Select an option

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

jgrar commented Oct 17, 2013

Copy link
Copy Markdown
Author

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