/* file.c - functions for file operations and memory management
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mstring.h"
#include "terminal.h"
#include "editor.h"


long ed__lines;				 /* number of lines in array */
char **ed__array;			 /* array of lines */


/* Load "file" into memory, returning nonzero on error.
 */
int ed_load(char *file)
{
	char buf[8192];
	FILE *fptr;
	char *a;
	char *s;
	char **b;
	int ol, i, c;

	ed__lines = 1;
	ed__array = malloc(sizeof(char *));
	if (!ed__array)
		return (1);
	ed__array[0] = 0;

	fptr = fopen(file, "r");
	if (!fptr) {
		ed_exit();
		return (1);
	}

	while (!feof(fptr)) {
		t_bored(1);
		buf[0] = 0;
		fgets(buf, sizeof(buf) / 8, fptr);	/* read line */

		a = strchr(buf, '\n');
		if (a)
			*a = 0;		    /* strip newline */

		for (i = 0; buf[i] != 0; i++) {	/* expand tabs & censor ctrl chars */
			if (buf[i] == 9) {
				buf[i] = ' ';
				c = buf[i + 1];
				buf[i + 1] = 0;
				switch ((mstrlen(buf)) % 8) {
				case 0:
					s = 0;
					break;
				case 1:
					s = "       ";
					break;
				case 2:
					s = "      ";
					break;
				case 3:
					s = "     ";
					break;
				case 4:
					s = "    ";
					break;
				case 5:
					s = "   ";
					break;
				case 6:
					s = "  ";
					break;
				case 7:
					s = " ";
					break;
				default:
					s = 0;
					break;
				}
				buf[i + 1] = c;
				c = i;
				if (s)
					mstrinsert(buf, s, &c,
						   sizeof(buf));
			} else if (((buf[i] < 32) && (buf[i] >= 0))
				   || (buf[i] == 127)) {
				if (!miscntl(buf[i]) && (buf[i] != 8))
					buf[i] = ' ';
			}
		}

		ol = (ed__array[ed__lines - 1]) ?
		    strlen(ed__array[ed__lines - 1]) : 0;
		ed__array[ed__lines - 1] =
		    realloc(ed__array[ed__lines - 1],
			    ol + strlen(buf) + 2);
		if (!ed__array[ed__lines - 1]) {	/* extend current line */
			fclose(fptr);
			ed_exit();
			return (1);
		}
		ed__array[ed__lines - 1][ol] = 0;
		strcat(ed__array[ed__lines - 1], buf);	/* add buffer to line */

		if (a) {		    /* new line - extend array */
			b = realloc(ed__array,
				    sizeof(char *) * (ed__lines + 1));
			if (!b) {
				fclose(fptr);
				ed_exit();
				return (1);
			}
			ed__array = b;
			ed__array[ed__lines] = 0;
			ed__lines++;
		}
	}

	fclose(fptr);

	return (0);
}


/* Save from memory to "file".
 */
void ed_save(char *file)
{
	FILE *fptr;
	long l;

	if (!ed__array)
		return;

	fptr = fopen(file, "w");
	if (!fptr)
		return;

	for (l = 0; l < ed__lines; l++) {
		t_bored(1);
		if (ed__array[l]) {
			if (l == 0)
				fprintf(fptr, "%s", ed__array[l]);
			else
				fprintf(fptr, "\n%s", ed__array[l]);
		}
	}

	fclose(fptr);
}


/* Free all memory being used.
 */
void ed_exit(void)
{
	long l;

	t_bored(0);

	if (!ed__array)
		return;

	for (l = 0; l < ed__lines; l++)
		free(ed__array[l]);

	free(ed__array);
	free(ed__killbuf);

	ed__array = 0;
	ed__lines = 0;
	ed__killbuf = 0;
}

/* EOF */
