File: unfold.c

package info (click to toggle)
sn 0.3.8-12
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 976 kB
  • sloc: ansic: 9,255; sh: 467; makefile: 210
file content (96 lines) | stat: -rw-r--r-- 1,955 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
 * This file is part of the sn package.
 * Distribution of sn is covered by the GNU GPL. See file COPYING.
 * Copyright � 1998-2000 Harold Tay.
 * Copyright � 2000- Patrik R�dman.
 */

/*
 * Return values:
 * -2 on format error
 * -1 on system error
 * 0 on success
 * 1 if decider short-circuited.
 */

#include <b.h>
#include <readln.h>

static const char ver_ctrl_id[] = "$Id: unfold.c 29 2004-04-24 23:02:38Z patrik $";

static struct b tmp = { 0, };
static char *line;
static int len;
static int bytes_consumed;
static int eof;

/*
 * Not supposed to get EOF here.  I think it is permitted to have an
 * empty body, but without the blank line separator?  I shan't permit
 * it, because there's no way to know if indeed it is a blank
 * article, or an error upstream.
 */

static int getline (struct readln *in)
{
   len = readln(in, &line, '\n');
   if (0 == len)
      return -2;
   if (len < 0)
      return -1;
   bytes_consumed += len;
   if (--len > 0)
      if ('\r' == line[len - 1])
         len--;
   return 0;
}

#define PUTLINE if (putline(tmp.buf, tmp.used)) return -3;

int unfold (struct readln *in, int (*putline) (char *, int))
{
   eof = tmp.used = bytes_consumed = 0;
   switch (getline(in))
   {
      case -2:
         return 0;
      case -1:
         return -1;
   }
   if (-1 == b_appendl(&tmp, line, len))
      return -1;

   for (;;)
   {
      int ret;

      if ((ret = getline(in)))
         return ret;
      if (0 == len)
      {
         if (tmp.used)
            PUTLINE
               break;
      }

      if (' ' == *line || '\t' == *line)
      {
         do
         {
            len--;
            line++;
         }
         while (' ' == *line || '\t' == *line);
         if (-1 == b_appendl(&tmp, " ", 1))
            return -1;
      }
      else
      {
         PUTLINE
            tmp.used = 0;
      }
      if (-1 == b_appendl(&tmp, line, len))
         return -1;
   }
   return bytes_consumed;
}