sttemp

Simple template manager
git clone git://git.konyahin.xyz/sttemp
Log | Files | Refs | LICENSE

commit 8a640d3acc4b01a60f6d20af787b43ae1f069b0d
parent 7b17daa3d4f340d9846d655b3302eb1acbd80f9d
Author: Anton Konyahin <me@konyahin.xyz>
Date:   Sun, 11 Feb 2024 20:21:20 +0300

rewrite in shell

Diffstat:
MLICENSE | 2+-
DMakefile | 50--------------------------------------------------
DREADME.md | 42------------------------------------------
Dsrc/config.h | 5-----
Dsrc/files.c | 48------------------------------------------------
Dsrc/files.h | 18------------------
Dsrc/main.c | 123-------------------------------------------------------------------------------
Dsrc/strings.c | 13-------------
Dsrc/strings.h | 9---------
Dsrc/token.c | 54------------------------------------------------------
Dsrc/token.h | 8--------
Dsttemp.1 | 37-------------------------------------
12 files changed, 1 insertion(+), 408 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,6 +1,6 @@ MIT/X Consortium License -(C)opyright 2021, 2022 Anton Konyahin <me@konyahin.xyz> +(C)opyright 2021-2024 Anton Konyahin <me@konyahin.xyz> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Makefile b/Makefile @@ -1,50 +0,0 @@ -.POSIX: -.SUFFIXES: -.PHONY: clean install uninstall test - -BIN = sttemp -SRCS = main.c token.c files.c strings.c -OBJC = ${SRCS:.c=.o} -CFLAGS = -Wall -Werror -Os -LDFLAGS = -s - -PREFIX = /usr/local -MANPREFIX = ${PREFIX}/share/man - -all: $(BIN) README.md - -strings.o: src/strings.c src/strings.h - $(CC) $(CFLAGS) -c src/strings.c - -files.o : src/files.c src/files.h - $(CC) $(CFLAGS) -c src/files.c - -token.o: src/token.c src/token.h - $(CC) $(CFLAGS) -c src/token.c - -main.o : src/main.c src/config.h - $(CC) $(CFLAGS) -c src/main.c - -$(BIN): main.o files.o strings.o token.o - $(CC) main.o files.o strings.o token.o -o $(BIN) - -README.md: $(BIN).1 - pandoc $(BIN).1 -o README.md - -clean: - rm -f $(BIN) - rm -f *.o - -install: $(BIN) - mkdir -p $(DESTDIR)$(PREFIX)/bin - mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - install -m 775 $(BIN) $(DESTDIR)$(PREFIX)/bin/ - install -m 644 $(BIN).1 $(DESTDIR)$(MANPREFIX)/man1/ - -uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN) - rm -f $(DESTDIR)$(MANPREFIX)/man1/$(BIN).1 - -test: $(BIN) - ./$(BIN) test && cat test && rm -f test - diff --git a/README.md b/README.md @@ -1,42 +0,0 @@ -# NAME - -sttemp - simple template manager - -# SYNOPSIS - -**sttemp** \[**-h**\] - -**sttemp** \[**-e**\] *template* \[*output*\] - -# DESCRIPTION - -**sttemp** copy file from your template directory and fill all -substitutions with user input, or environment variables. Template -directory and substitution pattern described in **src/config.h** file, -in suckless style. You can use **\~** as **first** symbol of your path, -for relative path from your home directory. - -# OPTIONS - -**-h** - -: displays help information - -**-e** - -: use environment variables for fill substitution in template, if - **sttemp** can\'t find environment variable with needed name, it - will use user input - -**template** - -: name of file in your templates directory, which will use to create - new file - -**output** - -: name of target file, if omit - **sttemp** will use template name - -# AUTHOR - -Anton Konyahin \<*me\@konyahin.xyz*\> diff --git a/src/config.h b/src/config.h @@ -1,5 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -const char template_dir[] = "~/project/templates/"; -const char pattern_start[] = "{|"; -const char pattern_end[] = "|}"; diff --git a/src/files.c b/src/files.c @@ -1,48 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include "files.h" - - -char* freadall(FILE* input, size_t* length) { - char *buf = malloc(BUF_SIZE); - size_t used = 0; - size_t len = 0; - - do { - buf = realloc(buf, BUF_SIZE + used); - len = fread(buf + used, sizeof(char), BUF_SIZE, input); - used = used + len; - } while (len != 0); - - buf = realloc(buf, used + 1); - buf[used] = '\0'; - - *length = used; - - return buf; -} - -char* freadline(FILE *input) { - char *buf = malloc(BUF_SIZE); - size_t used = 0; - - while(1) { - buf = realloc(buf, BUF_SIZE + used); - if (fgets(buf + used, BUF_SIZE, input) == NULL) { - break; - } - char *new_line = strchr(buf + used, '\n'); - if (new_line != NULL) { - used = new_line - buf; - break; - } else { - used += BUF_SIZE - 1; - } - } - - buf = realloc(buf, used + 1); - buf[used] = '\0'; - - return buf; -} - diff --git a/src/files.h b/src/files.h @@ -1,18 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#define BUF_SIZE 2 * 1024 * 1024 - -/** - * Read line from file `input` and return it content - * without new line symbol. - */ -char* freadline(FILE *input); - -/** - * Read all content of file `input` and return it. - */ -char* freadall(FILE* input, size_t* length); diff --git a/src/main.c b/src/main.c @@ -1,123 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include "config.h" -#include "files.h" -#include "strings.h" -#include "token.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -const int pat_start_len = sizeof(pattern_start) / sizeof(pattern_start[0]) - 1; -const int pat_end_len = sizeof(pattern_end) / sizeof(pattern_end[0]) - 1; - -enum search {WO_ENV, W_ENV}; -typedef enum search Search; - -void show_usage() { - printf("sttemp - simple template manager\n"); - printf("Usage:\n\tsttemp template_name [file_name]\n"); -} - -FILE* open_template(const char* template_name) { - const char* dir; - if (template_dir[0] == '~') { - char* homedir = getenv("HOME"); - dir = strconcat(homedir, template_dir + 1); - } else { - dir = template_dir; - } - char *template_path = strconcat(dir, template_name); - FILE *template = fopen(template_path, "rb"); - free(template_path); - return template; -} - -char* get_placeholder_value(Search search_type, const char* name, size_t length) { - char* value = find_in_tokens(name, length); - if (value != NULL) { - return value; - } - char* new_name = strndup(name, length); - if (search_type == W_ENV) { - value = getenv(new_name); - if (value != NULL) { - free(new_name); - return value; - } - } - - printf("Enter value for {%.*s}: ", (int) length, name); - value = freadline(stdin); - add_new_token(new_name, value); - return value; -} - -int main(int argc, char *argv[]) { - if (argc < 2) { - show_usage(); - return 1; - } - - if (strcmp("-h", argv[1]) == 0) { - show_usage(); - return 0; - } - - size_t first_file_arg = 1; - Search search_type = WO_ENV; - if (strcmp("-e", argv[1]) == 0) { - search_type = W_ENV; - first_file_arg++; - } - - char* template_name = argv[first_file_arg++]; - char* target_name; - if (first_file_arg < argc) { - target_name = argv[first_file_arg]; - } else { - target_name = template_name; - } - - FILE* template = open_template(template_name); - if (template == NULL) { - fprintf(stderr, "Template doesn't exist: %s\n", template_name); - return 1; - } - - size_t buf_len = 0; - char *buf = freadall(template, &buf_len); - fclose(template); - - FILE* output = fopen(target_name, "w"); - - char *start = buf; - char *last = start; - while ((start = strstr(start, pattern_start)) != NULL) { - fwrite(last, sizeof(char), start - last, output); - start = start + pat_start_len; - - char* end = strstr(start, pattern_end); - if (end == NULL) { - fprintf(stderr, "Unfinished pattern: %10s", start); - fclose(output); - free(buf); - return 1; - } - - size_t token_length = end - start; - char *value = get_placeholder_value(search_type, start, token_length); - fwrite(value, sizeof(char), strlen(value), output); - - start = end + pat_end_len; - last = start; - } - - fwrite(last, sizeof(char), buf_len - (last - buf), output); - fclose(output); - free(buf); - free_tokens(); - - return 0; -} diff --git a/src/strings.c b/src/strings.c @@ -1,13 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include "strings.h" - -char* strconcat(const char* first, const char* second) { - size_t first_len = strlen(first); - size_t second_len = strlen(second); - char *buf = malloc(first_len + second_len + 1); - memcpy(buf, first, first_len); - memcpy(buf + first_len, second, second_len + 1); - return buf; -} - diff --git a/src/strings.h b/src/strings.h @@ -1,9 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include <stdlib.h> -#include <string.h> - -/** - * Concat two string buffers in new one. - */ -char* strconcat(const char* first, const char* second); diff --git a/src/token.c b/src/token.c @@ -1,54 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include "token.h" - -struct token { - char* name; - char* value; -}; -typedef struct token Token; - -Token* new_token(char* name, char* value) { - Token* token = malloc(sizeof(Token)); - token->name = name; - token->value = value; - return token; -} - -void free_token(Token* token) { - free(token->name); - free(token->value); - free(token); -} - -Token** tokens = NULL; -size_t tokens_len = 0; - -void free_tokens() { - for (size_t i = 0; i < tokens_len; i++) { - free_token(tokens[i]); - } - free(tokens); - tokens = NULL; -} - -void add_token(Token* token) { - tokens = realloc(tokens, sizeof(Token) * ++tokens_len); - tokens[tokens_len - 1] = token; -} - -void add_new_token(char* name, char* value) { - Token* token = new_token(name, value); - add_token(token); -} - -char* find_in_tokens(const char* name, size_t length) { - // O(n) = n, but I don't worry about it right now - for (size_t i = 0; i < tokens_len; i++) { - if (strncmp(tokens[i]->name, name, length) == 0) { - return tokens[i]->value; - } - } - return NULL; -} - diff --git a/src/token.h b/src/token.h @@ -1,8 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#include <stdlib.h> -#include <string.h> - -void free_tokens(); -void add_new_token(char* name, char* value); -char* find_in_tokens(const char* name, size_t length); diff --git a/sttemp.1 b/sttemp.1 @@ -1,37 +0,0 @@ -.TH STTEMP 1 2022-01-09 V1.0 -.SH NAME -sttemp \- simple template manager -.SH SYNOPSIS -.B sttemp -[\fB\-h\fR] - -.B sttemp -[\fB\-e\fR] -\fItemplate\fR -[\fIoutput\fR] -.SH DESCRIPTION -.B sttemp -copy file from your template directory and fill all -substitutions with user input, or environment variables. -Template directory and substitution pattern described in -\fBsrc/config.h\fR file, in suckless style. You can use -\fB~\fR as \fBfirst\fR symbol of your path, for relative -path from your home directory. -.SH OPTIONS -.TP -.BI \-h -displays help information -.TP -.BI \-e -use environment variables for fill substitution in -template, if \fBsttemp\fR can't find environment variable -with needed name, it will use user input -.TP -.BI template -name of file in your templates directory, which will use -to create new file -.TP -.BI output -name of target file, if omit - \fBsttemp\fR will use template name -.SH AUTHOR -Anton Konyahin <\fIme@konyahin.xyz\fR>