1
0
mirror of https://github.com/rfivet/uemacs.git synced 2025-11-23 11:41:15 -05:00

Rework file primitives.

This commit is contained in:
2021-08-14 11:45:41 +08:00
parent b4d69118f5
commit 3bce7a4751
4 changed files with 610 additions and 654 deletions

214
fileio.c
View File

@@ -1,13 +1,10 @@
/* fileio.c -- implements fileio.h */
#include "fileio.h"
/* FILEIO.C
*
* The routines in this file read and write ASCII files from the disk. All of
* the knowledge about files are here.
*
* modified by Petri Kutvonen
/* The routines in this file read and write ASCII files from the disk. All
of the knowledge about files are here.
modified by Petri Kutvonen
*/
#include <stdio.h>
@@ -18,66 +15,62 @@
#include "retcode.h"
#include "utf8.h"
char *fline = NULL ; /* dynamic return line */
static int flen = 0 ; /* current allocated length of fline */
int ftype ;
int fcode ; /* encoding type FCODE_xxxxx */
int fpayload ; /* actual length of fline content */
char *fline = NULL ; /* dynamic return line */
static int flen = 0 ; /* current allocated length of fline */
int ftype ;
int fcode ; /* encoding type FCODE_xxxxx */
int fpayload ; /* actual length of fline content */
static FILE *ffp ; /* File pointer, all functions. */
static boolean eofflag ; /* end-of-file flag */
static FILE *ffp ; /* File pointer, all functions. */
static boolean eofflag ; /* end-of-file flag */
/*
* Open a file for reading.
*/
fio_code ffropen( const char *fn)
{
if ((ffp = fopen(fn, "r")) == NULL)
return FIOFNF;
eofflag = FALSE;
/* Open a file for reading. */
fio_code ffropen( const char *fn) {
eofflag = FALSE ;
ftype = FTYPE_NONE ;
fcode = FCODE_ASCII ;
return FIOSUC;
ffp = fopen( fn, "r") ;
return (ffp == NULL) ? FIOFNF : FIOSUC ;
}
/*
* Open a file for writing. Return TRUE if all is well, and FALSE on error
* (cannot create).
/* Open a file for writing. Return TRUE if all is well, and FALSE on error
(cannot create).
*/
fio_code ffwopen( const char *fn) {
ffp = fopen( fn, "w") ;
return (ffp == NULL) ? FIOERR : FIOSUC ;
return (ffp == NULL) ? FIOERR : FIOSUC ;
}
/*
* Close a file. Should look at the status in all systems.
/* Close a file. Should look at the status in all systems.
*/
fio_code ffclose(void)
{
fio_code ffclose( void) {
/* free this since we do not need it anymore */
if (fline) {
free(fline);
fline = NULL;
if( fline) {
free( fline) ;
fline = NULL ;
}
eofflag = FALSE;
eofflag = FALSE ;
ftype = FTYPE_NONE ;
fcode = FCODE_ASCII ;
return (fclose( ffp) != FALSE) ? FIOERR : FIOSUC ;
return (fclose( ffp) != FALSE) ? FIOERR : FIOSUC ;
}
/*
* Write a line to the already opened file. The "buf" points to the buffer,
* and the "nbuf" is its length, less the free newline. Return the status.
* Check only at the newline.
/* Write a line to the already opened file. The "buf" points to the
buffer, and the "nbuf" is its length, less the free newline. Return the
status. Check only at the newline.
*/
fio_code ffputline( char *buf, int nbuf, int dosflag) {
fwrite( buf, 1, nbuf, ffp) ;
if( dosflag)
fputc( '\r', ffp) ;
fwrite( buf, 1, nbuf, ffp) ;
if( dosflag)
fputc( '\r', ffp) ;
fputc( '\n', ffp) ;
@@ -87,92 +80,91 @@ fio_code ffputline( char *buf, int nbuf, int dosflag) {
return FIOSUC ;
}
/*
* Read a line from a file, and store the bytes in the supplied buffer. The
* "nbuf" is the length of the buffer. Complain about long lines and lines
* at the end of the file that don't have a newline present. Check for I/O
* errors too. Return status.
/* Read a line from a file, and store the bytes in the supplied buffer.
The "nbuf" is the length of the buffer. Complain about long lines and
lines at the end of the file that don't have a newline present. Check
for I/O errors too. Return status.
*/
fio_code ffgetline( void) {
int c ; /* current character read */
int i ; /* current index into fline */
int lcode = FCODE_ASCII ; /* line encoding, defaults to ASCII */
int c ; /* current character read */
int lcode = FCODE_ASCII ; /* line encoding, defaults to ASCII */
/* if we are at the end...return it */
if( eofflag)
return FIOEOF ;
if( eofflag)
return FIOEOF ;
/* dump fline if it ended up too big */
if( flen > NSTRING) {
free( fline) ;
fline = NULL ;
}
if( flen > NSTRING) {
free( fline) ;
fline = NULL ;
}
/* if we don't have an fline, allocate one */
if( fline == NULL)
if( (fline = malloc( flen = NSTRING)) == NULL)
return FIOMEM ;
if( fline == NULL)
if( (fline = malloc( flen = NSTRING)) == NULL)
return FIOMEM ;
/* read the line in */
i = 0 ;
while( (c = fgetc( ffp)) != EOF && c != '\r' && c != '\n') {
/* if line is full, get more room */
if( i >= flen) {
char *tmpline ; /* temp storage for expanding line */
int i = 0 ; /* current index into fline */
while( (c = fgetc( ffp)) != EOF && c != '\r' && c != '\n') {
/* if line is full, get more room */
if( i >= flen) {
char *tmpline ; /* temp storage for expanding line */
tmpline = malloc( flen + NSTRING) ;
if( tmpline == NULL)
return FIOMEM ;
tmpline = malloc( flen + NSTRING) ;
if( tmpline == NULL)
return FIOMEM ;
memcpy( tmpline, fline, flen) ;
flen += NSTRING ;
free( fline) ;
fline = tmpline ;
}
memcpy( tmpline, fline, flen) ;
flen += NSTRING ;
free( fline) ;
fline = tmpline ;
}
fline[ i++] = c ;
lcode |= c ;
}
fline[ i++] = c ;
lcode |= c ;
}
fpayload = i ;
lcode &= FCODE_MASK ;
if( lcode && (fcode != FCODE_MIXED)) { /* line contains extended chars */
/* Check if consistent UTF-8 encoding */
int pos = 0 ;
fpayload = i ;
if( lcode & 0x80 /* line contains extended chars */
&& (fcode != FCODE_MIXED)) {
/* Check if consistent UTF-8 encoding */
lcode = FCODE_ASCII ;
int pos = 0 ;
while( (pos < i) && (lcode != FCODE_MIXED)) {
unicode_t uc ;
while( (pos < i) && (lcode != FCODE_MIXED)) {
unicode_t uc ;
int bytes ;
int bytes = utf8_to_unicode( fline, pos, i, &uc) ;
pos += bytes ;
if( bytes > 1) /* Multi byte UTF-8 sequence */
lcode |= FCODE_UTF_8 ;
else if( uc > 127) /* Extended ASCII */
lcode |= FCODE_EXTND ;
}
bytes = utf8_to_unicode( fline, pos, i, &uc) ;
pos += bytes ;
if( bytes > 1) /* Multi byte UTF-8 sequence */
lcode |= FCODE_UTF_8 ;
else if( uc > 127) /* Extended ASCII */
lcode |= FCODE_EXTND ;
}
fcode |= lcode ;
}
fcode |= lcode ;
}
/* test for any errors that may have occured */
if( c == EOF) {
if( ferror( ffp))
return FIOERR ;
if( c == EOF) {
if( ferror( ffp))
return FIOERR ;
if( i != 0)
eofflag = TRUE ;
else
return FIOEOF ;
} else if( c == '\r') {
c = fgetc( ffp) ;
if( c != '\n') {
ftype |= FTYPE_MAC ;
ungetc( c, ffp) ;
} else
ftype |= FTYPE_DOS ;
} else /* c == '\n' */
ftype |= FTYPE_UNIX ;
if( i != 0)
eofflag = TRUE ;
else
return FIOEOF ;
} else if( c == '\r') {
c = fgetc( ffp) ;
if( c != '\n') {
ftype |= FTYPE_MAC ;
ungetc( c, ffp) ;
} else
ftype |= FTYPE_DOS ;
} else /* c == '\n' */
ftype |= FTYPE_UNIX ;
return FIOSUC ;
}
/* end of fileio.c */