/**
* Li Feng
* 2011/09/12
* */
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define FLEN 1024 // file name length
#define LINELEN 1024 // line length
#define FLAG_ON 1
#define FLAG_OFF 0
#define DEPTH 128 // stack depth
typedef enum {
_IF,
_WHILE,
_DO,
_FOR,
_ELSE,
_SWITCH, // before switch these keywords can be repalced by '{'
_CASE,
_DEFAULT,
KEYWORDCNT, // stand for the number of keywords
_LS, // stands for '('
_LB, // stands for '{'
_RS, // stands for ')'
_RB, // stands for '}'
_SEMICOLON // stands for ';'
} mykey_t; // these are all domains except KEYWORDCNT
typedef struct
{
mykey_t type; // domain type
int nexttabs; // next line ahead tabs
int currtabs; // current line ahead tabs
int isself; // when isself == FLAG_ON use currtabs otherwise nexttabs
int linenum; // linenum
int issub; // only used in situation of xxx = {..... next line }
} domain_t;
typedef struct
{
mykey_t type; // keyword type
int offset; // keyword's offset in the line
} keyword_t;
char *keywords[KEYWORDCNT] = { "if", "while", "do", "for",
"else", "switch", "case", "default" };
typedef enum{
_CMT, // comment line
_BLK, // blank line
_NOR, // normal line
}linetype_t;
/* read every line in the file and adjust the format*/
void adjfmt( char* line, char* buf, int* sflag, int* cflag,
int* domaintop, domain_t** domainS, int linenum );
/* when domain is '}',')'or';' popout domains*/
void popdomain( mykey_t domainkey, int* domaintopp, domain_t** domainS, int linenum );
void pushdomain( mykey_t domainkey, int* domaintopp, domain_t** domainS, int linenum );
void myinsertSort( keyword_t** tosort, int start, int end );
void myquickSort( keyword_t** tosort, int start, int end );
/* sort keywords by offset*/
void sortorigbyoffset( keyword_t** origkeywordS, int origtop );
/* get keywords in the line*/
void getorigkeywords(char* line, int* origtop, keyword_t** origkeywordS );
/* push keywords into the keywords stack*/
void pushorig(int offset, mykey_t type, int* origtopp, keyword_t** origkeywordS);
/* check is keywords or domains in the string*/
void checkstr( char* line, int index ,int *flag);
/* do prasefile in the file stack*/
void execS( char** fileS, int* filetop );
/* put files into the file stack*/
void Sfile( char* fname, char** fileS, int* filetop );
/* count souce*/
void cntsource( char* line, int* sflag, int* cflag, linetype_t* linetype );
/* do adjust to the file*/
int prasefile(char* _fname);
/* check domains' right*/
int checkright(char r, mykey_t type);
/* check domains' left*/
int checkleft(char l, mykey_t type);
/* prase directory*/
int prasedir(char* _fname, char** fileS, int* filetop);
/* check is keywords in comment*/
int checkcomment( char* line, int index, int* flag);
/* quick sort get mid*/
int getmid( keyword_t** tosort, int start, int end );
/* quicksort partion*/
int mypartion( keyword_t** tosort, int start, int end );
/* rule out keywords*/
mykey_t ruleoutkeywords(int offset, int* origtopp, keyword_t** origkeywordS );
/* not used*/
keyword_t* poporig(int* origtopp, keyword_t** origkeywordS);
static int mlcc1 =0, frc1 = 0; // malloc and free counter for keyword
static int mlcc2 =0, frc2 = 0; // malloc and free counter for domain
static int mlcc3 =0, frc3 = 0; // malloc and free counter for fname
/* flag reverse*/
static const char *shortoptions = "bcfnr";
static int isrecursive = FLAG_OFF;
static int isformat = FLAG_OFF;
static int iscount = FLAG_OFF;
static int isrollback = FLAG_OFF;
static int isbackup = FLAG_ON;
static int cmtline = 0, blkline = 0, norline = 0;
inline static void printusg()
{
printf( "Usage:blktotab < [ [-b] or [ [-f] [-c] ] ] > [-r] [-n] < [directory] [file]... > \n" );
printf( "\t-b: roll back formated source\n");
printf( "\t-c: count how many blank, comment and normal lines in the file\n" );
printf( "\t-f: format the source code\n");
printf( "\t\tyou can only choose one from -b and -f\n");
printf( "\t-n: no back up(have effect only when -f option is specified)\n");
printf( "\t\tWith *.bttbak files you can roll back by use ./blktotab -b -r [dir or file]\n");
printf( "\t-r: recursive\n");
printf( "In command line you can specify up to 128 files or directorys, and at least 1\n");
printf( "Ex:./blktotab -f -c -r dir1 file1\n");
}
inline static void perr(char* errstr)
{
printf("%s err\n", errstr);
}
int main( int argc, char* argv[] )
{
int ret = 0, filetop = 0;
char fnames[DEPTH][FLEN] = { {0} };
char fname[FLEN] = { 0 };
//char fname[FLEN] = "aa.c";
struct stat buf = { 0 };
char* fileS[DEPTH] = { 0 };
int optcnt = 1, filecnt = 0;
int opt = 0;
if( 2 > argc )
{
printusg();
exit( -1 );
}
while ((opt = getopt(argc, argv, shortoptions)) != EOF)
{
switch(opt)
{
case 'b':
isrollback = FLAG_ON;
break;
case 'r':
isrecursive = FLAG_ON;
break;
case 'c':
iscount = FLAG_ON;
break;
case 'f':
isformat = FLAG_ON;
break;
case 'n':
isbackup = FLAG_OFF;
break;
default:
printusg( );
exit( 0 );
break;
}
}
if( FLAG_OFF == iscount && FLAG_OFF == isformat && FLAG_OFF == isrollback )
{
printusg();
exit( 0 );
}
if( ( FLAG_ON == isformat || FLAG_ON == iscount ) && FLAG_ON == isrollback )
{
printusg();
exit( 0 );
}
while( optcnt < argc )
{
if( argv[optcnt][0] != '-' )
{
if( DEPTH > filecnt )
{
strncpy( fnames[filecnt], argv[optcnt], strlen( argv[optcnt] ) );
//printf("%s\n", fnames[filecnt]);
++filecnt;
}else perr("too much file on command line\n");
}
++optcnt;
}
optcnt = 0;
while( optcnt < filecnt )
{
strncpy( fname, fnames[optcnt], strlen( fnames[optcnt] ) );
++optcnt;
ret = access( fname, R_OK );
if( ret < 0 )
{
perr("access");
exit( -1 );
}
ret = lstat( fname, &buf );
if( ret < 0 )
{
perr("lstat");
exit( -1 );
}
if( S_ISREG( buf.st_mode ) )
{
char* temp = NULL;
temp = strrchr( fname, '.' );
if( temp != NULL )
{
int len = strlen( temp );
if( ( 2 == len && ( strncmp( temp, ".c", 2 ) == 0 || strncmp( temp, ".h", 2) == 0 ) ) ||
( 3 == len && strncmp( temp, ".cc", 3 ) == 0 ) ||
( 4 == len && ( strncmp( temp, ".cxx", 4 ) == 0 || strncmp( temp, ".cpp", 4 ) == 0 ) ) ||
( 5 == len && strncmp( temp, ".java", 5 ) == 0 ) )
{
ret = prasefile( fname );
if( 0 != ret )
perr("prasefile");
}else if( FLAG_ON == isrollback && 7 == len && strncmp( temp, ".bttbak", 7 ) == 0 )
{
char rollbackname[FLEN] = { 0 };
strncpy( rollbackname, fname, strlen( fname ) );
temp = strrchr( rollbackname, '.' );
*temp = '\0';
unlink(rollbackname);
ret = rename( fname, rollbackname );
if( 0 != ret )
{
perr( "rename" );
return ret;
}
}
}else{ }
}else if( S_ISDIR( buf.st_mode ) )
{
//printf( "directory\n" );
ret = prasedir( fname, fileS, &filetop );
if( 0 != ret)
perr("prasedir");
execS( fileS, &filetop );
}else{
printf( "other type of file, do nothing\n" );
printusg();
exit(0);
}
memset( fname, 0, FLEN );
}
if( 0 == optcnt )
{
printusg( );
exit( 0 );
}
if( FLAG_ON == iscount ){
printf("In all prased files have %d normal lines, %d comment lines, %d blank lines\n",
norline, cmtline, blkline );
}
if( FLAG_ON == isformat ){
printf( "At end [mlcc1:%d,frc1:%d] [mlcc2:%d,frc2:%d] [mlcc3:%d,frc3:%d]\n",
mlcc1, frc1, mlcc2, frc2, mlcc3, frc3 );
}
return ret;
}
void execS( char** fileS, int* filetopp )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int filetop = *filetopp;
while( filetop > 0 )
{
prasefile( fileS[--filetop] );
free( fileS[filetop] );
frc3++;
}
*filetopp = filetop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void Sfile( char* fname, char** fileS, int* filetopp )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
fileS[(*filetopp)++] = fname;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
int prasedir(char* dirname, char** fileS, int* filetop)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
DIR *dp = NULL;
int ret = 0;
struct dirent *dirp = NULL;
struct stat buf = { 0 };
if( (dp = opendir( dirname )) == NULL )
perr("opendir");
while( (dirp = readdir(dp)) != NULL )
{
char *d_name = dirp->d_name;
if( strcmp( d_name, ".." ) == 0 || strcmp( d_name, "." ) == 0 ||
strcmp( d_name, ".svn" ) == 0 ) continue;
char* fname = ( char * )malloc(FLEN);
mlcc3++;
sprintf( fname, "%s/%s", dirname, d_name );
ret = lstat( fname, &buf );
if( ret < 0 )
{
perr("lstat");
free(fname);
frc3++;
exit( -1 );
}
if( S_ISREG( buf.st_mode ) )
{
char* temp = NULL;
temp = strrchr( d_name, '.' );
if( temp != NULL )
{
int len = strlen( temp );
if( ( 2 == len && ( strncmp( temp, ".c", 2 ) == 0 || strncmp( temp, ".h", 2) == 0 ) ) ||
( 3 == len && strncmp( temp, ".cc", 3 ) == 0 ) ||
( 4 == len && ( strncmp( temp, ".cxx", 4 ) == 0 || strncmp( temp, ".cpp", 4 ) == 0 ) ) ||
( 5 == len && strncmp( temp, ".java", 5 ) == 0 ) )
{
if( DEPTH == *filetop )
execS(fileS, filetop );
Sfile( fname, fileS, filetop );
}else if( FLAG_ON == isrollback && 7 == len && strncmp( temp, ".bttbak", 7 ) == 0 ){
char rollbackname[FLEN] = { 0 };
strncpy( rollbackname, fname, strlen( fname ) );
temp = strrchr( rollbackname, '.' );
*temp = '\0';
unlink(rollbackname);
ret = rename( fname, rollbackname );
if( 0 != ret )
{
perr( "rename" );
return ret;
}
free(fname);
frc3++;
}else{
free(fname);
frc3++;
}
}else{
free(fname);
frc3++;
}
}else if( S_ISDIR( buf.st_mode ) )
{
//printf( "directory\n" );
if( FLAG_ON == isrecursive ){
ret = prasedir( fname, fileS, filetop );
if( 0 != ret)
{
free(fname);
frc3++;
perr("prasedir");
}
}
free(fname);
frc3++;
}else {
free(fname);
frc3++;
}
}
closedir(dp);
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return 0;
}
int prasefile(char* _fname)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
printf( "start prase file:%s\n", _fname );
int ret = 0;
FILE *infd = NULL, *outfd = NULL;
int strflagforfmt = FLAG_OFF, strflagforcnt = FLAG_OFF;
int cmtflagforfmt = FLAG_OFF, cmtflagforcnt = FLAG_OFF;
char bakname[FLEN] = { 0 };
char rdbuf[LINELEN] = { 0 };
char rtnbuf[LINELEN] = { 0 };
int domaintop = 0;
domain_t* domainS[DEPTH] = { 0 };
int lcmtline = 0, lblkline = 0, lnorline = 0;
linetype_t linetype = _BLK;
if( FLAG_ON == isformat )
{
strncpy( bakname, _fname, strlen( _fname ) );
strncat( bakname, ".bttbak", 7 );
ret = rename( _fname, bakname );
if( 0 != ret )
{
perr( "rename" );
return ret;
}
infd = fopen( bakname, "r+" );
if( NULL == infd )
{
perr( "fopen infd");
return -1;
}
outfd = fopen( _fname, "w+" );
if( NULL == outfd )
{
perr( "fopen outfd");
fclose( infd );
return -1;
}
}else{
infd = fopen( _fname, "r+" );
if( NULL == infd )
{
perr( "fopen infd");
return -1;
}
}
int linenum = 0;
while( NULL != fgets( rdbuf, LINELEN, infd ) )
{
if( FLAG_ON == isformat )
{
//printf("in line %d\n", ++linenum);
adjfmt( rdbuf, rtnbuf, &strflagforfmt, &cmtflagforfmt, &domaintop, domainS, ++linenum );
fwrite( rtnbuf, strlen(rtnbuf), 1, outfd );
memset( rtnbuf, 0x00, LINELEN );
}
if( FLAG_ON == iscount )
{
cntsource( rdbuf, &strflagforcnt, &cmtflagforcnt, &linetype );
switch(linetype)
{
case _BLK:
++lblkline;
break;
case _CMT:
++lcmtline;
break;
case _NOR:
++lnorline;
break;
}
}
}
if( FLAG_ON == isformat ){
//printf("at end domaintop is %d\n", domaintop);
while(domaintop > 0)
{
free( domainS[--domaintop] );
frc2++;
}
fflush( outfd );
fclose( outfd );
}
if( FLAG_ON == iscount )
{
printf("file %s has %d normal lines, %d comment lines, %d blank lines\n",
_fname, lnorline, lcmtline, lblkline );
norline += lnorline;
cmtline += lcmtline;
blkline += lblkline;
}
fclose( infd );
if( FLAG_ON == isformat && FLAG_OFF == isbackup )
{
unlink( bakname );
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
printf( "end prase file:%s\n", _fname );
return ret;
}
void cntsource( char* line, int* sflag, int* cflag, linetype_t* linetype )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int i = 0, startclm = 0;
*linetype = _BLK;
for( startclm = 0; startclm < strlen( line ); startclm++ )
{
if( '\t' != line[startclm] && ' ' != line[startclm]
&& '\n' != line[startclm] && '\r' != line[startclm] )
break;
}
for( i = startclm; i < strlen( line ); i++ )
{
if( *linetype == _BLK ) *linetype = _CMT;
if( FLAG_OFF == *sflag )
{
if( FLAG_ON == checkcomment( line, i, cflag ) )
break;
}
if( FLAG_OFF == *cflag )
{
*linetype = _NOR;
checkstr( line, i, sflag);
}
}//for( i = 0; i < strlen( line ); i++ )
}
void adjfmt( char* line, char* buf, int* sflag, int* cflag,
int* domaintop, domain_t** domainS, int linenum)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int i = 0, startclm = 0;
char *linestart = 0;
int origtop = 0;
keyword_t* origkeywordS[DEPTH+1] = { 0 };
domain_t* localdom = NULL;
getorigkeywords( line, &origtop, origkeywordS );
sortorigbyoffset( origkeywordS, origtop );
for( startclm = 0; startclm < strlen( line ); startclm++ )
{
if( '\t' != line[startclm] && ' ' != line[startclm] && '\r' != line[startclm] )
break;
}
linestart = line + startclm;
for( i = startclm; i < strlen( line ); i++ )
{
if( FLAG_OFF == *sflag )
{
if( FLAG_ON == checkcomment( line, i, cflag ) )
break;
}
if( FLAG_OFF == *cflag )
{
checkstr( line, i, sflag);
}
if( FLAG_OFF == *cflag && FLAG_OFF == *sflag )
{
mykey_t domainkey = ruleoutkeywords( i, &origtop, origkeywordS );
if( KEYWORDCNT != domainkey )
{
pushdomain( domainkey, domaintop, domainS, linenum );
continue;
}
if( i > 0 && i < strlen(line) - 1 && '\'' == line[i-1] && '\'' == line[i+1] )
continue;
switch(line[i])
{
case '{':
pushdomain( _LB, domaintop, domainS, linenum );
localdom = domainS[*domaintop-1];
int j = i - 1;
while( j >= 0 )
{
if( '\t' == line[j] || ' ' == line[j])
{
--j;
continue;
}else{
if( '=' == line[j] )
localdom->issub = FLAG_OFF;
break;
}
}
if( FLAG_OFF == localdom->issub )
localdom->nexttabs = localdom->nexttabs + ( i - startclm ) / 8;
localdom = NULL;
break;
case '(':
pushdomain( _LS, domaintop, domainS, linenum );
localdom = domainS[*domaintop-1];
localdom->nexttabs = localdom->nexttabs + ( i - startclm ) / 8;
localdom = NULL;
break;
case '}':
popdomain( _RB, domaintop, domainS, linenum );
localdom = domainS[*domaintop-1];
if( i > startclm && localdom->linenum < linenum )
localdom->currtabs = localdom->nexttabs;
else if( FLAG_OFF == localdom->issub && localdom->linenum < linenum )
localdom->currtabs = localdom->nexttabs - 1;
localdom = NULL;
break;
case ')':
popdomain( _RS, domaintop, domainS, linenum );
break;
case ';':
popdomain( _SEMICOLON, domaintop, domainS, linenum );
break;
}
}//if( FLAG_OFF == *cflag && FLAG_OFF == *sflag )
}//for( i = 0; i < strlen( line ); i++ )
while( origtop > 0 ){
free( origkeywordS[--origtop] );
frc1++;
}
int currtabs = 0;
if( 0 < *domaintop )
{
localdom = domainS[*domaintop-1];
mykey_t localtype = localdom->type;
if( localdom->isself == FLAG_ON )
{
localdom->isself = FLAG_OFF;
currtabs = localdom->currtabs;
}else{
currtabs = localdom->nexttabs;
}
if( _CASE == localtype || _DEFAULT == localtype
|| _RS == localtype || _RB == localtype || _SEMICOLON == localtype )
{
free(localdom);
frc2++;
localtype = KEYWORDCNT;
localdom = NULL;
domainS[--*domaintop] = 0;
}
}
i = 0;
while( i < currtabs )
buf[i++] = '\t';
strncat( buf, linestart, strlen( linestart ) );
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void popdomain( mykey_t domainkey, int* domaintopp, domain_t** domainS, int linenum )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int domaintop = 0;
mykey_t prevtype = KEYWORDCNT;
domain_t* prevdom = NULL;
domaintop = *domaintopp;
if( domaintop == 0 )
{
if( _SEMICOLON != domainkey )
perr( "domainS empty" );
}
if( 0 < domaintop )
{
prevdom = domainS[domaintop-1];
prevtype = prevdom->type;
if( _CASE == prevtype || _DEFAULT == prevtype || _SEMICOLON == prevtype )
{
free(domainS[--domaintop]);
frc2++;
prevtype = KEYWORDCNT;
prevdom = NULL;
domainS[domaintop] = 0;
}else if( _RS == prevtype || _RB == prevtype )
{
if( _SEMICOLON == domainkey )
{
if( domaintop > 1 && domainS[domaintop-2]->type < _SWITCH )
{
domainS[domaintop-2]->nexttabs = prevdom->currtabs;
free(domainS[--domaintop]);
frc2++;
prevtype = KEYWORDCNT;
prevdom = NULL;
domainS[domaintop] = 0;
}else{
prevdom->type = _SEMICOLON;
}
}else{
free(domainS[--domaintop]);
frc2++;
prevtype = KEYWORDCNT;
prevdom = NULL;
domainS[domaintop] = 0;
}
}
if( prevdom == NULL && 0 < domaintop )
{
prevdom = domainS[domaintop-1];
prevtype = prevdom->type;
}
}
switch( domainkey )
{
case _RS:
if( prevtype == _LS )
{
prevdom->type = _RS;
if( prevdom->linenum < linenum )
{
prevdom->linenum = linenum;
prevdom->isself = FLAG_ON;
prevdom->currtabs = prevdom->nexttabs;
}else
prevdom->currtabs = prevdom->currtabs;
}else{ printf("too much _RS,linenum %d\n", linenum);}
break;
case _RB:
if( prevtype == _LB )
{
prevdom->type = _RB;
if( prevdom->linenum < linenum )
{
//prevdom->linenum = linenum;
prevdom->isself = FLAG_ON;
}
}else{ printf("too much _RB,linenum %d\n", linenum);}
break;
case _SEMICOLON:
if( prevtype < _SWITCH )
{
prevdom->type = _SEMICOLON;
if( prevdom->linenum < linenum )
{
prevdom->linenum = linenum;
prevdom->isself = FLAG_ON;
prevdom->currtabs = prevdom->nexttabs;
}else
prevdom->currtabs = prevdom->currtabs;
}
break;
default:
break;
}
*domaintopp = domaintop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void pushdomain( mykey_t domainkey, int* domaintopp, domain_t** domainS, int linenum )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int domaintop = 0;
mykey_t prevtype = KEYWORDCNT;
domain_t* prevdom = NULL;
domain_t* currdomain = NULL;
domaintop = *domaintopp;
if( domaintop == DEPTH )
perr("domainS full");
if( 0 < domaintop )
{
prevdom = domainS[domaintop-1];
prevtype = prevdom->type;
if( _CASE == prevtype || _DEFAULT == prevtype
|| _RS == prevtype || _RB == prevtype || _SEMICOLON == prevtype)
{
free(domainS[--domaintop]);
frc2++;
prevtype = KEYWORDCNT;
prevdom = NULL;
domainS[domaintop] = 0;
}
if( prevdom == NULL && 0 < domaintop )
{
prevdom = domainS[domaintop-1];
prevtype = prevdom->type;
}
}
//printf( "prevtype is %d\n", prevtype );
//domain_t* currdomain = (domain_t *)malloc( sizeof( domain_t ) );
switch( domainkey )
{
case _IF:
if( prevtype == _ELSE )
{
prevdom->type = _IF;
if( prevdom->linenum < linenum )
{
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else if( prevtype < _ELSE )
{
prevdom->type = _IF;
prevdom->nexttabs = prevdom->nexttabs + 1;
if( prevdom->linenum < linenum )
{
prevdom->currtabs = prevdom->currtabs + 1;
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else{
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _IF;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
// lines below
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
}
break;
case _WHILE:
if( prevtype < _ELSE )
{
prevdom->type = _WHILE;
prevdom->nexttabs = prevdom->nexttabs + 1;
if( prevdom->linenum < linenum )
{
prevdom->currtabs = prevdom->currtabs + 1;
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else{
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _WHILE;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
}
break;
case _DO:
if( prevtype < _ELSE )
{
prevdom->type = _DO;
prevdom->nexttabs = prevdom->nexttabs + 1;
if( prevdom->linenum < linenum )
{
prevdom->currtabs = prevdom->currtabs + 1;
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else{
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _DO;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
}
break;
case _FOR:
if( prevtype < _ELSE )
{
prevdom->type = _FOR;
prevdom->nexttabs = prevdom->nexttabs + 1;
if( prevdom->linenum < linenum )
{
prevdom->currtabs = prevdom->currtabs + 1;
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else{
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _DO;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
}
break;
case _ELSE:
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _ELSE;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom != NULL){
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
}else{ }
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
break;
case _SWITCH:
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _SWITCH;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom != NULL){
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
}else{ }
currdomain->nexttabs = currdomain->currtabs + 2;
domainS[domaintop++] = currdomain;
break;
case _CASE:
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _CASE;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom != NULL){
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs - 1;
else
currdomain->currtabs = prevdom->currtabs;
}else{ }
domainS[domaintop++] = currdomain;
break;
case _DEFAULT:
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _DEFAULT;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if( prevdom != NULL){
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs - 1;
else
currdomain->currtabs = prevdom->currtabs;
}else{ }
domainS[domaintop++] = currdomain;
break;
case _LS:
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _LS;
currdomain->isself = FLAG_ON;
currdomain->linenum = linenum;
if(prevdom != NULL){
if( prevdom->linenum < linenum ){
currdomain->currtabs = prevdom->nexttabs;
}else
currdomain->currtabs = prevdom->currtabs;
}else{
currdomain->currtabs = 0;
}
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
break;
case _LB:
if( prevtype < _CASE )// while do if for else swith
{
prevdom->type = _LB;
prevdom->issub = FLAG_ON;
if( prevdom->linenum < linenum )
{
prevdom->isself = FLAG_ON;
prevdom->linenum = linenum;
}
}else{
currdomain = (domain_t *)malloc( sizeof( domain_t ) );
mlcc2++;
currdomain->type = _LB;
currdomain->isself = FLAG_ON;
currdomain->issub = FLAG_ON;
currdomain->linenum = linenum;
if(prevdom != NULL){
if( prevdom->linenum < linenum )
currdomain->currtabs = prevdom->nexttabs;
else
currdomain->currtabs = prevdom->currtabs;
}else
currdomain->currtabs = 0;
currdomain->nexttabs = currdomain->currtabs + 1;
domainS[domaintop++] = currdomain;
}
break;
default:
perr("domain");
break;
}
*domaintopp = domaintop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
mykey_t ruleoutkeywords(int offset, int* origtopp, keyword_t** origkeywordS )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int origtop = *origtopp;
mykey_t domainkey = KEYWORDCNT;
while( origtop > 0 )
{
if( origkeywordS[origtop-1]->offset < offset )
{
free(origkeywordS[--origtop]);
frc1++;
origkeywordS[origtop] = 0;
}else if( origkeywordS[origtop-1]->offset == offset )
{
domainkey = origkeywordS[--origtop]->type;
free(origkeywordS[origtop]);
frc1++;
origkeywordS[origtop] = 0;
}else break;
}
*origtopp = origtop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return domainkey;
}
int getmid( keyword_t** tosort, int start, int end )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int mid = ( start + end ) / 2;
tosort[DEPTH] = tosort[start];
if( tosort[end]->offset > tosort[start]->offset )
{
tosort[start] = tosort[end];
tosort[end] = tosort[DEPTH];
}
tosort[DEPTH] = tosort[start];
if( tosort[mid]->offset > tosort[start]->offset )
{
tosort[start] = tosort[mid];
tosort[mid] = tosort[DEPTH];
}
tosort[DEPTH] = tosort[mid];
if( tosort[end]->offset < tosort[mid]->offset )
{
tosort[mid] = tosort[end];
tosort[end] = tosort[DEPTH];
}
tosort[DEPTH] = tosort[end];
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return tosort[end]->offset;
}
int mypartion( keyword_t** tosort, int start, int end )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int pivot = getmid( tosort, start, end );
while( start < end )
{
while( start < end && pivot <= tosort[start]->offset )
++start;
tosort[end] = tosort[start];
while(start < end && pivot >= tosort[end]->offset )
--end;
tosort[start] = tosort[end];
}
tosort[start] = tosort[DEPTH];
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return start;
}
void myinsertSort( keyword_t** tosort, int start, int end )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int i, j;
keyword_t* temp = NULL;
for( i = start + 1; i <= end; i++ )
{
temp = tosort[i];
for( j = i; j > start && temp->offset > tosort[j-1]->offset; j-- )
{
tosort[j] = tosort[j-1];
}
tosort[j] = temp;
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void myquickSort( keyword_t** tosort, int start, int end )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int pivot = 0;
if( end - start >= 7 )
{
while( start < end ){
pivot = mypartion( tosort, start, end );
myquickSort( tosort, start, pivot - 1 );
start = pivot + 1;
}
}else
myinsertSort( tosort, start, end );
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void sortorigbyoffset( keyword_t** origkeywordS, int origtop )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
if( 1 < origtop && origtop <= 8 )
{
myinsertSort( origkeywordS, 0, origtop - 1 );
}else if( origtop > 8 && origtop < DEPTH)
{
myquickSort( origkeywordS, 0, origtop - 1 );
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
int checkright(char r, mykey_t type)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int ret = 0;
if( ' ' == r || '\n' == r || '\t' == r )
return 1;
switch(type)
{
case _DO://do
case _ELSE://else
break;
case _WHILE://while
case _IF://if
case _FOR://for
case _SWITCH://switch
if( '(' == r )
ret = 1;
break;
case _DEFAULT:
if( ':' == r )
ret = 1;
break;
case _CASE://case
if( '\'' == r )
ret = 1;
break;
default:
perr("unknow keyword type");
break;
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return ret;
}
int checkleft(char l, mykey_t type)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int ret = 0;
if( '\t' == l || ' ' == l || '}' == l )
ret = 1;
if( '#' == l && ( _IF == type || _ELSE == type ) )
ret = 0;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return ret;
}
void getorigkeywords(char* line, int* origtop, keyword_t** origkeywordS )
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int i = 0;
int linelen = strlen(line);
while( KEYWORDCNT > i )
{
char* word = keywords[i];
int wordlen = strlen(word);
char* temp = line;
while(1)
{
temp = strstr( temp, word );
if( temp != NULL )
{
int offset = temp - line;
if( temp == line && linelen > 1 )
{
char r = *( temp + wordlen );
if( checkright( r, i ) )
pushorig( offset, i, origtop, origkeywordS );
}else if( temp == line + linelen - wordlen && linelen > wordlen )
{
char l = *( temp - 1 );
if( checkleft( l, i ) )
pushorig( offset, i, origtop, origkeywordS );
}else{
char r = *( temp + wordlen );
char l = *( temp - 1 );
//printf("outer....key word is %s offset is %d, type is %s, r is %c,l is %c\n\n", temp, offset, word, r ,l);
if( checkright( r, i ) && checkleft( l, i ) )
{
//printf("key word is %s offset is %d, type is %s, in line %d\n\n", temp, offset, word, linecounter);
pushorig( offset, i, origtop, origkeywordS );
}
}
temp = temp + wordlen;
}else break;
}
++i;
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
void pushorig(int offset, mykey_t type, int* origtopp, keyword_t** origkeywordS)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int origtop = *origtopp;
if( origtop < DEPTH )
{
keyword_t *elemt = ( keyword_t * )malloc( sizeof( keyword_t ) );
mlcc1++;
if( elemt == NULL )
{
perr("malloc");
}
elemt->offset = offset;
elemt->type = type;
//printf("in pushorig, origtop is %d\n", origtop);
origkeywordS[origtop++] = elemt;
}else perr("too much origkeywords");
*origtopp = origtop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
keyword_t* poporig(int* origtopp, keyword_t** origkeywordS)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
int origtop = *origtopp;
if( origtop > 0)
{
printf("in poporig, origtop is %d\n", origtop);
return origkeywordS[--origtop];
}else perr("no elem in origkeywordS");
*origtopp = origtop;
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return NULL;
}
int checkcomment( char* line, int index, int* flag)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
if( strlen(line) > index + 1 ){
if( '/' == line[index] )
{
if( '/' == line[index+1] ) return FLAG_ON;
else if( '*' == line[index+1] )
*flag = FLAG_ON;
}
if( FLAG_ON == *flag && '*' == line[index] && '/' == line[index+1] )
*flag = FLAG_OFF;
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
return 0;
}
void checkstr( char* line, int index ,int *flag)
{
//printf("%d:%s start\n",__LINE__,__FUNCTION__);
if( '\"' == line[index] && ( 0 == index || '\\' != line[index-1] ) )
{
*flag = *flag == FLAG_OFF ? FLAG_ON : FLAG_OFF;
}
//printf("%d:%s end\n",__LINE__,__FUNCTION__);
}
分享到:
相关推荐
3. 格式化代码:运行AStyle命令,并指定要格式化的源代码文件或整个目录。AStyle会创建一个备份文件,然后对原始文件进行格式化,以避免意外覆盖未保存的更改。 4. 检查结果:格式化完成后,你应该检查新格式化的...
代码格式化工具是程序员在编写和维护代码时不可或缺的辅助工具。它们的主要目的是为了自动整理代码的排版,使其遵循特定的编码规范和风格,从而提高代码的可读性和团队协作效率。在软件开发过程中,代码风格的一致性...
**Astyle代码格式化工具详解** Astyle,全称Artistic Style,是一款开源的源代码格式化、美化工具,主要用于C、C++、C++/CLI、Objective-C、C#和Java等编程语言的代码风格调整。这款工具设计的目标是帮助开发者统一...
2. **代码审查**:在代码审查阶段,格式化代码可以消除因格式问题引发的讨论,让审查更加专注于逻辑错误和设计问题。 3. **版本控制**:在使用版本控制系统(如Git)时,避免提交未格式化的代码,以减少不必要的冲突...
Visual Studio 2019(VS2019)作为一款强大的IDE,提供了集成各种工具的能力,包括代码格式化工具。在本篇内容中,我们将探讨如何在VS2019中利用开源的clang-format工具来实现源代码的自动化格式化和排版。 首先,...
强大的源码格式化工具可以批量处理整个目录下的代码文件,极大地提高了工作效率。 4. **集成到IDE**:许多格式化工具可以与主流的集成开发环境(IDE)如Visual Studio、Eclipse、IntelliJ IDEA等无缝集成,只需一键...
它能够帮助程序员自动整理和格式化代码,使代码风格统一,提高代码可读性和团队协作效率。对于使用Visual Studio 2010的开发者来说,AStyle是一个不可或缺的辅助工具。 **1. 安装与配置AStyle** 首先,你需要下载...
7. **版本控制整合**:如果你的项目使用了版本控制系统(如Git),可以配置提交钩子(pre-commit hook)来自动在提交前格式化代码,确保团队成员遵循统一的代码风格。 综上所述,FlexBuilder提供了丰富的代码格式化...
Linux操作系统在管理存储时,经常会使用到分区、格式化、挂载以及物理卷(Physical Volume)、卷组(Volume Group)和逻辑卷(Logical Volume)等概念。这些技术可以帮助用户更灵活地管理和分配磁盘空间。 首先,让...
"astyle"(Artistic Style)就是这样一个开源的源代码格式化、美化工具,它能帮助程序员自动格式化代码,使其符合特定的编码规范。本文将详细介绍astyle 2.04版本及其在Linux环境下的使用方法。 **一、Astyle简介**...
3. 在命令行中,可以使用以下基本语法来格式化代码文件: ``` astyle --style=style_name input_file ``` 其中,`style_name`是预设的代码风格,如`java`、`kr`或`linux`,而`input_file`是需要格式化的源代码...
标题 "fat文件系统格式化代码范例" 涉及的核心知识点主要集中在FAT(File Allocation Table)文件系统、文件系统的格式化过程以及在嵌入式系统中的应用。FAT文件系统是计算机中最古老的文件系统之一,广泛应用于各种...
接下来,我们将详细介绍不同操作系统下的VSCode格式化代码快捷键。 1. **Windows系统** - 在Windows系统下,VSCode格式化代码的默认快捷键是**“Shift + Alt + F”**。 - 这个快捷键可以帮助用户快速格式化当前...
3. **自动化构建**:通过在构建脚本中集成AStyle,可以在构建过程中自动格式化代码,保持代码库的一致性。 4. **学习与教育**:对于初学者,AStyle是一个很好的工具,可以帮助他们理解和遵循良好的编码规范。 总的...
许多程序员在格式化代码时都有一种偏爱的风格,而另一些程序员似乎完全不了解项目的现有格式化惯例(这给同事们的鼓舞)。 在项目上进行协作时,就通用的编码样式达成共识可能会有所帮助,但是手动执行该操作既乏味...
7. 兼容性:好的XML格式化工具应兼容各种操作系统,如Windows、Mac OS和Linux等。 在压缩包中,"XmlFormat.exe"是这个XML格式化工具的执行程序。双击运行后,用户可以直接打开XML文件进行格式化操作。需要注意的是...
Linux内核代码自动格式化配置文件 Linux内核编码排版风格 Linux内核自动格式化代码clang-format工具配套配 重命名为.clang-format放到VSCODE工作区下面即可
Astyle 是一种格式化代码工具,能够对代码进行格式化、美化和调整,以提高代码的可读性和维护性。Astyle 支持多种编程语言,包括 C、C++、Java、Python 等,并提供了多种格式化风格供用户选择。 Astyle 的优点: 1...
- 许多VB代码格式化工具可以作为Visual Studio或其他VB支持的IDE的插件,使得格式化代码的操作更加便捷,只需一键即可完成。 5. **版本控制系统友好** - 格式化后的代码在提交到版本控制系统时,可以减少不必要的...
以上就是Linux下GPS代码开发涉及的主要知识点。在实际项目中,开发者需要具备扎实的系统编程基础,对GPS协议有深入理解,并熟悉Linux系统和相关开发工具,才能有效地编写出稳定、高效的GPS应用。