The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

subst.c

Go to the documentation of this file.
00001 #include <stddef.h>
00002 #include "jam.h"
00003 #include "regexp.h"
00004 #include "hash.h"
00005 
00006 #include "newstr.h"
00007 #include "lists.h"
00008 #include "parse.h"
00009 #include "compile.h"
00010 #include "frames.h"
00011 
00012 struct regex_entry
00013 {
00014     const char* pattern;
00015     regexp* regex;
00016 };
00017 typedef struct regex_entry regex_entry;
00018 
00019 static struct hash* regex_hash;
00020 
00021 regexp* regex_compile( const char* pattern )
00022 {
00023     regex_entry entry, *e = &entry;
00024     entry.pattern = pattern;
00025     
00026     if ( !regex_hash )
00027         regex_hash = hashinit(sizeof(regex_entry), "regex");
00028         
00029     if ( hashenter( regex_hash, (HASHDATA **)&e ) )
00030         e->regex = regcomp( (char*)pattern );
00031     
00032     return e->regex;
00033 }
00034 
00035 LIST*
00036 builtin_subst(
00037     PARSE    *parse,
00038     FRAME      *frame )
00039 {        
00040   LIST* result = L0;
00041   LIST* arg1 = lol_get( frame->args, 0 );
00042 
00043   if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) )
00044   {    
00045   
00046       const char* source = arg1->string;
00047       const char* pattern = list_next(arg1)->string;
00048       regexp* repat = regex_compile( pattern );
00049 
00050       if ( regexec( repat, (char*)source) )
00051       {
00052           LIST* subst = list_next(arg1);
00053           
00054           while ((subst = list_next(subst)) != L0)
00055           {
00056 # define BUFLEN 4096
00057               char buf[BUFLEN + 1];
00058               const char* in = subst->string;
00059               char* out = buf;
00060 
00061               for ( in = subst->string; *in && out < buf + BUFLEN; ++in )
00062               {
00063                   if ( *in == '\\' || *in == '$' )
00064                   {
00065                       ++in;
00066                       if ( *in == 0 )
00067                       {
00068                           break;
00069                       }
00070                       else if ( *in >= '0' && *in <= '9' )
00071                       {
00072                           unsigned n = *in - '0';
00073                           const size_t srclen = repat->endp[n] - repat->startp[n];
00074                           const size_t remaining = buf + BUFLEN - out;
00075                           const size_t len = srclen < remaining ? srclen : remaining;
00076                           memcpy( out, repat->startp[n], len );
00077                           out += len;
00078                           continue;
00079                       }
00080                       /* fall through and copy the next character */
00081                   }
00082                   *out++ = *in;
00083               }
00084               *out = 0;
00085 
00086               result = list_new( result, newstr( buf ) );
00087 #undef BUFLEN
00088           }
00089       }
00090   }
00091   
00092   return result;
00093 }
00094 

Generated on Mon Nov 8 17:07:52 2004 for MPT by  doxygen 1.3.9.1