/**
* This is a solution to the numcat problem.
* It does not:
* - indent the numbers the right way;
* - report all the errors the right way.
*/
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#define BUFFSIZE 4096
char buff[BUFFSIZE];
int number = 2;
/**
* A simple function to reverse some part of a string
*/
void reverse(char *start, char *end)
{ char x;
while (start < end)
{
x = *start;
*start = *end;
*end = x;
start++;
end--;
}
}
/**
* A simple function to print a number in a string.
* It also adds a tab before the string and a space after it.
*/
char *itostr(int n, char *result)
{
int i = 1;
result[0] = '\t';
while (n)
{
result[i++] = n%10 + '0';
n/=10;
}
reverse(&result[1], &result[i-1]);
result[i] = ' ';
result[i+1] = 0;
return result;
}
/**
* A function to process the buffer after each read.
* It splits it in new lines and writes the number and
* the line.
*/
void output(char *buf, int start, int end)
{
int i;
char x[10];
for (i=start;i<end;i++)
{
if (buf[i]=='\n')
{
write(1, &buf[start], i+1-start);
itostr(number++, x);
write(1, x, strlen(x));
start = i + 1;
}
}
write(1, buf + start, end - start);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
write(2, "Usage: numcat filename\n", 11);
exit(EXIT_FAILURE);
}
int fd = open(argv[1], O_RDONLY);
if (fd == -1)
{
write(2,"hmm..\n",6);
exit(EXIT_FAILURE);
}
ssize_t read_bytes;
write(1, "\t1 ",3);
while (1)
{
read_bytes = read(fd, buff, BUFFSIZE);
if (read_bytes == -1)
{
write(2, "Error!\n", 7);
exit(EXIT_FAILURE);
}
if (read_bytes == 0)
{
write(1, "\n", 1);
exit(EXIT_SUCCESS);
}
output(buff, 0, read_bytes);
}
return 0;
}