Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

substitute.c

Go to the documentation of this file.
00001 #include "lexer.h"
00002 #include "substitute.h"
00003 #include <stdlib.h>
00004 
00005 /*
00006  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
00007  *      For copying and distribution information, see the file
00008  *      "mit-copyright.h".
00009  *
00010  *      Modified for jwgc by Daniel Henninger.
00011  */
00012 
00013 #include "mit-copyright.h"
00014 
00015 /*
00016  *  Internal Routine:
00017  *
00018  *    string eat_dollar_sign_stuff(string (*lookup)(string); string *text_ptr)
00019  *        Modifies: *text_ptr
00020  *        Effects: This routine deals with handling the stuff after a '$'
00021  *                 for substitute.  If *text_ptr starts with a valid
00022  *                 variable reference (minus the leading '$'), we look up
00023  *                 the variable using lookup and return its value.
00024  *                 *text_ptr is also advanced past the variable reference.
00025  *                 If a '$' starts *text_ptr, *text_ptr is advanced past it &
00026  *                 "$" returned.  (This handles "$$" -> "$")  Otherwise,
00027  *                 "$" is returned and *text_ptr is not advanced.
00028  *                 The returned string must not be freed.
00029  */
00030 
00031 static string 
00032 eat_dollar_sign_stuff(lookup, text_ptr)
00033 string(*lookup) ();
00034         string *text_ptr;       /* Input/Output parameter */
00035 {
00036         char c;
00037         char closing_brace = 0;
00038         char *p = *text_ptr;
00039         char *variable_name_start;
00040         int variable_name_length;
00041 
00042         /*
00043          * Handle "$$" -> "$" translation:
00044          */
00045         c = *p;
00046         if (c == '$') {
00047                 *text_ptr = p + 1;
00048                 return ("$");
00049         }
00050 
00051         /*
00052          * If opening brace present (i.e., '(' or '{'), skip it and save away
00053          * what closing brace we must see at the end of the variable reference:
00054          */
00055         if (c == '{') {
00056                 closing_brace = '}';
00057                 c = *++p;
00058         }
00059         else if (c == '(') {
00060                 closing_brace = ')';
00061                 c = *++p;
00062         }
00063 
00064         /*
00065          * Eat {identifier_char}* keeping track of what we ate:
00066          */
00067         variable_name_start = p;
00068         variable_name_length = 0;
00069         while (c = *p, is_identifier_char(c)) {
00070                 p++;
00071                 variable_name_length++;
00072         }
00073 
00074         /*
00075          * If there was an opening brace, there had better be a comparable
00076          * closing brace.  If so, skip it.  If not, we have an invalid variable
00077          * reference so return '$' without advancing *text_ptr.
00078          */
00079         if (closing_brace) {
00080                 if (c == closing_brace)
00081                         c = *++p;
00082                 else
00083                         return ("$");
00084         }
00085 
00086         /*
00087          * Zero length variable names are not valid:
00088          */
00089         if (!variable_name_length)
00090                 return ("$");
00091 
00092         /*
00093          * We have a valid variable reference.  Advance past it then lookup
00094          * its value and return it:
00095          */
00096         *text_ptr = p;
00097         if (variable_name_length > MAX_IDENTIFIER_LENGTH)
00098                 variable_name_length = MAX_IDENTIFIER_LENGTH;
00099         variable_name_start = string_CreateFromData(variable_name_start,
00100                                                     variable_name_length);
00101         p = lookup(variable_name_start);
00102         free(variable_name_start);
00103         return (p);
00104 }
00105 
00106 /*
00107  *    string substitute(string (*lookup)(string); string text)
00108  *        Effects: returns the result of expanding all variable
00109  *                 references in text using lookup.  Example:
00110  *                 "test $foo.$bar baz" would be translated to
00111  *                 "text <foo>.<bar> baz" where "<foo>" is the value of
00112  *                 lookup("foo") and "<bar>" is the value of lookup("bar").
00113  *                 Variables are case sensitive and have the form
00114  *                 {identifier_char}+ where identifier_char is defined
00115  *                 in lexer.h by is_identifier_char.  $(foo) and
00116  *                 ${foo} are alternate forms for $foo.  In particular,
00117  *                 ${foo}bar is a reference to foo followed by "bar" while
00118  *                 $foobar is a reference to foobar.  Incomplete variable
00119  *                 references like $(foo bar are displayed as if they
00120  *                 were not variable references.  To allow quoting, "$$"
00121  *                 is translated to "$".  Only the first
00122  *                 MAX_IDENTIFIER_LENGTH characters of an identifier are
00123  *                 significant.  The strings returned by lookup are not
00124  *                 modified in any way or freed.
00125  */
00126 
00127 string 
00128 substitute(lookup, text)
00129 string(*lookup) ();
00130         string text;
00131 {
00132         string result_so_far = string_Copy("");
00133         char *p, *temp;
00134 
00135         for (;;) {
00136                 /*
00137                  * Move [^$]* from start of text to end of result_so_far:
00138                  */
00139                 for (p = text; *p && (*p) != '$'; p++);
00140                 if (text != p) {
00141                         temp = string_CreateFromData(text, p - text);
00142                         text = p;
00143                         result_so_far = string_Concat2(result_so_far, temp);
00144                         free(temp);
00145                 }
00146 
00147                 /*
00148                  * If text now empty, exit -- the result is in result_so_far:
00149                  */
00150                 if (!*text)
00151                         return (result_so_far);
00152 
00153                 /*
00154                  * Otherwise, text begins with a '$'.  Eat it then call
00155                  * eat_dollar_sign_stuff to process stuff after it.
00156                  * Append result to result_so_far, update text, & continue.
00157                  */
00158                 text++;
00159                 p = eat_dollar_sign_stuff(lookup, &text);
00160                 result_so_far = string_Concat2(result_so_far, p);
00161         }
00162 }


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye