home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * GetRefs.c
- * ( if it looks yucky, set tabstops to 4 )
- *
- * Program to extract a section of a file. Primarily for use with the
- * AREXX referencing macro and TxEd Plus, it can also be used as a
- * standalone program.
- *
- * The program takes 1 command line argument. If any other number
- * is supplied, the program will exit with an error. The argument is
- * an ascii string that should match one of the entries in the reference
- * file.
- * The program writes the extracted text to the file ram:extract.txt
- *
- * Programmed by John G. Hardie
- * This program is in the public domain, do with it what you will.
- *
- * Compiled under Lattice C v4.0 ( lc -v -b -r getrefs )
- * and Blink 7.2 (blink with lc.lib, amiga.lib, SD SC ND)
- **************************************************************************/
- #include "libraries/dosextens.h"
- #include "stdio.h"
- #include "string.h"
- #include "ctype.h"
-
- /* Prototypes */
- int stringcmp(char *,char *,int *);
- void scopynull(char *,char *);
-
- struct Process *HereWeAre;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- FILE *infile,*outfile;
- char line[256],searchstr[256],*str,found=0,inch,*sarg[5];
- int leng,locate;
-
- HereWeAre = (struct Process *)FindTask(0);
-
- if (argc != 2)
- {
- puts("Bad command line - you must supply 1 parameter");
- seterror(50);
- Exit(20); /* bad command line - go away */
- }
-
- /* we search for the reference file in df1:s df0:s and ram:s */
- /* before we give up and go away */
- if (!(infile = fopen("df1:s/txed.refs","r")))
- if (!(infile = fopen("df0:s/txed.refs","r")))
- if (!(infile = fopen("ram:s/txed.refs","r")))
- {
- puts("Error - couldn't open input file");
- seterror(51);
- Exit(20); /* Huh? where the hell is it? */
- }
-
- /* Try to find the keyword string in the file. */
- leng = strlen(argv[1]);
- while (str = fgets(line,256,infile))
- {
- if (stringcmp(str,argv[1],&locate) == leng)
- {
- /* we want an exact match, no partials e.g */
- /* Open and OpenLibrary don't match in this case */
- if (isspace(*(str+locate+leng)))
- {
- found++;
- break;
- }
- }
- }
-
- /* Did we find the string or run out of input file? */
- if (!found)
- {
- puts("Reference String Not Found");
- fclose(infile);
- seterror(52);
- Exit(20); /* nope, didn't find it <sigh> */
- }
-
- /* get the start, stop, and filename from the input line */
- scopynull(line,searchstr);
- if ((leng = strbpl(sarg,6,searchstr)) != 4)
- {
- puts("Bad Line format in ref file");
- fclose(infile);
- seterror(53);
- Exit(20);
- }
- fclose(infile);
-
- /* Open the search file and commence much looking about */
- if (!(infile = fopen(sarg[2],"r")))
- {
- puts("Error - couldn't open input file");
- seterror(54);
- Exit(20); /* Huh? where the hell is it? */
- }
-
- /* Try to find the start string in the file. */
- leng = strlen(sarg[3]);
- while (fgets(line,256,infile))
- {
- if (stringcmp(line,sarg[3],&locate) == leng)
- {
- found++;
- break;
- }
- }
-
- /* Did we find the string or run out of input file? */
- if (!found)
- {
- puts("Could not find referenced text");
- fclose(infile);
- seterror(55);
- Exit(20); /* Ah well, can't have everything (anything?) */
- }
-
- /* Ok, we found it, now try to open the output file */
- if (!(outfile = fopen("ram:extract.txt","w")))
- {
- puts("Error - Couldn't open the output file");
- fclose(infile);
- seterror(56);
- Exit(20); /* bad news - something is seriously broke */
- }
-
- /* Write the matching line to the output file, and commence copying */
- fputs(line,outfile);
- found = 0;
-
- /* if stop string is a ^L must read char by char mainly because */
- /* I was too lazy to figure out a more efficient way to do it. */
- if (!stricmp(sarg[1],"^L"))
- {
- while ((inch = fgetc(infile)) != EOF)
- {
- if (inch == 0xC)
- {
- found++;
- break;
- }
- fputc(inch,outfile); /* we don't want to write the ^L */
- } /* it makes reading difficult */
- }
- else /* otherwise read a line at a time */
- {
- leng = strlen(sarg[1]);
- while (!found)
- {
- if (!(str = fgets(line,256,infile)))
- break;
- if (stringcmp(str,sarg[1],&locate) == leng)
- found++;
- fputs(line,outfile);
- }
- }
-
- /* we are (hopefully) done - either EOF or matched, go away anyway */
- fclose(infile);
- fclose(outfile);
- return(0); /* keep AREXX happy */
- }
-
- /*** little bitty procedure to set the DOS return code if we have ***/
- /*** an error. If we just do an Exit(20) then ARexx doesn't know ***/
- /*** anything about the error. ***/
- int seterror(err)
- int err;
- {
- HereWeAre->pr_Result2 = err;
- return(0);
- }
-
- /***********************************************************************
- * stringcmp()
- *
- * Unanchored non-destructive string comparison. Written primarily
- * because I couldn't get the lattice pattern matching routines to
- * work, and didn't feel like taking the time to figure out what was
- * wrong.
- ***********************************************************************/
- int stringcmp(s,p,l)
- char *s,*p;
- int *l;
- {
- int len1,len2,i;
-
- len1 = strlen(s);
- len2 = strlen(p);
-
- /* this can't possibly match so give up immediately */
- if (len1 < len2)
- return(0);
-
- /* no need to go all the way to the end, just stop when target */
- /* can't fit in the remainder of the source */
- for (i=0;i<len1-len2;i++)
- {
- if (!strncmp(s,p,len2)) /* I cheated a bit with this call */
- {
- *l = i; /* want to know where in source we matched */
- return(len2);
- }
- s++;
- }
- *l = len1;
- return(0); /* no match, sorry */
- }
-
-
- /**********************************************************************
- * scopynull
- *
- * This routine copies the first string to the second, skipping
- * whitespace, except if it is enclosed in quotes
- * the procedure also places a null after each string section
- * (a string section is a contiguous group of printable ascii chars
- * or several groups and whitespace inside quotes)
- * and adds a null to the end of the resultant string (so that it ends
- * with 2 nulls). This is meant to be used primarily with the
- * Lattice function strbpl() which requires a string of this form
- * as input.
- **********************************************************************/
- void scopynull(s1,s2)
- char *s1,*s2;
- {
- int inquote=0,copying=0;
-
- while (*s1)
- {
- if (*s1 == '\"') /* is it a quote? yes -> just copy it */
- {
- s1++;
- inquote = 1 - inquote;
- }
- if (inquote) /* just copy it, like I said */
- {
- copying = 1;
- *s2++ = *s1;
- }
- else
- {
- if (isspace(*s1) || (*s1 == '\n')) /* whitespace or newline? */
- {
- if (copying) /* if we are in a string section, then */
- { /* we found the end of it, so put a NULL */
- *s2++ = 0; /* otherwise, just skip it */
- copying = 0;
- }
- }
- else
- {
- copying = 1; /* just copy the stupid thing already */
- *s2++ = *s1;
- }
- }
- s1++;
- }
- *s2 = 0;
- }
-