#define _POSIX_C_SOURCE 200809L #include #include #include 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; }