summaryrefslogtreecommitdiff
path: root/src/gopher.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-03 13:36:46 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-03 13:36:46 +0300
commita940d0e221fe039209aad481035e7e736765f267 (patch)
treef7109a3ed409ab27672ddeeaed91115fe2505f0b /src/gopher.c
parent1cbf6167a870978465eb2fba800049f4c92aaf1d (diff)
Gopher: Be more lenient about line termination
Allow plain `\n` for line termination in addition to `\r\n`.
Diffstat (limited to 'src/gopher.c')
-rw-r--r--src/gopher.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/gopher.c b/src/gopher.c
index 708b2ee8..6203f36d 100644
--- a/src/gopher.c
+++ b/src/gopher.c
@@ -26,10 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 26
27iDefineTypeConstruction(Gopher) 27iDefineTypeConstruction(Gopher)
28 28
29iLocalDef iBool isLineTerminator_(const char *str) { 29iLocalDef iBool isCRLFLineTerminator_(const char *str) {
30 return str[0] == '\r' && str[1] == '\n'; 30 return str[0] == '\r' && str[1] == '\n';
31} 31}
32 32
33iLocalDef iBool isLineTerminator_(const char *str) {
34 return isCRLFLineTerminator_(str) || str[0] == '\n';
35}
36
33iLocalDef iBool isDiagram_(char ch) { 37iLocalDef iBool isDiagram_(char ch) {
34 return strchr("^*_-=~/|\\<>()[]{}", ch) != NULL; 38 return strchr("^*_-=~/|\\<>()[]{}", ch) != NULL;
35} 39}
@@ -68,20 +72,19 @@ static void setPre_Gopher_(iGopher *d, iBool pre) {
68static iBool convertSource_Gopher_(iGopher *d) { 72static iBool convertSource_Gopher_(iGopher *d) {
69 iBool converted = iFalse; 73 iBool converted = iFalse;
70 iRangecc body = range_Block(&d->source); 74 iRangecc body = range_Block(&d->source);
71 iRegExp *pattern = new_RegExp("(.)([^\t]*)\t([^\t]*)\t([^\t]*)\t([0-9]+)", 75 iRegExp *pattern = new_RegExp("(.)([^\t]*)\t([^\t]*)\t([^\t]*)\t([0-9]+)", 0);
72 caseInsensitive_RegExpOption);
73 for (;;) { 76 for (;;) {
74 /* Find the end of the line. */ 77 /* Find the end of the line. */
75 iRangecc line = { body.start, body.start }; 78 iRangecc line = { body.start, body.start };
76 while (line.end < body.end - 1 && !isLineTerminator_(line.end)) { 79 while (line.end < body.end && !isLineTerminator_(line.end)) {
77 line.end++; 80 line.end++;
78 } 81 }
79 if (line.end >= body.end - 1 || !isLineTerminator_(line.end)) { 82 if (line.end >= body.end || !isLineTerminator_(line.end)) {
80 /* Not a complete line. */ 83 /* Not a complete line. More may be coming later. */
81 printf("[Gopher] unterminated: {%s}\n", cstr_Rangecc(line));
82 break; 84 break;
83 } 85 }
84 body.start = line.end + 2; 86 body.start = line.end + (isCRLFLineTerminator_(line.end) ? 2 : 1);
87 trimEnd_Rangecc(&line);
85 iRegExpMatch m; 88 iRegExpMatch m;
86 init_RegExpMatch(&m); 89 init_RegExpMatch(&m);
87 if (matchRange_RegExp(pattern, line, &m)) { 90 if (matchRange_RegExp(pattern, line, &m)) {
@@ -141,10 +144,13 @@ static iBool convertSource_Gopher_(iGopher *d) {
141 delete_String(buf); 144 delete_String(buf);
142 } 145 }
143 else { 146 else {
147#if !defined (NDEBUG)
144 printf("[Gopher] unrecognized: {%s}\n", cstr_Rangecc(line)); 148 printf("[Gopher] unrecognized: {%s}\n", cstr_Rangecc(line));
149#endif
145 } 150 }
146 } 151 }
147 iRelease(pattern); 152 iRelease(pattern);
153 /* Remove the part of the source that was successfully converted. */
148 remove_Block(&d->source, 0, body.start - constBegin_Block(&d->source)); 154 remove_Block(&d->source, 0, body.start - constBegin_Block(&d->source));
149 return converted; 155 return converted;
150} 156}