init
This commit is contained in:
commit
eae18257d7
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target/
|
||||||
|
build/
|
||||||
|
|
16
CMakeLists.txt
Normal file
16
CMakeLists.txt
Normal file
@ -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)
|
||||||
|
|
10
build_debug.sh
Normal file
10
build_debug.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
cmake . -B target/debug -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
|
||||||
|
cmake --build target/debug
|
||||||
|
|
||||||
|
|
||||||
|
|
16
build_release.sh
Normal file
16
build_release.sh
Normal file
@ -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 ../..
|
||||||
|
|
||||||
|
|
||||||
|
|
126
main.c
Normal file
126
main.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user