void irc_parse(struct Buffer* b) { register char* p = b->buf, *line = p; size_t bytes_parsed = 0; struct Command* command; struct Sender sender; while (p <= (b->buf + b->bytes_used)) { if ((*p == '\r') || (*p == '\n')) { char* argv[32] = { NULL }; int argc = 0; while (((*p == '\r') || (*p == '\n')) && (p <= (b->buf + b->bytes_used))) *p++ = '\0'; bytes_parsed += (p - line); argv[argc++] = line; debug("line: %s", line); while ((line <= p) && (argc < 32)) { if (*line == ' ') { *line++ = '\0'; if (*line == ':') { argv[argc++] = ++line; while ((*line != ':') && (line <= p)) line++; continue; } argv[argc++] = line; } line++; } if (*argv[0] == ':') { if ((command = command_find(argv[1])) == NULL) goto keep_going; if (strlen(++argv[0]) > 3) { sender.s.client = client_find_by_uid(argv[0]); } else { sender.s.server = server_find_by_sid(argv[0]); sender.server = true; } } else { if ((command = command_find(argv[0])) == NULL) goto keep_going; sender.s.server = first_server; sender.server = true; } command->handler(&sender, argc, argv); keep_going: line = p; continue; } p++; } buffer_remove(b, bytes_parsed); }