日期:2014-05-16  浏览次数:20658 次

Linux下格式化代码的小工具
/**
 * 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, comme