ib_getlin.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright (c) 2003 Gunnar Ritter
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute
  10. * it freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. *
  17. * 2. Altered source versions must be plainly marked as such, and must not be
  18. * misrepresented as being the original software.
  19. *
  20. * 3. This notice may not be removed or altered from any source distribution.
  21. */
  22. /* Sccsid @(#)ib_getlin.c 1.2 (gritter) 4/17/03 */
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include "iblok.h"
  26. size_t
  27. ib_getlin(struct iblok *ip, char **line, size_t *alcd,
  28. void *(*reallc)(void *, size_t))
  29. {
  30. char *nl;
  31. size_t sz, llen = 0, nllen;
  32. for (;;) {
  33. if (ip->ib_cur >= ip->ib_end) {
  34. if (ip->ib_incompl) {
  35. ip->ib_incompl = 0;
  36. return 0;
  37. }
  38. if (ib_read(ip) == EOF) {
  39. if (llen) {
  40. ip->ib_incompl++;
  41. (*line)[llen] = '\0';
  42. return llen;
  43. } else
  44. return 0;
  45. }
  46. /*
  47. * ib_read() advances ib_cur since *ib_cur++ gives
  48. * better performance than *++ib_cur for ib_get().
  49. * Go back again.
  50. */
  51. ip->ib_cur--;
  52. }
  53. sz = ip->ib_end - ip->ib_cur;
  54. if ((nl = memchr(ip->ib_cur, '\n', sz)) != NULL) {
  55. sz = nl - ip->ib_cur + 1;
  56. if ((nllen = llen + sz + 1) > *alcd) {
  57. *line = reallc(*line, nllen);
  58. *alcd = nllen;
  59. }
  60. memcpy(&(*line)[llen], ip->ib_cur, sz);
  61. (*line)[llen + sz] = '\0';
  62. ip->ib_cur = nl + 1;
  63. return llen + sz;
  64. }
  65. if ((nllen = llen + sz + 1) > *alcd) {
  66. *line = reallc(*line, nllen);
  67. *alcd = nllen;
  68. }
  69. memcpy(&(*line)[llen], ip->ib_cur, sz);
  70. llen += sz;
  71. ip->ib_cur = ip->ib_end;
  72. }
  73. /*NOTREACHED*/
  74. return 0;
  75. }