Skip to content

Instantly share code, notes, and snippets.

@mrchrisadams
Created September 24, 2011 11:51
Show Gist options
  • Save mrchrisadams/1239235 to your computer and use it in GitHub Desktop.
Save mrchrisadams/1239235 to your computer and use it in GitHub Desktop.
static VALUE
rb_str_each_line(argc, argv, str)
int argc;
VALUE *argv;
VALUE str;
{
VALUE rs;
int newline;
char *p = RSTRING(str)->ptr, *pend = p + RSTRING(str)->len, *s;
char *ptr = p;
long len = RSTRING(str)->len, rslen;
VALUE line;
if (rb_scan_args(argc, argv, "01", &rs) == 0) {
rs = rb_rs;
}
RETURN_ENUMERATOR(str, argc, argv);
if (NIL_P(rs)) {
rb_yield(str);
return str;
}
StringValue(rs);
rslen = RSTRING(rs)->len;
if (rslen == 0) {
newline = '\n';
}
else {
newline = RSTRING(rs)->ptr[rslen-1];
}
for (s = p, p += rslen; p < pend; p++) {
if (rslen == 0 && *p == '\n') {
if (*++p != '\n') continue;
while (*p == '\n') p++;
}
if (RSTRING(str)->ptr < p && p[-1] == newline &&
(rslen <= 1 ||
rb_memcmp(RSTRING(rs)->ptr, p-rslen, rslen) == 0)) {
line = rb_str_new5(str, s, p - s);
OBJ_INFECT(line, str);
rb_yield(line);
str_mod_check(str, ptr, len);
s = p;
}
}
if (s != pend) {
if (p > pend) p = pend;
line = rb_str_new5(str, s, p - s);
OBJ_INFECT(line, str);
rb_yield(line);
}
return str;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment