#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BUFFSIZE 3 /* >= 2 */
char *mygetline(FILE *fp) {
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff;
char *p, *r;
int fEOL;
if ((outbuff_malloc = malloc(1)) == NULL) {
return NULL;
}
*outbuff_malloc = '\0';
fEOL = 0;
do {
r = fgets(inbuff, BUFFSIZE, fp);
if (r == NULL)
break;
for (p = inbuff; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
fEOL = 1;
if ((tmpbuff = realloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) == NULL) {
free(outbuff_malloc);
return NULL;
}
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
if (strlen(outbuff_malloc) > 0) {
for (p = outbuff_malloc; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
*(p - 1) = '\0';
return outbuff_malloc;
}
free(outbuff_malloc);
return NULL;
}
struct queue {
struct queue *next;
struct queue *prev;
void *data;
};
struct queue *pushQ(struct queue *root, void *data) {
struct queue *p;
if ((p = malloc(sizeof(struct queue))) == NULL)
return NULL;
p->next = root;
p->prev = root->prev;
root->prev->next = p;
root->prev = p;
p->data = data;
return p;
}
void *popQ(struct queue *root) {
struct queue *p;
void *q;
if (root->next != root) {
p = root->next;
p->prev->next = p->next;
p->next->prev = p->prev;
q = p->data;
free(p);
return q;
}
return NULL;
}
void task_step(char *name, FILE *fp) {
char *text, *p;
int totalln, commentln, executeln;
int state_commentin, state_stringin, state_multistringin;
int flag_commentexist, flag_bracesexist, flag_nobracesexist, flag_alphabetexist, flag_commentonly;
totalln = commentln = executeln = 0;
state_multistringin = state_commentin = 0;
while ((text = mygetline(fp)) != NULL) {
flag_commentexist = flag_bracesexist = flag_alphabetexist = flag_nobracesexist = 0;
flag_commentonly = 1;
if (state_commentin)
flag_commentexist = 1;
if (state_multistringin)
state_stringin = 1;
else
state_stringin = 0;
for (p = text; *p != '\0'; p++) {
if (*p == ' ' || *p == '\t')
continue;
if (*p == '\"' && state_stringin && !state_commentin)
state_stringin = 0;
else if (*p == '\"' && !state_stringin && !state_commentin)
state_stringin = 1;
if (!state_commentin) {
if (*p == '{' || *p == '}' ) {
flag_bracesexist = 1;
}
if (isalpha(*p & 0xff)) {
flag_alphabetexist = 1;
flag_nobracesexist = 1;
flag_commentonly = 0;
}
}
if (!state_commentin && !state_stringin && *p == '/' ) {
if (*(p + 1) == '/') {
flag_commentexist = 1;
flag_nobracesexist = 1;
break;
} else if (*(p + 1) == '*') {
flag_commentexist = 1;
flag_nobracesexist = 1;
state_commentin = 1;
continue;
}
} else if (state_commentin && !state_stringin && *p == '*') {
if (*(p + 1) == '/') {
flag_commentexist = 1;
flag_nobracesexist = 1;
state_commentin = 0;
continue;
}
}
}
if (state_stringin)
state_multistringin = 1;
else
state_multistringin = 0;
/* printf("%s\n", text); */
if (flag_commentexist)
commentln++;
if ((flag_bracesexist && !flag_nobracesexist) || flag_commentonly) {
} else {
executeln++;
}
totalln++;
/*---------------------------------------*/
free(text);
}
printf("%s : line: %d, executive: %d, comment: %d, comment-percentage %d %%\n",
name,
totalln,
executeln,
commentln,
(int)((double)commentln / (double)totalln * 100.0));
return;
}
#include <sys/stat.h>
#include <dirent.h>
static struct queue fileQS = { &fileQS, &fileQS, NULL };
static struct queue dirQS = { &dirQS, &dirQS, NULL };
int main(int argc, char **argv) {
struct stat buff;
char *p, *q;
if (argc <= 1) {
fprintf(stderr, "usage: %s file|dir [[file|dir]...]\n", argv[0]);
exit(-1);
}
argc--;
argv++;
while (*argv != NULL) {
if (stat(*argv, &buff) != 0) {
printf("%s: not found.\n", *argv);
} else {
if ((p = malloc(strlen(*argv) + 1)) == NULL) {
fprintf(stderr, "cannot allocate enough memory(path), aborted\n");
exit(-1);
}
strcpy(p, *argv);
if(buff.st_mode & S_IFREG) {
if (!pushQ(&fileQS, (void *)p)) {
fprintf(stderr, "cannot allocate enough memory(fileQ), aborted\n");
exit(-1);
}
} else if (buff.st_mode & S_IFDIR) {
if (!pushQ(&dirQS, (void *)p)) {
fprintf(stderr, "cannot allocate enough memory(dirQ), aborted\n");
exit(-1);
}
}
}
argv++;
}
while ((p = popQ(&dirQS)) != NULL) {
DIR *dir;
struct dirent *dirent;
dir = opendir(p);
while ((dirent = readdir(dir)) != NULL) {
if (strstr(dirent->d_name, ".") == dirent->d_name)
continue;
if (strstr(dirent->d_name, "..") == dirent->d_name)
continue;
if ((q = malloc(strlen(p) + strlen(dirent->d_name) + 2)) == NULL) {
fprintf(stderr, "cannot allocate enough memory(dirent), aborted\n");
exit(-1);
}
strcpy(q, p);
strcat(q, "/");
strcat(q, dirent->d_name);
if (stat(q, &buff) != 0) {
fprintf(stderr, "internal error: %s\n", q);
} else {
if(buff.st_mode & S_IFREG) {
if (!pushQ(&fileQS, (void *)q)) {
fprintf(stderr, "cannot allocate enough memory(fileQ), aborted\n");
exit(-1);
}
} else if (buff.st_mode & S_IFDIR) {
if (!pushQ(&dirQS, (void *)q)) {
fprintf(stderr, "cannot allocate enough memory(dirQ), aborted\n");
exit(-1);
}
}
}
} /* readdir() */
closedir(dir);
free(p);
} /* popQ() */
while ((p = popQ(&fileQS)) != NULL) {
char *q;
FILE *fp;
for (q = p; *q; q++)
;
for (;q >= p && *q != '.'; q--)
;
if (*(q + 1) == 'c') {
fp = fopen(p, "rt");
task_step(p, fp);
fclose(fp);
}
free(p);
}
return 0;
}
/* end */