/* readline.c - read line from file
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mstring.h"
#include "viewfile.h"


/* Read line "line" from the currently open file into the line buffer. Trailing
 * newlines and carriage returns are removed, and the string is
 * null-terminated.
 *
 * No more than sizeof (data->linebuf) bytes will be read.
 */
void rf_read_line(rf_data_t data, long line)
{
	long start_pos;
	long num_bytes;
	int spaces, i, j;
	char foo[9];			 /* it's a dirty kludge, sir! */

	data->linebuf[0] = 0;		    /* start with an empty buffer */
	if (line < 0)
		return;
	if (line >= data->num_lines)
		return;			    /* just return if line out of range */

	start_pos = data->line_pos[line].offset;
	num_bytes = data->line_pos[line].len;

	if (num_bytes >= sizeof(data->linebuf))
		num_bytes = sizeof(data->linebuf) - 1;

	lseek(data->fd, start_pos, SEEK_SET);	/* go to start of line */
	read(data->fd, data->linebuf, num_bytes);	/* read into buffer */

	data->linebuf[num_bytes] = 0;	    /* terminate the string */

	num_bytes--;
	while ((num_bytes >= 0) && ((data->linebuf[num_bytes] == 13) ||
				    (data->linebuf[num_bytes] == 10))) {
		data->linebuf[num_bytes] = 0;
		num_bytes--;
	}

	for (i = 0; data->linebuf[i] != 0; i++) {
		if (data->linebuf[i] == 9) {	/* expand tabs to spaces */
			spaces = 8 - (i % 8);
			for (j = 0; j < spaces; j++)
				foo[j] = 32;
			foo[spaces - 1] = 0;
			data->linebuf[i] = 32;
			mstrinsert(data->linebuf, foo, &i,
				   sizeof(data->linebuf));
			i--;
		}
	}
}

/* EOF */
