// crm_file_io.c - Controllable Regex Mutilator, version v1.0 // Copyright 2001-2004 William S. Yerazunis, all rights reserved. // // This software is licensed to the public under the Free Software // Foundation's GNU GPL, version 2. You may obtain a copy of the // GPL by visiting the Free Software Foundations web site at // www.fsf.org, and a copy is included in this distribution. // // Other licenses may be negotiated; contact the // author for details. // // include some standard files #include "crm114_sysincludes.h" // include any local crm114 configuration file #include "crm114_config.h" // include the crm114 data structures file #include "crm114_structs.h" // and include the routine declarations file #include "crm114.h" // the command line argc, argv extern int prog_argc; extern char **prog_argv; // the auxilliary input buffer (for WINDOW input) extern char *newinputbuf; // the globals used when we need a big buffer - allocated once, used // wherever needed. These are sized to the same size as the data window. extern char *inbuf; extern char *outbuf; extern char *tempbuf; int crm_expr_input ( CSL_CELL *csl, ARGPARSE_BLOCK *apb ) { // Allow input of text from stdin. FILE *fp; char temp_vars [MAX_PATTERN]; long tvlen; char filename [MAX_FILE_NAME_LEN]; long fnlen; char ifn [MAX_FILE_NAME_LEN]; char fileoffset [MAX_FILE_NAME_LEN]; long fileoffsetlen; char fileiolen [MAX_FILE_NAME_LEN]; long fileiolenlen; long offset, iolen; long vstart; long vlen; long mc; long done; long till_eof; // a couple of vars to bash upon long i, j; if (user_trace) fprintf (stderr, "executing an INPUT statement\n"); // set up the flags (if any) // till_eof = 1; if (apb->sflags & CRM_BYLINE) { till_eof = 0; if (user_trace) fprintf (stderr, " reading one line mode\n "); }; // get the list of variable names // crm_get_pgm_arg (temp_vars, MAX_PATTERN, apb->p1start, apb->p1len); tvlen = crm_nexpandvar (temp_vars, apb->p1len, MAX_PATTERN); // If you think INPUT should read to the data window, uncomment this. // //if (tvlen == 0) // { // strcpy (temp_vars, ":_dw:"); // tvlen = strlen (":_dw:"); // }; if (internal_trace) fprintf (stderr, " inputting to var: >>>%s<<<\n", temp_vars); // and what file to get it from... // crm_get_pgm_arg (filename, MAX_FILE_NAME_LEN, apb->b1start,apb->b1len); crm_nextword (filename, apb->b1len, 0, &i, &j); memmove (ifn, &filename[i], j); fnlen = crm_nexpandvar (ifn, j, MAX_FILE_NAME_LEN); ifn[fnlen] = '\0'; if (user_trace) fprintf (stderr, " from filename >>>%s<<<\n", ifn); // and what offset we need to do before the I/O... // offset = 0; crm_nextword (filename, apb->b1len, i+j, &i, &j); memmove (fileoffset, &filename[i], j); fileoffsetlen = crm_qexpandvar (fileoffset, j, MAX_FILE_NAME_LEN, NULL); fileoffset [fileoffsetlen] = '\0'; sscanf (fileoffset, "%ld", &offset); if (user_trace) fprintf (stderr, " pre-IO seek to >>>%s<<< --> %ld \n", fileoffset, offset); // and how many bytes to read // iolen = 0; crm_nextword (filename, apb->b1len, i+j, &i, &j); memmove (fileiolen, &filename[i], j); fileiolenlen = crm_qexpandvar (fileiolen, j, MAX_FILE_NAME_LEN, NULL); fileiolen [fileiolenlen] = '\0'; sscanf (fileiolen, "%ld", &iolen); if (iolen == 0) iolen = data_window_size; if (user_trace) fprintf (stderr, " and maximum length IO of >>>%s<<< --> %ld\n", fileiolen, iolen); fp = stdin; if ( fnlen > 0) { fp = fopen (ifn, "r"); if (fp == NULL) { fatalerror ("For some reason, I was unable to read-open the file named ", filename); goto input_no_open_bailout; }; }; done = 0; mc = 0; // get the variable name crm_nextword( temp_vars, tvlen, 0, &vstart, &vlen); if (vlen == 0) { done = 1; } else { // must make a copy of the varname. // char vname[MAX_VARNAME]; long ichar; memmove (vname, &(temp_vars[vstart]), vlen); vname [vlen] = '\000'; // If we have a seek requested, do an fseek // fseek (fp, offset, SEEK_SET); // and grab a line from fp // grab characters in a loop, terminated by EOF or newline ichar = 0; if (feof (fp) ) clearerr (fp); while (!feof (fp) && ichar < (data_window_size >> SYSCALL_WINDOW_RATIO) && ( till_eof || ( ichar == 0 || inbuf [ichar-1] != '\n')) && ichar <= iolen ) { inbuf[ichar] = fgetc (fp); ichar++; }; if (ichar > 0) ichar-- ; // get rid of the newline - if there was one. inbuf[ichar] = '\000'; // and put a null on the end of it. crm_set_temp_nvar (vname, inbuf, ichar); }; // and close the input file if it's not stdin. if (fp != stdin) fclose (fp); input_no_open_bailout: return (0); }; ////////////////////////////////////////// // // And here's where we do output int crm_expr_output ( CSL_CELL *csl, ARGPARSE_BLOCK *apb) { long i, j; // output a string, usually to stdout unless otherwise // specified in the output statement. // // We do variable substitutions here.... // char outfile[MAX_VARNAME]; //long outfilelen; //char ofn[MAX_VARNAME]; long outtextlen; FILE *outf; char filename [MAX_FILE_NAME_LEN]; char fnam [MAX_FILE_NAME_LEN]; long fnlen; char fileoffset [MAX_FILE_NAME_LEN]; long fileoffsetlen; char fileiolen [MAX_FILE_NAME_LEN]; long fileiolenlen; long offset, iolen; if (user_trace) fprintf (stderr," Executing an OUTPUT statement\n"); // get the output file name // // crm_get_pgm_arg (outfile, MAX_FILE_NAME_LEN, apb->b1start,apb->b1len); //crm_nextword (outfile, apb->b1len, 0, &i, &j); //memmove (ofn, &outfile[i], j); //outfilelen = crm_nexpandvar (ofn, j, MAX_FILE_NAME_LEN); //ofn[outfilelen] = '\0'; //if (internal_trace) // fprintf (stderr, " to filename >>>%s<<<\n", ofn); // What file name? // crm_get_pgm_arg (filename, MAX_FILE_NAME_LEN, apb->b1start,apb->b1len); crm_nextword (filename, apb->b1len, 0, &i, &j); memmove (fnam, &filename[i], j); fnlen = crm_nexpandvar (fnam, j, MAX_FILE_NAME_LEN); fnam[fnlen] = '\0'; if (user_trace) fprintf (stderr, " filename >>>%s<<<\n", fnam); // and what offset we need to do before the I/O... // offset = 0; crm_nextword (filename, apb->b1len, i+j, &i, &j); memmove (fileoffset, &filename[i], j); fileoffsetlen = crm_qexpandvar (fileoffset, j, MAX_FILE_NAME_LEN, NULL); fileoffset [fileoffsetlen] = '\0'; sscanf (fileoffset, "%ld", &offset); if (user_trace) fprintf (stderr, " pre-IO seek to >>>%s<<< --> %ld \n", fileoffset, offset); // and how many bytes to read // iolen = 0; crm_nextword (filename, apb->b1len, i+j, &i, &j); memmove (fileiolen, &filename[i], j); fileiolenlen = crm_qexpandvar (fileiolen, j, MAX_FILE_NAME_LEN, NULL); fileiolen [fileiolenlen] = '\0'; sscanf (fileiolen, "%ld", &iolen); if (iolen == 0) iolen = data_window_size; if (user_trace) fprintf (stderr, " and maximum length IO of >>>%s<<< --> %ld\n", fileiolen, iolen); outf = stdout; if ( fnlen > 0) { if (user_trace) fprintf (stderr, "Outputting to file %s\n", fnam); if (strcmp(fnam,"stderr")==0) { outf = stderr; } else if (strcmp(fnam,"stdout")!=0) { if (apb->sflags & CRM_APPEND || fileoffsetlen > 0 ) { outf = fopen (fnam, "r+"); // // If the file didn't exist already, that open would fail. // so we retry with "w+". if (!outf) outf = fopen (fnam, "w+"); // // And make sure the file pointer is at EOF. if ( outf != 0 ) fseek (outf, 0, SEEK_END); } else { outf = fopen (fnam, "w"); }; }; }; // // could we open the file? // if ( outf == 0 ) { fatalerror ("For some reason, I was unable to write-open the file named", fnam); } else { // Yep, file is open, go for the writing. // crm_get_pgm_arg (outbuf, data_window_size, apb->s1start, apb->s1len); outtextlen = apb->s1len; if (internal_trace) fprintf (stderr, " outputting with pattern %s\n", outbuf); // Do variable substitution on outbuf. outtextlen = crm_nexpandvar (outbuf, outtextlen, data_window_size); // Do the seek if necessary // if ( fileoffsetlen > 0) { // fprintf (stderr, "SEEKING to %ld\n", offset); rewind (outf); fseek (outf, offset, SEEK_SET); }; // Write at most iolen bytes // if (fileiolen > 0) if (iolen < outtextlen) outtextlen = iolen; // and send it to outf // fwrite (outbuf, outtextlen, 1, outf); fflush (outf); if (outf != stdout && outf != stderr ) fclose (outf); }; return (0); }