#include #include #include #include #include #include #define MAX_PATH_SIZE 512 #define SEGMENT_LENGTH 2 #define LAST_SEGMENT_MAX_LENGTH 16 #define MAX_SEGMENTS_AMOUNT 64 typedef struct { size_t seperator; size_t length; } Segment; /// @returns Amount of segments size_t get_path_segments( Segment* dest, size_t dest_size, const char* path, size_t path_length) { size_t dest_i = 0; size_t i = 0; while (i < path_length) { size_t seperator = i; i += 1; while (path[i] != '\0' && path[i] != '/') { i += 1; } size_t length = i - seperator - 1; dest[dest_i] = (Segment) { seperator, length }; dest_i += 1; } return dest_i; } bool in_home_directory( const char* path, const Segment* segments, size_t segments_length, const char* username) { if (segments_length < 2) return false; if (strncmp(&path[segments[0].seperator + 1], "home", segments[0].length) != 0) { return false; } if (strncmp(&path[segments[1].seperator + 1], username, strlen(username)) != 0) { return false; } return true; } int main(void) { char cwd_path[MAX_PATH_SIZE] = ""; if (getcwd(cwd_path, sizeof(cwd_path)) == NULL) { fprintf(stderr, "error: failed to get current working directory: %s\n", strerror(errno)); exit(1); } const size_t cwd_path_length = strlen(cwd_path); const char* username = getlogin(); Segment segments[MAX_SEGMENTS_AMOUNT] = { 0 }; size_t segments_length = get_path_segments( segments, sizeof(segments) / sizeof(segments[0]), cwd_path, cwd_path_length); bool in_home_dir = in_home_directory(cwd_path, segments, segments_length, username); char short_path[MAX_PATH_SIZE] = ""; size_t segments_i = 0; size_t dest_i = 0; if (in_home_dir) { short_path[dest_i] = '~'; dest_i += 1; segments_i += 2; } for (; segments_i < segments_length - 1; segments_i += 1) { short_path[dest_i] = '/'; dest_i += 1; Segment* segment = &segments[segments_i]; for (size_t i = 0; i < segment->length && i < SEGMENT_LENGTH; i += 1) { short_path[dest_i] = cwd_path[segment->seperator + 1 + i]; dest_i += 1; } } if (!(segments_length == 2 && in_home_dir)) { short_path[dest_i] = '/'; dest_i += 1; Segment* last = &segments[segments_i]; if (last->length >= LAST_SEGMENT_MAX_LENGTH) { for (size_t i = 0; i < 5; i += 1) { short_path[dest_i] = cwd_path[last->seperator + 1 + i]; dest_i += 1; } for (size_t i = 0; i < 3; i += 1) { short_path[dest_i] = '.'; dest_i += 1; } for (size_t i = 0; i < 8; i += 1) { short_path[dest_i] = cwd_path[last->seperator + 1 + last->length - 8 + i]; dest_i += 1; } } else { for (size_t i = 0; i < last->length; i += 1) { short_path[dest_i] = cwd_path[last->seperator + 1 + i]; dest_i += 1; } } } short_path[dest_i] = '\0'; fputs(short_path, stdout); }