/* Copyright (C) 2006 Stephen Jungels This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Stephen Jungels. */ #include #include static void usage(); static void version(); static void process_line(char *); /* the name this program was called by */ char *me; /* set for non-fatal error */ static int exitstatus; /* An array of file handles */ FILE *inputfile, **inputfiles; size_t ninputs; size_t inputindex; /* Expandable argument list */ char **myargv; size_t myargc; size_t nargs; /* skip hints array */ char **skiphints; size_t nskiphints; size_t skipindex; /* play hints array */ char **playhints; size_t nplayhints; size_t playindex; /* the tty */ FILE *tty_in, *tty_out; /* todo: make some of these static local */ #define BUFLEN 512 char all[2]; /* this choice applies to all remaining lines */ char prefix[BUFLEN]; /* remove this prefix from each line */ char search[BUFLEN]; /* a search string */ char savesearch[BUFLEN]; /* the last search, if any */ char levelsep[BUFLEN]; /* the separator character for levels in the hierarchy */ char verb[BUFLEN]; /* the action word preceding each line */ int state; /* 0 means init state of process_line */ int levelindex; /* level in the (directory?) hierarchy */ /* insert an argument into the expandable argument list */ int insert_arg (char *arg, size_t index) { int i; if (index > myargc) return (-1); myargc++; if (myargc > nargs) { myargv = realloc (myargv, 2 * nargs * sizeof *myargv); nargs *= 2; } for (i = index; i < myargc; i++) { char *temp; temp = myargv[i]; myargv[i] = arg; arg = temp; } return (myargc); } int main (int argc, char **argv) { char line[BUFLEN]; me = argv[0]; exitstatus = 0; ninputs=10; inputindex=0; inputfiles = malloc (ninputs * sizeof *inputfiles); strcpy(prefix, ""); strcpy(levelsep, "/"); strcpy(verb, "Include"); /* copy arguments to expandable list */ nargs = 20; myargc = 0; myargv = malloc (nargs * sizeof *myargv); int i; for (i = 0; i < argc; i++) insert_arg (argv[i], myargc); i=1; while (i 2) { /* blindly expand grouped options to individual options */ int j = i + 1; int k = 1; while (k < strlen (myargv[i])) { int c = *(myargv[i]+k); char *arg = malloc (3 * sizeof *arg); *(arg) = '-'; *(arg+1) = c; *(arg+2) = '\0'; insert_arg (arg, j); /*dump_myargs();*/ j++; k++; } } else /* anything else is taken as a file */ { inputfile = fopen (myargv[i], "r"); if (inputfile==NULL) { fprintf (stderr, "interactive: could not open file %s for reading\n", myargv[i]); exit (1); } else { if (inputindex == ninputs) { inputfiles = realloc (inputfiles, 2 * ninputs * sizeof *inputfiles); ninputs *= 2; } inputfiles[inputindex++] = inputfile; } } i++; } if (inputindex == 0) { inputfiles[inputindex++] = stdin; } skipindex = 0; playindex = 0; strcpy(all, ""); strcpy(search, ""); strcpy(savesearch, ""); state = 0; levelindex = 0; nskiphints=10; skipindex=0; skiphints = malloc (nskiphints * sizeof *skiphints); nplayhints=10; playindex=0; playhints = malloc (nplayhints * sizeof *playhints); tty_in = fopen ("/dev/tty", "r"); if (tty_in==NULL) { fprintf (stderr, "interactive: could not open file /dev/tty for reading\n"); exit (1); } tty_out = fopen ("/dev/tty", "w"); if (tty_out==NULL) { fprintf (stderr, "interactive: could not open file /dev/tty for writing\n"); exit (1); } for (i=0; i len)) { strcpy(action, "n"); len = strlen(skiphints[i]); } } for (i=0; i len)) { strcpy(action, "y"); break; } } if ((strcmp(action, "") == 0) && (strcmp(all, "") != 0)) { strcpy(action, all); } if ((strcmp(action, "") == 0) && (strcmp(search, "") != 0)) { // should use tolower here if (strstr(line, search) != NULL) { strcpy(search, ""); } else { strcpy(action, "n"); } } if (strcmp(action, "y") == 0) { printf("%s\n", line); } // if hints and "all" gave no instruction, ask the user else if (strcmp(action, "") == 0) { levels = 0; strncpy(line2, line, BUFLEN); line2[BUFLEN-1] = '\0'; line3 = line2; // fprintf (tty_out, "Still alive...\n"); // remove prefix, if found if (strncmp(line2, prefix, strlen(prefix)) == 0) { line3 = line3 + strlen(prefix); } // split the line if ((briefparts[0] = strtok(line3, levelsep)) != NULL) { levels = 1; while (levels < 256) { if ((briefparts[levels] = strtok(NULL, levelsep))==NULL) break; else levels++; } } // fprintf (tty_out, "Still alive 2...\n"); // bounds check levelindex if (levels + levelindex < 1) { levelindex = 1 - levels; } if (levels == 0) { levelindex = 0; } // loop while moving up and down in the hierarchy int cont = 1; while (cont==1) { char sep[BUFLEN]; cont = 0; strcpy (str, ""); strcpy (sep, ""); for (i=0; i 0) { levelindex = 0; } } } // finished moving up and down, so check for other responses if (strcmp(response, "Y")==0 || strcmp(response, "Yes")==0) { strcpy(response, "y"); strcpy(all, "y"); } else if (strcmp(response, "N")==0 || strcmp(response, "No")==0) { strcpy(response, "n"); strcpy(all, "n"); } else if (strncmp(response, "/", 1)==0) { char *s2 = response; s2++; strncpy(search, s2, BUFLEN); search[BUFLEN-1] = '\0'; if (strlen(search) == 0) { strcpy(search, savesearch); } if (strlen(search) == 0) { fprintf(tty_out, "Search string: "); fgets(search, BUFLEN, tty_in); search[strlen(search)-1] = '\0'; } strcpy(savesearch, search); strcpy(response, "n"); } if (strcmp(response, "y")==0 || strcmp(response, "yes")==0 || strlen(response)==0) { printf ("%s\n", line); if (levelindex < 0) { // playhints if (playindex == nplayhints) { playhints = realloc (2 * nplayhints * sizeof *playhints); nplayhints *= 2; } playhints[playindex] = malloc((strlen(str) + 1) * sizeof *str); strcpy(playhints[playindex], str); playindex++; } } else if (strcmp(response, "n")==0 || strcmp(response, "no")==0 ) { if (levelindex < 0) { // skiphints if (skipindex == nskiphints) { skiphints = realloc (2 * nskiphints * sizeof *skiphints); nskiphints *= 2; } skiphints[skipindex] = malloc((strlen(str) + 1) * sizeof *str); strcpy(skiphints[skipindex], str); skipindex++; } } } } void usage () { printf ("Usage: %s [OPTION]... [FILE]...\n", me); fputs ("Processes a list interactively.\n", stdout); fputs ("Options:\n", stdout); fputs (" --prefix=, -p : set prefix to remove from each line\n", stdout); fputs (" --levelsep=, -l: set level separator\n", stdout); fputs (" --action=, -a : set descriptive verb\n", stdout); fputs (" --help, -h : show help\n", stdout); fputs (" --version, -v : show version information", stdout); } void version() { fputs ("\ interactive 1.0\n\ \n\ Copyright (C) 2006 Stephen Jungels\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", stdout); }