FENIX_coreutils/expand.c

183 lines
3.7 KiB
C
Executable file

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int is_integer(char * str);
int is_comma_list(char * str);
int * comma_list_stops(char * str);
int comma_list_num_stops(char * str);
int stoi_mini(char * str);
int main(int argc, char ** argv) {
int *tab_stops;
int col_pos, num_tab_stops = 0, cur_stop;
FILE *current_file;
int i = 1, j; char c;
int all_good = 1;
if(argv[1][0] == '-' && argv[1][1] == 't' && argv[1][2] == '\0') {
i++;
j = 2;
if(is_comma_list(argv[j])) {
num_tab_stops = comma_list_num_stops(argv[j]);
tab_stops = comma_list_stops(argv[j]);
i++;
}
else {
while(is_integer(argv[j]) && j < (argc - 1)) {
num_tab_stops++;
i++;
j++;
}
tab_stops = calloc(num_tab_stops, sizeof(*tab_stops));
for(j = 2; j < num_tab_stops + 2; j++) {
tab_stops[j-2] = stoi_mini(argv[j]);
}
}
}
else if(argv[1][0] == '-' && argv[1][1] == 't' &&
argv[1][2] <= '9' && argv[1][2] >= '0'){
char * str = strtok(argv[1], "t");
str = strtok(NULL, "\0");
num_tab_stops = comma_list_num_stops(str);
tab_stops = comma_list_stops(str);
i++;
}
else {
tab_stops = malloc(sizeof(*tab_stops));
*tab_stops = 8;
num_tab_stops = 1;
}
for(i = i; i < argc; i++) {
current_file = fopen(argv[i], "r");
if(current_file == NULL) {
fprintf(stderr, "%s: %s: No such file or directory\n", argv[0], argv[i]);
all_good = 0;
}
else {
cur_stop = 0; col_pos = 0;
for(c = fgetc(current_file); c != EOF; c = fgetc(current_file)) {
if(c == '\t') {
if(num_tab_stops == 1) {
cur_stop++;
printf(" "); col_pos++;
while(col_pos % *tab_stops != 0) {
printf(" "); col_pos++;
}
}
else {
if(cur_stop >= num_tab_stops) {
printf(" ");
col_pos++;
cur_stop++;
}
else {
printf(" "); col_pos++;
while(col_pos % tab_stops[cur_stop] != 0) {
printf(" "); col_pos++;
}
cur_stop++;
}
}
}
else if(c == '\n') {
printf("%c", c);
col_pos = 0;
cur_stop = 0;
}
else {
printf("%c", c);
col_pos++;
}
}
fclose(current_file);
}
}
}
int is_integer(char * str) {
int i = 0;
while(str[i] != '\0' && str[i] != ',') {
if(str[i] > 57 || str[i] < 48) {
return 0;
}
i++;
}
return 1;
}
int is_comma_list(char * str) {
int i = 0, has_comma = 0;
while(str[i] != '\0') {
if((str[i] > 57 || str[i] < 48) && str[i] != ',') {
return 0;
}
if(str[i] == ',') {
has_comma = 1;
}
i++;
}
return has_comma;
}
int stoi_mini(char * str) {
int i, str_int = 0;
for(i = 0; str[i] != '\0' && str[i] != ','; i++) {
str_int *= 10;
switch(str[i]) {
case '0': str_int += 0; break;
case '1': str_int += 1; break;
case '2': str_int += 2; break;
case '3': str_int += 3; break;
case '4': str_int += 4; break;
case '5': str_int += 5; break;
case '6': str_int += 6; break;
case '7': str_int += 7; break;
case '8': str_int += 8; break;
case '9': str_int += 9; break;
default: return -1;
}
}
return str_int;
}
int comma_list_num_stops(char * str) {
int num_stops = 0;
for(int i = 0; str[i] != '\0'; i++) {
if(str[i] == ',') {
num_stops++;
}
}
return num_stops;
}
int * comma_list_stops(char * str) {
int * tab_stops;
int num_stops = comma_list_num_stops(str), i;
tab_stops = calloc(num_stops, sizeof(*tab_stops));
char * stop = strtok(str, ",");
i = 0;
while(stop != NULL && i < num_stops) {
tab_stops[i] = stoi_mini(stop);
i++;
stop = strtok(NULL, ",");
}
return tab_stops;
}