⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 journal.c

📁 aee是一种易使用的文本编辑器。你可以不用说明书来使用它。它提供终端接口和本地的X-windows接口。它的特性包括即弹的菜单
💻 C
📖 第 1 页 / 共 2 页
字号:
/* |	journal.c | |		This file contains the routines for handling the journal file |		for ae. | |	$Header: /home/hugh/sources/aee/RCS/journal.c,v 1.34 1998/11/08 23:30:37 hugh Exp $ *//* |	This file contains routines for performing journalling for aee and  |	xae.  Journalling is writing lines and information about them to a  |	file when the cursor moves away from them (if they have been changed  |	during the time the cursor was on the line). | |	The data structure ae_file_info contains the information about  |	locations in the file for where to find the information about the  |	current line, the information about the previous line, the info  |	about the next line, and the location of the actual text.  The  |	length of the line (which is important!) is contained in the 'text'  |	structure for the line.   | |	The format that the information is written into the file is as  |	follows: | |	+--+--+--+--+ |	|  |  |  |  |	previous line info location |	+--+--+--+--+ | |	+--+--+--+--+ |	|  |  |  |  |   next line info location |	+--+--+--+--+ | |	+--+--+--+--+ |	|  |  |  |  |	text location |	+--+--+--+--+ | |	+--+--+--+--+ |	|  |  |  |  |	text length (in bytes, including terminating NULL) |	+--+--+--+--+ | *//* |	Also in this file are routines for managing information about what  |	journal files have been written, and the relationship between the  |	journal file and the file being journalled.  This helps when  |	recovering from a disaster, and could be used to determine duplicate  |	edit sessions, or a failed previous session. | |	The name of the file is ~/.aeeinfo, and there is a lock file named  |	~/.aeeinfo.L.  The format of ~/.aeeinfo is as follows: | |	32 30 /home/hugh/sources/aee/journal.c /tmp/hugh/journal/journal.c.rv | |	where the first number is the length (decimal) if the full file name,  |	the second number is the length of the journal file name, followed by  |	the file name, and the name of the journal file.  The fields are  |	separated by a single space (ASCII 32). | | *//* | |	Copyright (c) 1994, 1995, 1996, 1998 Hugh Mahon. | */char *jrn_vers_str = "@(#)                           journal.c $Revision: 1.34 $";#include "aee.h"#include <time.h>/* |	writes the contents of the line, updates the value stored in  |	memory of where the start of the line is stored in the file */void write_journal(buffer, line)struct bufr *buffer;struct text *line;{	int counter;	int ret_val = 0;	ret_val = line->file_info.line_location = 				lseek(buffer->journ_fd, 0, SEEK_END);	for (counter = 0; (counter < line->line_length) && (ret_val != -1); 			counter += min(1024, (line->line_length - counter)))	{		ret_val = write(buffer->journ_fd, &(line->line[counter]), 			min(1024, (line->line_length - counter)));	}	update_journal_entry(buffer, line);	line->changed = FALSE;}/* |	update the information for a line that has already been written, or |	write a line for the first after its values have been initialised |	by journ_info_init */void update_journal_entry(buffer, line)struct bufr *buffer;struct text *line;{	int ret_val;	if (line->file_info.info_location == NO_FURTHER_LINES)	{		journ_info_init(buffer, line);		return ;	}	ret_val = lseek(buffer->journ_fd, line->file_info.info_location, 								SEEK_SET);	ret_val |= write(buffer->journ_fd, 		  (char *)&(line->file_info.prev_info), sizeof(unsigned long));	ret_val |= write(buffer->journ_fd, 		  (char *)&(line->file_info.next_info), sizeof(unsigned long));	ret_val |= write(buffer->journ_fd, 		  (char *)&(line->file_info.line_location), 		  	sizeof(unsigned long));	ret_val |= write(buffer->journ_fd, (char *)&(line->line_length), 						sizeof(int));}/* |	change journal info at first line if the first line is deleted  |	while editing */void remove_journ_line(buffer, line)struct bufr *buffer;struct text *line;{	if (line->prev_line == NULL)	{		/*		 |	This was the first line, now the next line is.		 */		line->next_line->file_info.info_location = 					line->file_info.info_location;		update_journal_entry(buffer, line->next_line);		if (line->next_line->next_line != NULL)		{			line->next_line->next_line->file_info.prev_info = 						line->file_info.info_location;			update_journal_entry(buffer, line->next_line->next_line);		}	}	else if (line->next_line == NULL)	{		/*		 |	This was the last line, now the prev line is.		 */		line->prev_line->file_info.next_info = NO_FURTHER_LINES;		update_journal_entry(buffer, line->prev_line);		/*		 |	no point in writing to file since no way to 		 |	access current line now		 */	}	else	{		/*		 |	Need to allow previous line to see next line, 		 |	vice-versa.		 */				line->prev_line->file_info.next_info = 				line->next_line->file_info.info_location;		line->next_line->file_info.prev_info = 				line->prev_line->file_info.info_location;		update_journal_entry(buffer, line->next_line);		update_journal_entry(buffer, line->prev_line);	}}/* |	initialize the location of where the information is to reside  |	(using lseek), initialize information for this line of where the  |	previous line is, set the information where to find this line for  |	the previous line, next line then | |	update current line (write for the first time) |	update the previous line (if prev_line != NULL) |	update the next line (if next_line != NULL) | */void journ_info_init(buffer, line)struct bufr *buffer;struct text *line;{	int ret_val;	ret_val = line->file_info.info_location = 					lseek(buffer->journ_fd, 0, SEEK_END);	if (line->prev_line != NULL)	{		line->file_info.prev_info = 				line->prev_line->file_info.info_location;		line->prev_line->file_info.next_info = 				line->file_info.info_location;	}	if (line->next_line != NULL)	{		line->file_info.next_info = 				line->next_line->file_info.info_location;		line->next_line->file_info.prev_info = 				line->file_info.info_location;	}	else		line->file_info.next_info = NO_FURTHER_LINES;	update_journal_entry(buffer, line);	if (line->prev_line != NULL)		update_journal_entry(buffer, line->prev_line);	if ((line->next_line != NULL) && 	    (line->file_info.next_info != NO_FURTHER_LINES))		update_journal_entry(buffer, line->next_line);}/* |	read the journal entry from the file */void read_journal_entry(buffer, line)struct bufr *buffer;struct text *line;{	int counter;	lseek(buffer->journ_fd, line->file_info.info_location, SEEK_SET);	read(buffer->journ_fd, (char *)&(line->file_info.prev_info), 						sizeof(unsigned long));	read(buffer->journ_fd, (char *)&(line->file_info.next_info), 						sizeof(unsigned long));	read(buffer->journ_fd, (char *)&(line->file_info.line_location), 						sizeof(unsigned long));	read(buffer->journ_fd, (char *)&(line->line_length), 						sizeof(unsigned int));	lseek(buffer->journ_fd, line->file_info.line_location, SEEK_SET);	line->line = malloc(line->line_length);	for (counter = 0; counter < line->line_length; 			counter += min(1024, (line->line_length - counter)))	{		read(buffer->journ_fd, &(line->line[counter]), 			min(1024, (line->line_length - counter)));	}}/* |	read the contents of the edited file from the journal file |	read the file up to the first '\n' (line feed), which is where  |	the journal information begins |	 |	This reads the contents of the edited file, plus sets the values  |	in the data structures to allow continued editing (it is recreated  |	within the editor, so why not?). */int recover_from_journal(buffer, file_name)struct bufr *buffer;char *file_name;{	int counter = 0;	struct text *line;	char temp;	char done = FALSE;	char name[1024];	if ((buffer->journ_fd = open(file_name, O_RDONLY)) == -1)	{		/*		 |	Unable to open journal file.		 */		return(1);	}	memset(name, 0, 1024);	/*	 |	get to first record in file (skip the file name)	 */	do	{		read(buffer->journ_fd, &temp, 1);		if ((counter < 1024) && (temp != '\n'))			name[counter] = temp;		counter++;	}	while (temp != '\n');	line = buffer->first_line;	/*	 |	set up first entry	 */	line->file_info.info_location = counter;	do	{		read_journal_entry(buffer, line);		line->vert_len = (scanline(line, line->line_length) / COLS) + 1;		line->max_length = line->line_length;		if (line->file_info.next_info != NO_FURTHER_LINES)		{			line->next_line = txtalloc();			buffer->num_of_lines++;			line->next_line->prev_line = line;			line->next_line->next_line = NULL;			line->next_line->line_number = line->line_number + 1;			line = line->next_line;			line->file_info.next_info = 0;			line->file_info.info_location = 				line->prev_line->file_info.next_info;		}		else			done = TRUE;	} 	while (!done);	curr_buff->pointer = buffer->first_line->line;	close(buffer->journ_fd);	change = TRUE;	buffer->changed = TRUE;	/*	 |	open journal for further changes	 */	if (buffer->journalling)	{		if ((buffer->journ_fd = 			open(buffer->journal_file, O_WRONLY)) == -1)		{			wprintw(com_win, cant_opn_rcvr_fil_msg);			buffer->journalling = FALSE;		}	}	/*	 |	Since the user can specify a journal name without specifying 	 |	the name of the file it journalled, use the name stored in 	 |	the journal file.	 */	if ((buffer->full_name == NULL) || (*buffer->full_name == (char) NULL))	{		buffer->full_name = (name[0] == (char) NULL) ? NULL : strdup(name);		if (buffer->full_name != NULL)		{			buffer->file_name = ae_basename(buffer->full_name);			if (strcmp(main_buffer_name, buffer->name))				buffer->name = strdup(buffer->file_name);		}		else			buffer->file_name = NULL;	}	/*	 |	Success!	 */	return(0);}/* |	journal database file routines */static char *lock_file_name = NULL;static char *db_file_name = NULL;/* |	write a lock file so that another process doesn't try to open  |	the file | |	This is an atomic action since the open should fail if the file  |	already exists, thus it can't be opened if someone else has a  |	lock in place. */int lock_journal_fd(){	int counter = 0;	int ret_val;	if (lock_file_name == NULL)		lock_file_name = resolve_name("~/.aeeinfo.L");	/*	 |	At some point may want to put in a check for an old lock file.	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -