fmt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 643 行 · 第 1/2 页
C
643 行
for( tmp += p->len; tmp < p->words + p->size; tmp++ ) {
memset( tmp, 0, sizeof( word ) );
}
return( 0 );
} else {
p->size -= inc;
return( 1 );
}
}
return( 0 );
}
static int getIndentation( FILE *fp, unsigned *os )
{
int ch = 0;
while( 1 ) {
ch = fgetc( fp );
if( ch == ' ' ) {
*os += 1;
} else if( ch == '\t' ) {
*os += 8 - *os % 8;
} else {
break;
}
}
if( ch == '\n' ) {
*os = 0;
return( END_LINE );
} else if( ch == EOF ) {
*os = 0;
return( END_FILE );
} else {
ungetc( ch, fp );
return( 0 );
}
}
static char *insertWord( wordlist **list, char *wtext, unsigned wlen )
{
wordlist *temp;
char *text;
unsigned size;
for( temp = *list; temp != NULL; temp = temp->next ) {
if( wlen < temp->size - temp->len ) {
text = temp->buf + temp->len;
strcpy( text, wtext );
temp->len += wlen + 1;
return( text );
}
}
size = max( wlen + 1, DEF_LIST_LEN );
while( size > wlen ) {
temp = (wordlist *) realloc( temp, sizeof( wordlist ) + size - sizeof( char ) );
if( temp != NULL ) {
break;
} else {
size /= 2;
}
}
if( temp == NULL ) {
return( NULL );
} else {
temp->size = size;
temp->next = *list;
temp->len = wlen + 1;
strcpy( temp->buf, wtext );
*list = temp;
return( temp->buf );
}
}
static int getWord( FILE *fp, wordlist **list, word *w, unsigned *os )
{
static int ret = 0;
char *tmp = NULL;
int ch = 0;
int pv = 0;
int ppv = 0;
ret &= ~OUT_OF_MEM;
if( w->len == 0 || w->len >= w_size ) {
ret = 0;
while( 1 ) {
if( w->len >= w_size ) {
w_size += MIN_WORD_LEN;
tmp = (char *) realloc( w_buff, w_size );
if( tmp == NULL ) {
w_size -= MIN_WORD_LEN;
return( OUT_OF_MEM );
}
w_buff = tmp;
}
ppv = pv;
pv = ch;
ch = fgetc( fp );
if( ch == '\n' || ch == '\t' || ch == ' ' || ch == EOF ) {
break;
} else {
*os += 1;
w_buff[ w->len ] = ch;
w->len++;
}
}
while( 1 ) {
if( ch == ' ' ) {
w->spc++;
*os += 1;
} else if( ch == '\t' ) {
w->spc += 8 - *os % 8;
*os += 8 - *os % 8;
} else {
break;
}
ch = fgetc( fp );
}
if( w->len > 0 ) {
w_buff[ w->len ] = '\0';
}
if( ch == EOF ) {
*os = 0;
w->spc = 1;
ret |= END_FILE;
} else if( ch == '\n' ) {
*os = 0;
w->spc = 1;
ret |= END_LINE;
} else {
ungetc( ch, fp );
}
if( w->spc == 0 ) {
w->spc = 1;
} else if( f_mode & FMT_NOSPACE ) {
if( pv == '.' || pv == '?' || pv == '!' ) {
if( isupper( ppv ) ) {
w->spc = 1;
} else {
w->spc = 2;
}
} else {
w->spc = 1;
}
}
}
w->text = insertWord( list, w_buff, w->len );
if( w->text == NULL ) {
ret |= OUT_OF_MEM;
}
return( ret );
}
static int getParagraph( FILE *fp, para *p, wordlist **list )
{
static unsigned lastos = 0;
static unsigned lineos = 0;
static unsigned curros = 0;
static int start = -1;
int status = 0;
int retval = 0;
while( 1 ) {
if( expandParagraph( p, MIN_PARA_LEN ) ) {
return( OUT_OF_MEM );
}
if( lineos == 0 ) {
lastos = curros;
status = getIndentation( fp, &lineos );
curros = lineos;
start++;
}
if( (status & END_FILE) || (status & END_LINE) ) {
curros = 0;
start = 0;
return( status );
} else if( curros > lastos && start ) {
lastos = curros;
return( status );
}
if( curros > p->indent ) {
p->indent = curros;
p->offset = curros;
}
if( curros < p->offset ) {
p->offset = curros;
}
retval = getWord( fp, list, &p->words[ p->len ], &lineos );
if( retval & OUT_OF_MEM ) {
return( OUT_OF_MEM );
}
p->len++;
if( retval & END_FILE ) {
return( END_FILE );
}
}
}
static void formatFile( FILE *fp, int width, int offset )
{
int ret;
para p = { NULL, 0, 0, 0, 0 };
int oldos = 0;
int erros = -1;
wordlist *list = NULL;
expandParagraph( &p, DEF_PARA_LEN );
for( ; ; ) {
ret = getParagraph( fp, &p, &list );
if( ret & OUT_OF_MEM ) {
if( erros != p.len ) {
trimParagraph( &p );
erros = p.len;
continue;
} else if( p.len == 0 ) {
Die( "fmt: out of memory error\n" );
}
}
if( p.len != 0 ) {
if( p.indent <= oldos ) { // keep track of offsets & indents
p.indent = oldos; // in case of out of mem. errors
p.offset = oldos;
}
oldos = p.offset;
formatParagraph( &p, width, offset, ret & OUT_OF_MEM );
}
if( ret & END_LINE ) { // no need to format blank line
fputchar( '\n' );
oldos = 0;
}
resetParagraph( &p );
resetWordlist( list );
if( ret & END_FILE ) {
break;
}
erros = -1;
}
free( p.words ); // free the paragraph space
freeWordlist( list ); // free the text space
}
void main( int argc, char **argv )
{
FILE *fp;
int ch;
int width = DEF_LINE_LEN;
int offset = 0;
int regexp = 0;
argv = ExpandEnv( &argc, argv );
while( 1 ) {
ch = GetOpt( &argc, argv, "Xcjnl:p:", usageMsg );
if( ch == -1 ) {
break;
}
switch( ch ) {
case 'c':
f_mode |= FMT_CENTRE;
break;
case 'j':
f_mode |= FMT_JUSTIFY;
break;
case 'n':
f_mode |= FMT_NOSPACE;
break;
case 'l':
width = atoi( OptArg );
break;
case 'p':
offset = atoi( OptArg );
break;
case 'X':
regexp = 1;
break;
}
}
if( width <= 0 ) {
Die( "fmt: invalid line length\n" );
}
if( offset < 0 ) {
Die( "fmt: invalid page offset\n" );
}
argv = ExpandArgv( &argc, argv, regexp );
argv++;
if( *argv == NULL ) {
formatFile( stdin, width, offset );
} else {
while( *argv != NULL ) {
fp = fopen( *argv, "r" );
if( fp == NULL ) {
fprintf( stderr, "fmt: cannot open input file \"%s\"\n", *argv );
} else {
if( argc > 2 ) {
fprintf( stdout, "%s:\n", *argv );
}
formatFile( fp, width, offset );
fclose( fp );
}
argv++;
}
}
free( w_buff ); // free the word space
exit( EXIT_SUCCESS );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?