Narthex

Modular dictionary generator
git clone git://mcdim.xyz/Narthex.git
Log | Files | Refs | README | LICENSE

ncom.c (4212B)


      1 /*
      2  *    ncom - Narthex combinator
      3  *
      4  *  By Michael Constantine Dimopoulos https://mcdim.xyz	<mk@mcdim.xyz>
      5  *  License: GNU GPL v3
      6  *
      7  *  ncom iterates over stdin and after printing the dictionary as is, it
      8  *  will print it again but will also append every line of stdin to each
      9  *  iteration creating, that way, a list of combinations (pairs) of
     10  *  the lines.
     11  *
     12  *  By default, it will append when the *  base is the same as the
     13  *  appended part (i.e wordword), but that can be *  switched off with the
     14  *  -b flag. It can also use other separators, such *  as a hyphen or a
     15  *  dot, all with their own flags.
     16  *
     17  * * * * * * * *
     18  *
     19  *  This program is free software: you can redistribute it and/or modify
     20  *  it under the terms of the GNU General Public License as published by
     21  *  the Free Software Foundation, either version 3 of the License, or
     22  *  (at your option) any later version.
     23  *
     24  *  This program is distributed in the hope that it will be useful,
     25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     27  *  GNU General Public License for more details.
     28  *
     29  *  You should have received a copy of the GNU General Public License
     30  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
     31  *
     32  */
     33 
     34 #include <stdlib.h>
     35 #include <stdio.h>
     36 #include <string.h>
     37 #include <unistd.h>
     38 #include <ctype.h>
     39 
     40 #define VERSION "v1.2.0"
     41 #define BUFFER_SIZE 256
     42 
     43 static void
     44 help(char *exename)
     45 {
     46 	printf( "ncom - Narthex combinator %s\n"
     47 		"By Michael Constantine Dimopoulos <mk@mcdim.xyz>\n\n"
     48 
     49 		"-d  use delimiters (specified in a string)\n"
     50 		"-n  exclude numerical bases\n"
     51 		"-b  exclude base-appended\n"
     52 		"-h  print this panel & exit\n"
     53 		"-v  print current version & exit\n\n"
     54 
     55 		"Usage:	cat [FILENAME] | %s [-d] [-n] [-b]\n"
     56 		"        %s [FILENAME] [OPTIONS]\n",
     57 		VERSION, exename, exename);
     58 	exit(EXIT_SUCCESS);
     59 }
     60 
     61 static inline void
     62 die(char *str)
     63 {
     64 	printf("%s\n", str);
     65 	exit(EXIT_SUCCESS);
     66 }
     67 
     68 static FILE *
     69 save_stdin(FILE *f)
     70 {
     71 	FILE *f2 = tmpfile();
     72 	char buffer[BUFFER_SIZE];
     73 	while(fgets(buffer, sizeof(buffer), f) != NULL) {
     74 		fprintf(f2, "%s", buffer);
     75 	}
     76 	return f2;
     77 }
     78 
     79 static int
     80 isnumber(char * str)
     81 {
     82 	for (int i = 0; str[i] != '\0'; i++) {
     83 		if (isdigit(str[i]) != 0)
     84 			return 1;
     85 	}
     86 	return 0;
     87 }
     88 
     89 static inline void
     90 ssprint(char *buffer, char *buffer2, char del, int n, int b)
     91 {
     92 	if ((n == 1 && isnumber(buffer) == 0) || n == 0) {
     93 		if ((b == 1 && strcmp(buffer,buffer2) != 0) || b == 0) {
     94 			if (del == ' ')
     95 				printf("%s%s\n", buffer, buffer2);
     96 			else
     97 				printf("%s%c%s\n", buffer, del, buffer2);
     98 		}
     99 	}
    100 }
    101 
    102 static void
    103 com(FILE *f2, FILE *f3, char del, int n, int b)
    104 {
    105 	char buffer[BUFFER_SIZE];
    106 	char buffer2[BUFFER_SIZE];
    107 
    108 	while (fgets(buffer, sizeof(buffer), f2) != NULL) {
    109 		strtok(buffer, "\n");
    110 		while (fgets(buffer2, sizeof(buffer2), f3) != NULL) {
    111 			strtok(buffer2, "\n");
    112 			ssprint(buffer, buffer2, del, n, b);
    113 		}
    114 
    115 		rewind(f3);
    116 	}
    117 }
    118 
    119 static void
    120 print_only(FILE *f)
    121 {
    122 	char buffer[BUFFER_SIZE];
    123 	while (fgets(buffer, sizeof(buffer), f) != NULL) {
    124 		printf("%s", buffer);
    125 	}
    126 }
    127 
    128 void
    129 main(int argc, char *argv[])
    130 {
    131 	int d, b, n, t;
    132 	d = b = n = t = 0;
    133 	char *cvalue = NULL;
    134 	char del[10];
    135 	char filename[256];
    136 	int filename_given = 0;
    137 	int index;
    138 	int c;
    139 
    140 	opterr = 0;
    141 
    142 	while ((c = getopt(argc, argv, "d:nvbh")) != -1 )
    143 		switch (c) {
    144 		case 'v':
    145 			die(VERSION);
    146 		case 'h':
    147 			help(argv[0]);
    148 		case 'd':
    149 			d=1;
    150 			strncpy(del, optarg, 10);
    151 			break;
    152 		case 'n':
    153 			n=1;
    154 			break;
    155 		case 'b':
    156 			b=1;
    157 			break;
    158 		case '?':
    159 			exit(EXIT_FAILURE);
    160 			break;
    161 		}
    162 
    163 	if (optind < argc) {
    164 		strncpy(filename, argv[optind], 256);
    165 		filename_given = 1;
    166 	}
    167 
    168 	FILE *f2, *f3;
    169 	if (filename_given == 0) {
    170 		f2 = save_stdin(stdin);
    171 		rewind(f2);
    172 		f3 = save_stdin(f2);
    173 	} else {
    174 		f2 = fopen(filename, "r");
    175 		f3 = fopen(filename, "r");
    176 		if (!f2) {
    177 			fprintf(stderr, "File could not be opened: %s\n",
    178 			filename);
    179 			exit(EXIT_FAILURE);
    180 		}
    181 	}
    182 
    183 	rewind(f2);
    184 	print_only(f2);
    185 	rewind(f2);
    186 	rewind(f3);
    187 
    188 	com(f2, f3, ' ', n, b);
    189 
    190 	for (int i = 0; i < strlen(del); i++) {
    191 		rewind(f2);
    192 		rewind(f3);
    193 		com(f2, f3, del[i], n, b);
    194 	}
    195 
    196 	fclose(f2);
    197 	fclose(f3);
    198 
    199 	exit(EXIT_SUCCESS);
    200 }