Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
clocf.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#ifdef _WIN32
6 #include <io.h>
7 #include <windows.h>
8 #define popen _popen
9 #define pclose _pclose
10 #define STDIN_FILENO 0
11#else
12 #include <unistd.h>
13 #include <sys/select.h>
14#endif
15
16#define MAX_LANG 100
17#define LINE_LEN 256
18#define MAX_CMD 4096
19
20typedef struct {
21 char name[64];
22 int code;
23} Language;
24
25void print_help(void) {
26 printf("clocf - cloc formatter\n\n");
27 printf("Usage:\n");
28 printf(" cloc [options] <path> | clocf # Process cloc output\n");
29 printf(" clocf [options] <path> # Run cloc automatically\n");
30 printf(" clocf --help # Show this help\n\n");
31 printf("Examples:\n");
32 printf(" cloc . | clocf # Pipe cloc output\n");
33 printf(" clocf src/ # Auto-run cloc on src/\n");
34 printf(" clocf --exclude-dir=vendor . # Pass options to cloc\n\n");
35}
36
37int stdin_has_data(void) {
38#ifdef _WIN32
39 HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
40 DWORD mode;
41 if (!GetConsoleMode(hStdin, &mode)) {
42 /* Not a console, likely a pipe */
43 return 1;
44 }
45 DWORD events;
46 if (GetNumberOfConsoleInputEvents(hStdin, &events) && events > 1) {
47 return 1;
48 }
49 return 0;
50#else
51 struct timeval tv;
52 fd_set fds;
53 tv.tv_sec = 0;
54 tv.tv_usec = 0;
55 FD_ZERO(&fds);
56 FD_SET(STDIN_FILENO, &fds);
57 select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
58 return FD_ISSET(STDIN_FILENO, &fds);
59#endif
60}
61
62int main(int argc, char *argv[]) {
63 if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)) {
64 print_help();
65 return 0;
66 }
67
68 FILE *input = stdin;
69
70 if (argc > 1) {
71 char cmd[MAX_CMD];
72 size_t pos = 0;
73 const char *cloc_cmd = "cloc";
74 size_t cloc_len = strlen(cloc_cmd);
75
76 if (cloc_len >= MAX_CMD) {
77 fprintf(stderr, "Error: Command too long\n");
78 return 1;
79 }
80
81 memcpy(cmd, cloc_cmd, cloc_len);
82 pos = cloc_len;
83
84 for (int i = 1; i < argc; i++) {
85 size_t arg_len = strlen(argv[i]);
86 int needs_quotes = (strchr(argv[i], ' ') != NULL) ? 1 : 0;
87 size_t required = pos + 1 + (needs_quotes ? 2 : 0) + arg_len;
88
89 if (required >= MAX_CMD) {
90 fprintf(stderr, "Error: Command too long\n");
91 return 1;
92 }
93
94 cmd[pos++] = ' ';
95 if (needs_quotes) {
96 cmd[pos++] = '"';
97 }
98 memcpy(cmd + pos, argv[i], arg_len);
99 pos += arg_len;
100 if (needs_quotes) {
101 cmd[pos++] = '"';
102 }
103 }
104 cmd[pos] = '\0';
105
106 input = popen(cmd, "r");
107 if (!input) {
108 fprintf(stderr, "Error: Failed to run cloc command\n");
109 return 1;
110 }
111 }
112 else if (!stdin_has_data()) {
113 fprintf(stderr, "Error: No input provided\n\n");
114 print_help();
115 return 1;
116 }
117
118 char line[LINE_LEN];
119 Language langs[MAX_LANG];
120 int langCount = 0;
121 int totalCode = 0;
122 int maxNameLen = 0;
123
124 while (fgets(line, sizeof(line), input)) {
125 size_t line_len = strlen(line);
126 if (strstr(line, "----") || line_len < 5) continue;
127 if (strstr(line, "Language") || strstr(line, "files") || strstr(line, "SUM")) continue;
128
129 char langName[64];
130 int files, blank, comment, code;
131
132 int matched = sscanf(line, "%63[^0-9] %d %d %d %d", langName, &files, &blank, &comment, &code);
133 if (matched == 5) {
134 size_t name_len = strlen(langName);
135 for (size_t i = name_len; i > 0 && (langName[i - 1] == ' ' || langName[i - 1] == '\t'); i--) {
136 langName[i - 1] = '\0';
137 name_len = i - 1;
138 }
139
140 if (langCount < MAX_LANG) {
141 size_t copy_len = name_len < 63 ? name_len : 63;
142 memcpy(langs[langCount].name, langName, copy_len);
143 langs[langCount].name[copy_len] = '\0';
144 langs[langCount].code = code;
145 totalCode += code;
146
147 if ((int)name_len > maxNameLen) {
148 maxNameLen = (int)name_len;
149 }
150
151 langCount++;
152 }
153 }
154 }
155
156 if (argc > 1) {
157 pclose(input);
158 }
159
160 printf("Total code lines: %d\n", totalCode);
161 printf("Language percentages:\n");
162 for (int i = 0; i < langCount; i++) {
163 double percent = (totalCode > 0) ? (langs[i].code * 100.0 / totalCode) : 0.0;
164 printf("%-*s : %6.2f%% (%d lines)\n", maxNameLen, langs[i].name, percent, langs[i].code);
165 }
166
167 return 0;
168}
fn main()
The main execution loop of the Phasor Shell.
Definition Shell.dox:38
void print_help(void)
Definition clocf.c:25
#define LINE_LEN
Definition clocf.c:17
#define MAX_LANG
Definition clocf.c:16
#define MAX_CMD
Definition clocf.c:18
int stdin_has_data(void)
Definition clocf.c:37
char name[64]
Definition clocf.c:21
int code
Definition clocf.c:22