coreutils4.5.1 fold.c
今天看了看fold.c,开始有些害怕,硬着头皮,终于看出了点眉目。
先试着用一下。
echo 001{a-z} | fold -w 8
echo 001{a..z} | ./fold -w 8
hello world 1
001a 001
b 001c 0
01d 001e
001f 00
1g 001h
001i 001
j 001k 0
01l 001m
001n 00
1o 001p
001q 001
r 001s 0
01t 001u
001v 00
1w 001x
001y 001
z
echo 001{a-z} | fold -s -w 8
echo 001{a..z} | ./fold -s -w 8
hello world 1
001a
001b
001c
001d
001e
001f
注意,前面的“hello world1"是我加的测试语句,可不管。
在main中有一段程序,用于把
fold -8
换成
fold -w 8
程序如下:
/* Turn any numeric options into -w options. */
for (i = 1; i < argc; i++)
{
char const *a = argv[i];
if (a[0] == '-')
{
if (a[1] == '-' && ! a[2])
break;
if (ISDIGIT (a[1]))
{
char *s = xmalloc (strlen (a) + 2);
s[0] = '-';
s[1] = 'w';
strcpy (s + 2, a + 1);
argv[i] = s;
if (200112 <= posix2_version ())
{
error (0, 0, _("`%s' option is obsolete; use `%s'"), a, s);
usage (EXIT_FAILURE);
}
}
}
}
看上去有些头大,但完成的功能应该是这样。我也懒得验证了。
/* Fold file FILENAME, or standard input if FILENAME is "-",
to stdout, with maximum line length WIDTH.
Return 0 if successful, 1 if an error occurs. */
static int
fold_file (char *filename, int width)
完成折行的操作就在这个子程序中,所以重点分析其流程。先用我的语言说一下。
先打开文件
从中一个字符一个字符的读
如果是\n就写到结果,再输出
如果行长已经越过宽度
进入调整行长的处理
如果有-s选项,进行一段复杂处理。
如果没有-s选项,这个没看懂
把当前的串当成一行,写到结果并输出,重置参数。
如果行长没超过宽度
把当前字符写到结果
/* Assuming the current column is COLUMN, return the column that
printing C will move the cursor to.
The first column is 0. */
static int
adjust_column (int column, char c)
{
if (!count_bytes)
{
if (c == '\b')
{
if (column > 0)
column--;
}
else if (c == '\r')
column = 0;
else if (c == '\t')
column = column + 8 - column % 8;
else /* if (isprint (c)) */
column++;
}
else
column++;
return column;
}
这个子程序的处理,主要用于处理选项-b,我先忽略。
这样,基本把流程走通了。