чување e92bad6391aa2ca8648976a8307ae7b6cc4a2601
родитељ 3a7da39339cdc139b724e6eba90001a623dc76e4
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Mon, 19 Jul 2021 20:12:09 +0200
Added logic for -s (spaces option)
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | do-test | | | 16 | ++++++++-------- |
| M | ufold.c | | | 227 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
измењених датотека: 2, додавања: 189(+), брисања: 54(-)
diff --git a/do-test b/do-test
@@ -1,26 +1,26 @@
#!/bin/sh
echo -ne "Test 1 - normal:\t"
-fold test1.txt > f.out
-ufold test1.txt > uf.out
+fold -w 20 test1.txt > f.out
+ufold -w 20 test1.txt > uf.out
diff f.out uf.out 2>/dev/null >/dev/null && echo "PASS" || echo "FAIL"
rm -f f.out uf.out
echo -ne "Test 1 - spaces:\t"
-fold -s test1.txt > f.out
-ufold -s test1.txt > uf.out
+fold -w 20 -s test1.txt > f.out
+ufold -w 20 -s test1.txt > uf.out
diff f.out uf.out 2>/dev/null >/dev/null && echo "PASS" || echo "FAIL"
rm -f f.out uf.out
echo -ne "Test 2 - normal:\t"
-fold test2.txt > f.out
-ufold test2.txt > uf.out
+fold -w 20 test2.txt > f.out
+ufold -w 20 test2.txt > uf.out
diff f.out uf.out 2>/dev/null >/dev/null && echo "PASS" || echo "FAIL"
rm -f f.out uf.out
echo -ne "Test 2 - spaces:\t"
-fold -s test2.txt > f.out
-ufold -s test2.txt > uf.out
+fold -w 20 -s test2.txt > f.out
+ufold -w 20 -s test2.txt > uf.out
diff f.out uf.out 2>/dev/null >/dev/null && echo "PASS" || echo "FAIL"
rm -f f.out uf.out
diff --git a/ufold.c b/ufold.c
@@ -55,6 +55,183 @@ starts_with(const char* s, const char* with)
return *with == 0;
}
+void
+fold_line_spaces(const u8* line, const int width)
+{
+ if (!line)
+ return;
+
+ /*
+ * Idea:
+ * 1. store characters in token until line is exhausted
+ * 2. when ' ' or end of line is encountered:
+ * 2,1, if token length > width, see if current column is 0:
+ * 2.1.1. if it isn't, output newline and go to 2.1.2.
+ * 2.1.2. (if it is) output chunks of length "width" until the
+ * end of token, then reset token
+ * 2.2. if token length <= width, see if token length + current
+ * column exceed width
+ * 2.2.1. if they do, output newline and go to 2.2.2.
+ * 2.2.2. (if they don't) output token
+ * 3. go to 1. unless line is exhausted
+ */
+ const u8* pline = line;
+ u32 uch = 0;
+ u32 token[MAXINPUTBUF];
+ u32* ptoken = NULL;
+ u8 u8ch[7];
+ size_t u8ch_len = 0;
+ size_t delta = 0;
+ size_t len = 0;
+ size_t col = 0;
+
+ *token = 0;
+ ptoken = token;
+ /* 1. */
+ while (1)
+ {
+ u8_char_to_u32(&uch, pline, &len);
+ if (!len)
+ return;
+ *ptoken++ = uch;
+ pline += len;
+
+ /* 2. */
+ if (uch == (u32)L' ' || !uch)
+ {
+
+ if (ptoken - token > width)
+ {
+ /* 2.1. */
+ if (col > 0)
+ {
+ /* 2.1.1. */
+ printf("\n");
+ col = 0;
+ }
+
+ /* 2.1.2. */
+ *ptoken = 0;
+ ptoken = token;
+ while (*ptoken)
+ {
+ u8ch_len = u32_char_to_u8(u8ch,
+ *ptoken);
+ if (!u8ch_len)
+ return;
+ u8ch[u8ch_len] = 0;
+
+ if (*ptoken == (u32)L'\t')
+ delta = 8 - (col % 8);
+ else
+ delta = 1;
+
+ if (col + delta > width)
+ {
+ printf("\n");
+ col = 0;
+ if (*ptoken == (u32)'\t')
+ delta = 8;
+ else
+ delta = 1;
+ }
+ printf("%s", u8ch);
+ col += delta;
+ ptoken += u8ch_len;
+ }
+ *token = 0;
+ ptoken = token;
+ }
+ else
+ {
+ /* 2.2. */
+ if (ptoken - token + col > width)
+ {
+ /* 2.2.1. */
+ printf("\n");
+ col = 0;
+ }
+
+ /* 2.2.2. */
+ *ptoken = 0;
+ ptoken = token;
+ while (*ptoken)
+ {
+ u8ch_len = u32_char_to_u8(u8ch,
+ *ptoken);
+ if (!u8ch_len)
+ return;
+ u8ch[u8ch_len] = 0;
+
+ if (*ptoken == (u32)L'\t')
+ delta = 8 - (col % 8);
+ else
+ delta = 1;
+
+ printf("%s", u8ch);
+ col += delta;
+ ptoken++;
+ }
+ *token = 0;
+ ptoken = token;
+ }
+ }
+
+ /* 3. */
+ if (!uch)
+ break;
+ }
+}
+
+void
+fold_line_normal(const u8* line, const int width)
+{
+ if (!line)
+ return;
+
+ const u8* pline = line;
+ const u8* pline_inner = NULL;
+ u32 uch;
+ u8 u8_char[7];
+ u8* pu8_char = NULL;
+ size_t uch_len;
+ size_t delta = 0;
+ size_t col = 0;
+
+ while (*pline)
+ {
+ /* convert only to get byte length */
+ u8_char_to_u32(&uch, pline, &uch_len);
+ if (!uch_len)
+ return;
+
+ pline_inner = pline;
+ pu8_char = u8_char;
+ while (*pline_inner && pline_inner < pline + uch_len)
+ *pu8_char++ = *pline_inner++;
+ *pu8_char = 0;
+
+ if (uch == (u32)L'\t')
+ delta = 8 - (col % 8);
+ else
+ delta = 1;
+
+ if (col + delta > width)
+ {
+ printf("\n");
+ col = 0;
+ if (uch == (u32)L'\t')
+ delta = 8;
+ else
+ delta = 1;
+ }
+
+ printf("%s", u8_char);
+ col += delta;
+ pline += uch_len;
+ }
+}
+
int
main(int argc, char** argv)
{
@@ -130,16 +307,6 @@ main(int argc, char** argv)
return error(errno, "Cannot open file");
char line[MAXINPUTBUF];
- u32 token[MAXBUF];
- u32 uch;
- u8 u8_char[8];
- u8* pu8_char = NULL;
- u8* pline = NULL;
- u8* pline_inner = NULL;
- u32* ptoken = NULL;
- long col = 0;
- long delta = 0;
- size_t len = 0;
while (!feof(input))
{
if (!fgets(line, MAXINPUTBUF, input))
@@ -152,44 +319,12 @@ main(int argc, char** argv)
char* eol = strchr(line, '\n');
if (eol)
*eol = 0;
- pline = (u8*)line;
- while (*pline)
- {
- if (spaces)
- {
- /* TODO: -s logic */
- }
- else
- {
- u8_char_to_u32(&uch, pline, &len);
- pline_inner = pline;
- pu8_char = u8_char;
- while (*pline_inner && pline_inner <
- pline + len)
- *pu8_char++ = *pline_inner++;
- *pu8_char = 0;
- if (uch == (u32)L'\t')
- delta = 8 - (col % 8);
- else
- delta = 1;
- if (col + delta > width)
- {
- printf("\n");
- col = 0;
- if (uch == (u32)L'\t')
- delta = 8;
- else
- delta = 1;
- }
- printf("%s", u8_char);
- col += delta;
- pline += len;
- }
- }
+ if (spaces)
+ fold_line_spaces((const u8*)line, width);
+ else
+ fold_line_normal((const u8*)line, width);
printf("\n");
- col = 0;
}
- //printf("\n");
fclose(input);
return 0;