gem.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #include "lua.h"
  2. #include "lauxlib.h"
  3. #define CR '\xD'
  4. #define LF '\xA'
  5. #define CRLF "\xD\xA"
  6. #define candidate(c) (c == CR || c == LF)
  7. static int pushchar(int c, int last, const char *marker,
  8. luaL_Buffer *buffer) {
  9. if (candidate(c)) {
  10. if (candidate(last)) {
  11. if (c == last)
  12. luaL_addstring(buffer, marker);
  13. return 0;
  14. } else {
  15. luaL_addstring(buffer, marker);
  16. return c;
  17. }
  18. } else {
  19. luaL_putchar(buffer, c);
  20. return 0;
  21. }
  22. }
  23. static int eol(lua_State *L) {
  24. int context = luaL_checkint(L, 1);
  25. size_t isize = 0;
  26. const char *input = luaL_optlstring(L, 2, NULL, &isize);
  27. const char *last = input + isize;
  28. const char *marker = luaL_optstring(L, 3, CRLF);
  29. luaL_Buffer buffer;
  30. luaL_buffinit(L, &buffer);
  31. if (!input) {
  32. lua_pushnil(L);
  33. lua_pushnumber(L, 0);
  34. return 2;
  35. }
  36. while (input < last)
  37. context = pushchar(*input++, context, marker, &buffer);
  38. luaL_pushresult(&buffer);
  39. lua_pushnumber(L, context);
  40. return 2;
  41. }
  42. static luaL_reg func[] = {
  43. { "eol", eol },
  44. { NULL, NULL }
  45. };
  46. int luaopen_gem(lua_State *L) {
  47. luaL_openlib(L, "gem", func, 0);
  48. return 0;
  49. }