diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c355e03 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 4 + +[Makefile] +indent_style = tab diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 53ac98c..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,18 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.0.0] - -### Added - -- First iteration of egc program -- Manpage for egc - -[unreleased]: https://github.com/cpmachado/egc/compare/v0.0.0...HEAD -[0.0.0]: https://github.com/cpmachado/egc/releases/tag/v0.0.0 diff --git a/Makefile b/Makefile index 20df7d3..744df64 100644 --- a/Makefile +++ b/Makefile @@ -8,21 +8,16 @@ include config.mk # Files for distribution PKGFILES = \ - CHANGELOG.md\ - CODE_OF_CONDUCT.md\ - CONTRIBUTING.md\ LICENSE\ Makefile\ README.md\ - config.def.h\ config.mk\ doc\ - include\ - man\ - src + egc.c\ + man -SRC = ${wildcard src/*.c} -OBJ = ${patsubst src/%.c,obj/%.o, ${SRC}} +SRC = egc.c +OBJ = ${SRC:.c=.o} BIN = egc @@ -34,6 +29,8 @@ clean: @echo cleaning @rm -rf ${OBJ} ${DEP} ${BIN} *.tar.gz *.zip +lint: + cpplint egc.c options: @echo "egc compilation flags" @@ -64,20 +61,9 @@ uninstall: @echo removing executable file from ${PREFIX}/bin @rm -f ${PREFIX}/bin/egc -config.h: config.def.h - cp config.def.h config.h - -obj/%.o: src/%.c - @mkdir -p obj - ${CC} ${CFLAGS} ${CPPFLAGS} -c -o $@ $< - ${BIN}: ${OBJ} ${CC} -o $@ $^ ${LDFLAGS} -obj/cli.o: src/cli.c -obj/util.o: src/util.c config.h -obj/rational.o: src/rational.c -obj/main.o: src/main.c - +egc.o: egc.c egc: ${OBJ} diff --git a/config.def.h b/config.def.h deleted file mode 100644 index e76d353..0000000 --- a/config.def.h +++ /dev/null @@ -1,3 +0,0 @@ -/* See LICENSE for details */ - -/* DEFINE DEFAULT VALUES HERE */ diff --git a/egc.c b/egc.c new file mode 100644 index 0000000..cb117a5 --- /dev/null +++ b/egc.c @@ -0,0 +1,199 @@ +/* Copyright 2024 cpmachado */ + +/* HEADERS */ +#include +#include +#include +#include + + +/* TYPES */ +typedef struct CliArgs { + int64_t *num, *den; + int32_t *csv, *straight; +} CliArgs; + + +/* FUNCTION DECLARATIONS */ + +void parseFlags(int32_t argc, char **argv, CliArgs args); + +void promptForParameter(char *str, int64_t *n); + +void csvOutput(int64_t *s, int64_t n); + +void simpleOutput(int64_t *s, int64_t n); + +void straightOutput(int64_t *s, int64_t n); + +int32_t computeUnitaryFractions(int64_t num, int64_t den, int64_t *s); + + +int32_t +main(int32_t argc, char **argv) { + int64_t s[BUFSIZ]; + int64_t n = 0; + int64_t num = -1, den = -1; + int32_t csv = 0, straight = 0; + + parseFlags(argc, argv, (CliArgs){ + .num = &num, + .den = &den, + .csv = &csv, + .straight = &straight + }); + if (num <= 0) { + promptForParameter("numerator: ", &num); + } + if (den <= 0) { + promptForParameter("denominator: ", &den); + } + + if (num > den || num <= 0) { + fprintf(stderr, "r not in ]0, 1[\n"); + exit(EXIT_FAILURE); + } + + n = computeUnitaryFractions(num, den, s); + if (csv) { + csvOutput(s, n); + } else if (straight) { + straightOutput(s, n); + } else { + simpleOutput(s, n); + } + return 0; +} + +/* FUNCTION DEFINITIONS */ + +void usage(void) { + fprintf(stdout, + "egc computes an unitary fraction expansion of a given n.\n" + " n is a rational, such that 0 < n < 1.\n\n" + "Usage: egc [OPTIONS] [-n NUMERATOR] [-d DENOMINATOR]\n" + "Options:\n" + " - h -- display help and exit\n" + " - v -- display version and exit\n" + " - n Numerator -- set numerator of fraction\n" + " - d Denominator -- set denominator of fraction\n" + " - c -- display csv output\n" + " - s -- display output in tuples \n"); +} + + +void version(void) { + fprintf(stdout, + "egc-" VERSION + " Copyright © 2023 " + ": cpmachado\n"); +} + +int32_t +parseVal(char *str, int64_t *n) { + *n = atoll(str); + if (*n <= 0) { + printf("Invalid value %s\n", str); + return 1; + } + return 0; +} + +void parseFlags(int32_t argc, char **argv, CliArgs args) { + int32_t i, j; + char *curr; + + for (i = 1; i < argc; i++) { + curr = argv[i]; + if (*curr != '-') { + break; + } + for (j = 1; curr[j] ; j++) { + switch (curr[j]) { + case 'h': usage(); exit(EXIT_SUCCESS); + case 'v': version(); exit(EXIT_SUCCESS); + case 'c': *(args.csv) = 1; break; + case 's': *(args.straight) = 1; break; + case 'n': + if (curr[j + 1] || i > argc - 1 + || parseVal(argv[i+1], args.num)) { + usage(); + exit(EXIT_FAILURE); + } + i++; + break; + case 'd': + if (curr[j + 1] || i > argc - 1 + || parseVal(argv[i+1], args.den)) { + usage(); + exit(EXIT_FAILURE); + } + i++; + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + } +} + +int32_t +computeUnitaryFractions(int64_t num, int64_t den, int64_t *s) { + int64_t n, i; + + s[0] = 0; + + for (i = 1; num > 1; i++) { + n = den / num + (den % num > 0); + s[i] = n; + num = num * n - den; + den = den * n; + } + + if (num > 0) { + s[i] = den; + i++; + } + return i; +} + +void +promptForParameter(char *str, int64_t *n) { + printf("%s", str); + scanf(" %ld", n); +} + +void +csvOutput(int64_t *s, int64_t n) { + int64_t i; + + printf("i,n_i\n"); + + for (i = 1; i < n; i++) { + printf("%ld,%ld\n", i, s[i]); + } +} + +void +simpleOutput(int64_t *s, int64_t n) { + int64_t i; + + for (i = 1; i < n; i++) { + printf("%ld\n", s[i]); + } +} + +void +straightOutput(int64_t *s, int64_t n) { + int64_t i; + + for (i = 1; i < n; i++) { + printf("(%ld, %ld)", i, s[i]); + if (i < n - 1) { + putchar(','); + } + } + putchar('\n'); +} + diff --git a/include/cli.h b/include/cli.h deleted file mode 100644 index 9f74e77..0000000 --- a/include/cli.h +++ /dev/null @@ -1,12 +0,0 @@ -/* See LICENSE for details */ - -/* CLI parameters */ -typedef struct CliArgs { - long long int *num, *den; - int *csv, *straight; -} CliArgs; - - -/* FUNCTION DECLARATIONS */ - -void parseFlags(int argc, char **argv, CliArgs args); diff --git a/include/util.h b/include/util.h deleted file mode 100644 index eab5600..0000000 --- a/include/util.h +++ /dev/null @@ -1,8 +0,0 @@ -/* See LICENSE for details */ - - -/* FUNCTION DECLARATIONS */ - -void usage(void); - -void version(void); diff --git a/src/cli.c b/src/cli.c deleted file mode 100644 index d2f9428..0000000 --- a/src/cli.c +++ /dev/null @@ -1,61 +0,0 @@ -/* See LICENSE for details */ - -/* HEADERS */ -#include -#include -#include - -#include "cli.h" -#include "util.h" - - -/* FUNCTION DEFINITIONS */ - -int -parseVal(char *str, long long int *n) { - *n = atoll(str); - if(*n <= 0) { - printf("Invalid value %s\n", str); - return 1; - } - return 0; -} - -void parseFlags(int argc, char **argv, CliArgs args) { - int i, j; - char *curr; - - for (i = 1; i < argc; i++) { - curr = argv[i]; - if (*curr != '-') { - break; - } - for (j = 1; curr[j] ; j++) { - switch (curr[j]) { - case 'h': usage(); exit(EXIT_SUCCESS); - case 'v': version(); exit(EXIT_SUCCESS); - case 'c': *(args.csv) = 1;break; - case 's': *(args.straight) = 1;break; - case 'n': - if (curr[j + 1] || i > argc - 1 - || parseVal(argv[i+1], args.num)) { - usage(); - exit(EXIT_FAILURE); - } - i++; - break; - case 'd': - if (curr[j + 1] || i > argc - 1 - || parseVal(argv[i+1], args.den)) { - usage(); - exit(EXIT_FAILURE); - } - i++; - break; - default: - usage(); - exit(EXIT_FAILURE); - } - } - } -} diff --git a/src/main.c b/src/main.c deleted file mode 100644 index fadecdb..0000000 --- a/src/main.c +++ /dev/null @@ -1,106 +0,0 @@ -/* See LICENSE for details */ - -/* HEADERS */ -#include -#include - -#include "cli.h" - - -/* FUNCTIONS */ - -int -computeUnitaryFractions(long long int num, long long int den, long long int *s) { - long long int n, i; - - s[0] = 0; - - for (i = 1; num > 1; i++) { - n = den / num + (den % num > 0); - s[i] = n; - num = num * n - den; - den = den * n; - } - - if(num > 0) { - s[i] = den; - i++; - } - return i; -} - -void -promptForParameter(char *str, long long int *n) { - printf("%s", str); - scanf(" %lld", n); -} - -void -csvOutput(long long int *s, long long int n) { - long long int i; - - printf("i,n_i\n"); - - for(i = 1; i < n; i++) { - printf("%lld,%lld\n", i, s[i]); - } -} - -void -simpleOutput(long long int *s, long long int n) { - long long int i; - - for(i = 1; i < n; i++) { - printf("%lld\n", s[i]); - } -} - -void -straightOutput(long long int *s, long long int n) { - long long int i; - - for(i = 1; i < n; i++) { - printf("(%lld, %lld)", i, s[i]); - if (i < n - 1) { - putchar(','); - } - } - putchar('\n'); -} - - -int -main(int argc, char **argv) { - long long int s[BUFSIZ]; - long long int n = 0; - long long int num = -1, den = -1; - int csv = 0, straight = 0; - - parseFlags(argc, argv, (CliArgs){ - .num = &num, - .den = &den, - .csv = &csv, - .straight = &straight - }); - if(num <= 0) { - promptForParameter("numerator: ", &num); - } - if(den <= 0) { - promptForParameter("denominator: ", &den); - } - - if (num > den || num <= 0) { - fprintf(stderr, "r not in ]0, 1[\n"); - exit(EXIT_FAILURE); - } - - n = computeUnitaryFractions(num, den, s); - if(csv) { - csvOutput(s, n); - } else if (straight) { - straightOutput(s, n); - } else { - simpleOutput(s, n); - } - return 0; -} diff --git a/src/util.c b/src/util.c deleted file mode 100644 index 92bf752..0000000 --- a/src/util.c +++ /dev/null @@ -1,31 +0,0 @@ -/* See LICENSE for details */ - -/* HEADERS */ -#include - -#include "config.h" - - -/* FUNCTION DEFINITIONS */ -void usage(void) { - fprintf(stdout, - "egc computes an unitary fraction expansion of a given n.\n" - " n is a rational, such that 0 < n < 1.\n\n" - "Usage: egc [OPTIONS] [-n NUMERATOR] [-d DENOMINATOR]\n" - "Options:\n" - " - h -- display help and exit\n" - " - v -- display version and exit\n" - " - n Numerator -- set numerator of fraction\n" - " - d Denominator -- set denominator of fraction\n" - " - c -- display csv output\n" - " - s -- display output in tuples \n"); -} - - -void version(void) { - fprintf(stdout, - "egc-" VERSION - " Copyright © 2023 " - ": cpmachado\n"); -} -