// crm_expr_translate.c - Controllable Regex Mutilator, version v1.0
// Copyright 2001-2006 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;
// And the translate routine. We use strntrn to do the hard work;
// this code here is just glue code.
//
int crm_expr_translate (CSL_CELL *csl, ARGPARSE_BLOCK *apb)
{
long strntrn_flags;
char destination[MAX_VARNAME];
long destination_len, dst_nstart;
// for source, we use tempbuf
long vmidx;
char *mdwptr;
long offset;
long len, retlen;
char errstr[MAX_PATTERN];
long i;
// the "from" charset
char fromset[MAX_PATTERN];
long fromset_len;
// the "to" charset
char toset[MAX_PATTERN];
long toset_len;
//
strntrn_flags = 0;
// Go through the flags
//
// UNIQUE flag set?
//
if (apb->sflags & CRM_UNIQUE)
{
if (user_trace)
fprintf (stderr, " uniquing flag turned on...\n");
strntrn_flags = strntrn_flags | CRM_UNIQUE;
};
//
// How about the LITERAL flag
if (apb->sflags & CRM_LITERAL)
{
if (user_trace)
fprintf (stderr, " literal (no invert or ranges) turned on...\n");
strntrn_flags = strntrn_flags | CRM_LITERAL ;
};
// Get the destination for the translation
//
crm_get_pgm_arg (destination, MAX_VARNAME, apb->p1start, apb->p1len);
destination_len = crm_nexpandvar (destination, apb->p1len, MAX_VARNAME);
//if (destination_len == 0)
// {
// strcpy (destination, ":_dw:");
// destination_len = 5;
// };
if (internal_trace)
fprintf (stderr, " destination: ***%s*** len=%ld\n",
destination, destination_len);
crm_nextword (destination, destination_len, 0, &dst_nstart,
&destination_len);
if (destination_len < 3)
{
strcpy (destination, ":_dw:");
destination_len = 5;
}
// here's where we look for a [] var-restriction source
//
// Experimentally, we're adding [ :foo: 123 456 ] to
// allow an externally specified start and length.
crm_get_pgm_arg (tempbuf, data_window_size, apb->b1start, apb->b1len);
// Use crm_restrictvar to get start & length to look at.
i = crm_restrictvar(tempbuf, apb->b1len,
&vmidx,
&mdwptr,
&offset,
&len,
errstr);
if (internal_trace)
fprintf (stderr,
"restriction out: vmidx: %ld mdw: %ld start: %ld len: %ld\n",
vmidx, (long) mdwptr, offset, len);
if ( i < 0)
{
long curstmt;
curstmt = csl->cstmt;
if (i == -1)
nonfatalerror (errstr, "");
if (i == -2)
fatalerror (errstr, "");
//
// did the FAULT handler change the next statement to execute?
// If so, continue from there, otherwise, we FAIL.
if (curstmt == csl->cstmt)
{
csl->cstmt = csl->mct[csl->cstmt]->fail_index - 1;
csl->aliusstk [ csl->mct[csl->cstmt]->nest_level ] = -1;
};
goto nonfatal_route_outwards;
};
// No problems then. We can just memmove the result into tempbuf
memmove (tempbuf, &mdwptr[offset], len);
// get the FROM charset out of the first // slashes
crm_get_pgm_arg (fromset, MAX_PATTERN, apb->s1start, apb->s1len);
if (internal_trace)
fprintf (stderr, " FROM-charset: =%s=\n", fromset );
// if not LITERAL, then expand them as well
fromset_len = apb->s1len;
if ( ! (strntrn_flags & CRM_LITERAL))
fromset_len = crm_nexpandvar (fromset, apb->s1len, MAX_PATTERN);
if (user_trace)
fprintf (stderr, " from-charset expands to =%s= len %ld \n",
fromset, fromset_len);
// get the TO charset out of the second // slashes
crm_get_pgm_arg (toset, MAX_PATTERN, apb->s2start, apb->s2len);
if (internal_trace)
fprintf (stderr, " TO-charset: =%s=\n", toset );
// if not LITERAL, then expand them as well
toset_len = apb->s2len;
if ( ! (strntrn_flags & CRM_LITERAL))
toset_len = crm_nexpandvar (toset, apb->s2len, MAX_PATTERN);
if (user_trace)
fprintf (stderr, " to-charset expands to =%s= len %ld\n",
toset, toset_len);
// We have it all now - the [expanded] input in tempbuf, the
// from-charset, the to-charset, and the flags. We can now
// make the big call to strntrn and get the new (in-place) string.
retlen = strntrn ((unsigned char *)tempbuf, &len, data_window_size,
(unsigned char *)fromset, fromset_len,
(unsigned char *)toset, toset_len,
strntrn_flags);
if (retlen < 0)
{
nonfatalerror ("Messy problem in TRANSLATE.",
"Try again with -t tracing maybe?");
goto nonfatal_route_outwards;
};
//
// OK, we have final result and a valid length. Now push that
// back into the destination.
//tempbuf[retlen] = '\0';
//if (user_trace)
// fprintf (stderr, "Result of TRANSLATE: %s len %ld\n",
// tempbuf, retlen);
if (user_trace)
{
long i;
fprintf (stderr, "Result of TRANSLATE: -");
for(i=0;i<retlen;i++) fputc(tempbuf[i],stderr);
fprintf (stderr, "- len %ld\n", retlen);
};
crm_destructive_alter_nvariable (destination, destination_len,
tempbuf, retlen);
// All done - return to caller.
//
if (0)
{
nonfatal_route_outwards:
if (user_trace)
fprintf (stderr, "The TRANSLATE FAULTed and we're taking the TRAP out");
};
return (0);
};
syntax highlighted by Code2HTML, v. 0.9.1