commit 3fd4e0182afec4fe3548689c25a74fe11735d066 Author: MatMasIt Date: Wed Oct 6 17:50:47 2021 +0200 Add files via upload diff --git a/README.md b/README.md new file mode 100644 index 0000000..24a1212 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Ropipe +> Convert roman numbers to integers and vice-versa in pipes +## What is ropipe? +Ropipe converts decimal integers to roman numbers and vice versa, reading from stdin and printing to stdout, it is meant to primarily be used in pipes. +Default is integer to roman. +## Options +* -r : Roman to integer. Integer to roman is the default. +## Installation + 1. Clone this repository + 2. `cd` into it + 3. run + ```sh + sudo bash install.sh + ``` + (The program is compiled at this time, you may check the script and the program out beforehand) +## Examples +Once installed, you can find sample files in the project dir. +```sh +ropipe < arabic.txt +``` +```sh +ropipe -r < roman.txt +``` +## Manpage + +A manpage is installed alongside the program, try running `man ropipe` + +## Updates + +There is no automatic update system as of yet, you are advised to regularly visit https://github.com/MatMasIt/ropipe, download and re-run the installer in order to get updates \ No newline at end of file diff --git a/arabic.txt b/arabic.txt new file mode 100644 index 0000000..88df454 --- /dev/null +++ b/arabic.txt @@ -0,0 +1,4 @@ +1 +10 +123 +321 diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..12d0b15 --- /dev/null +++ b/install.sh @@ -0,0 +1,16 @@ +if [ $(id -u) -ne 0 ] + then echo "Please run as root" + exit +fi +if [ -z $(which gcc) ] + then echo "Please install gcc first" + exit +fi +echo "Compiling ropipe" +gcc -o ropipe ropipe.c +mkdir -p /usr/local/share/man/man1/ +echo "Copying man file" +cp ropipe.1 /usr/local/share/man/man1/ropipe.1 +echo "Installing binary" +cp ropipe /usr/bin/ropipe +echo "Done" \ No newline at end of file diff --git a/roman.txt b/roman.txt new file mode 100644 index 0000000..9d62580 --- /dev/null +++ b/roman.txt @@ -0,0 +1,4 @@ +IV +V +VII +MCC diff --git a/ropipe b/ropipe new file mode 100644 index 0000000..051cf33 Binary files /dev/null and b/ropipe differ diff --git a/ropipe.1 b/ropipe.1 new file mode 100644 index 0000000..e2a71d8 --- /dev/null +++ b/ropipe.1 @@ -0,0 +1,18 @@ +.TH ROPIPE 1 "06 October 2021" +.SH NAME +ropipe - Convert roman numbers to integers and vice-versa in pipes +.SH SYNOPSIS +ropipe [ -r ] +.SH DESCRIPTION +Ropipe converts decimal integers to roman numbers and vice versa, reading from stdin and printing to stdout, it is meant to primarily be used in pipes. +Default is integer to roman. +.SS Options +.TP +-r +Roman to integer. Integer to roman is the default. +.SH FILES +.TP +/usr/bin/ropipe +The program +.SH BUGS +Send bug reports at https://github.com/MatMasIt/ropipe \ No newline at end of file diff --git a/ropipe.c b/ropipe.c new file mode 100644 index 0000000..3bced61 --- /dev/null +++ b/ropipe.c @@ -0,0 +1,139 @@ +#include +#include +#include +#define RDIGITS 14 +/* + * Returns the value of a roman numeral digit + * @param {char} c - Roman digit +*/ +static int roman_to_integer(char c) +{ + switch (c) + { + case 'I': + return 1; + case 'V': + return 5; + case 'X': + return 10; + case 'L': + return 50; + case 'C': + return 100; + case 'D': + return 500; + case 'M': + return 1000; + default: + return 0; + } +} +/* + * Returns the interger value of a roman number + * @param {string} s - Roman number +*/ +int roman_to_int(char *s) +{ + int i, int_num = roman_to_integer(s[0]); + + for (i = 1; s[i] != '\0'; i++) + { + int prev_num = roman_to_integer(s[i - 1]); + int cur_num = roman_to_integer(s[i]); + if (prev_num < cur_num) + { + int_num = int_num - prev_num + (cur_num - prev_num); + } + else + { + int_num += cur_num; + } + } + return int_num; +} +/* + * Map of roman digits symbols and their value + * @elem {string} sym - digit symbol + * @elem {int} val - digit symbol +*/ +typedef struct +{ + char *sym; + int val; +} numeral; +/* + * Returns greatest numeral index + * @elem {numeral} nu - map of roman digits symbols and their value + * @elem {int} num - number +*/ +int maxNume(numeral *nu, int num) +{ + int i, index; + for (i = 0; i < RDIGITS; i++) + { //RDIGITS numerals in array + if (nu[i].val <= num) + index = i; + } + //gretest value numeral index, not greater than number + return index; +} +/* + * Prints roman number from integer + * @elem {numeral} nu - map of roman digits symbols and their value + * @elem {int} num - number +*/ +void decToRoman(numeral *nu, int num) +{ + int max; + if (num != 0) + { + max = maxNume(nu, num); + printf("%s", nu[max].sym); + num -= nu[max].val; //decrease number + decToRoman(nu, num); //recursively print numerals + } +} +/* + * Main + * @elem {int} argc - Argument count + * @elem {string[]} argv - Strings array +*/ +int main(int argc, char *argv[]) +{ + int direction = 0; + /* + * 0: integer to roman (default) + * 1: roman to integer + */ + for (int i = 0; i < argc; i++) + { + if (strcmp(argv[i], "-r")) + { + direction = 1; + } + else + { + direction = 0; + } + } + numeral nume[RDIGITS] = {{"I", 1}, {"IV", 4}, {"V", 5}, {"IX", 9}, {"X", 10}, {"XL", 40}, {"L", 50}, {"XC", 90}, {"C", 100}, {"CD", 400}, {"D", 500}, {"CM", 900}, {"M", 1000}, {"MMMM", 4000}}; + char *str1; + int inputint = 0; + switch (direction) + { + case 0: + while (scanf("%s", &str1) && !feof(stdin)) // read integers and convert to roman + { + printf("%d\n", roman_to_int(&str1)); + } + break; + case 1: + while (scanf("%d", &inputint) && !feof(stdin)) // read roman and convert to integers + { + decToRoman(nume, inputint); + printf("\n"); + } + break; + } + return 0; +}