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 }