/* format a string into an ei_x_buff, except the version token */ static int eiformat(const char** fmt, union arg** args, ei_x_buff* x) { const char* p = *fmt; int res; ei_x_buff x2; while (isspace((int)*p)) ++p; switch (*p) { case '~': res = pformat(&p, args, x); break; case '[': res = ei_x_new(&x2); if (res >= 0) res = plist(&p, args, &x2, 0); if (res > 0) res = ei_x_encode_list_header(x, res); if (res >= 0) res = ei_x_append(x, &x2); ei_x_free(&x2); break; case '{': res = ei_x_new(&x2); if (res >= 0) res = ptuple(&p, args, &x2, 0); if (res >= 0) res = ei_x_encode_tuple_header(x, res); if (res >= 0) res = ei_x_append(x, &x2); ei_x_free(&x2); break; case '"': res = pstring(&p, x); break; case '\'': res = pquotedatom(&p, x); break; default: if (isdigit((int)*p)) res = pdigit(&p, x); else if ((*p == '-' || *p == '+') && isdigit((int)*(p+1))) res = pdigit(&p, x); else if (islower((int)*p)) res = patom(&p, x); else res = -1; break; /* Variables */ } *fmt = p; return res; }
/* encode a tuple */ static int ptuple(const char** fmt, union arg** args, ei_x_buff* x, int size) { int res = 0; const char* p = *fmt; char after = *p++; if (after == '}') { *fmt = p; return size; } while (isspace((int)*p)) ++p; switch (*p++) { case '}': if (after == ',') res = -1; else res = size; break; case ',': if (after == ',' || after == '{') res = -1; else res = ptuple(&p, args, x, size); break; default: --p; res = eiformat(&p, args, x); if (res >= 0) res = ptuple(&p, args, x, size + 1); break; /* Variables */ } *fmt = p; return res; }