From eae18257d78f8ef30618a63e912c64311fb11071 Mon Sep 17 00:00:00 2001 From: Simon From Jakobsen Date: Tue, 16 Jul 2024 10:52:13 +0000 Subject: [PATCH] init --- .gitignore | 3 ++ CMakeLists.txt | 16 ++++++ build_debug.sh | 10 ++++ build_release.sh | 16 ++++++ main.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 build_debug.sh create mode 100644 build_release.sh create mode 100644 main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..94a9008 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target/ +build/ + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4c891c0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ + +cmake_minimum_required(VERSION 3.29) + +project(path-shortener VERSION 0.0.0 LANGUAGES C) + +add_executable(shortpath main.c) + +install(TARGETS shortpath) + +set(CPACK_PACKAGE_NAME path-shortener) +set(CPACK_PACKAGE_VENDOR simon) +set(CPACK_PACKAGE_DESCRIPTION "CWD path but short") +set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) +set(CPACK_VERBATIM_VARIABLES TRUE) +include(CPack) + diff --git a/build_debug.sh b/build_debug.sh new file mode 100644 index 0000000..0a7a6cd --- /dev/null +++ b/build_debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -xe + +cmake . -B target/debug -DCMAKE_BUILD_TYPE=Debug + +cmake --build target/debug + + + diff --git a/build_release.sh b/build_release.sh new file mode 100644 index 0000000..d64c2f0 --- /dev/null +++ b/build_release.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -xe + +cmake . -B target/release -DCMAKE_BUILD_TYPE=Release + +cmake --build target/release + +cd target/release + +cpack -G "TGZ" + +cd ../.. + + + diff --git a/main.c b/main.c new file mode 100644 index 0000000..8fd75f0 --- /dev/null +++ b/main.c @@ -0,0 +1,126 @@ +#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); +} +