parser_bits.cpp

Go to the documentation of this file.
00001 #ifndef PARSER_BITS_IMPLEMENTATION_FILE
00002 #define PARSER_BITS_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : parser_bits                                                       *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "parser_bits.h"
00019 
00020 #include <basis/function.h>
00021 #include <basis/istring.h>
00022 #include <basis/log_base.h>
00023 #include <basis/portable.h>
00024 
00025 #include <ctype.h>
00026 
00027 #undef LOG
00028 #define LOG(s) STAMPED_EMERGENCY_LOG(program_wide_logger(), s)
00029 
00030 bool parser_bits::is_printable_ascii(char to_check)
00031 { return (to_check >= 32) && (to_check <= 126); }
00032 
00033 bool parser_bits::white_space_no_cr(char to_check)
00034 { return (to_check == ' ') || (to_check == '\t'); }
00035 
00036 bool parser_bits::is_eol(char to_check)
00037 { return (to_check == '\n') || (to_check == '\r'); }
00038 
00039 bool parser_bits::white_space(char to_check)
00040 { return white_space_no_cr(to_check) || is_eol(to_check); }
00041 
00042 void parser_bits::translate_CR_for_platform(istring &to_translate)
00043 {
00044   log_base::line_ending plat_eol = log_base::pick_ending_for_platform();
00045   bool last_was_lf = false;
00046   for (int i = 0; i <= to_translate.end(); i++) {
00047     if (to_translate[i] == '\r') {
00048       if (last_was_lf) continue;  // ignore two in a row.
00049       last_was_lf = true;
00050     } else if (to_translate[i] == '\n') {
00051       if (last_was_lf) {
00052         if (plat_eol != log_base::CRLF_AT_END) {
00053           // fix it, since there was not supposed to be an LF.
00054           to_translate.zap(i - 1, i - 1);
00055           i--;
00056         }
00057       } else {
00058         if (plat_eol == log_base::CRLF_AT_END) {
00059           // fix it, since we're missing an LF that we want.
00060           to_translate.insert(i, "\r");
00061           i++;
00062         }
00063       }
00064       last_was_lf = false;
00065     } else {
00066       // not the two power characters.
00067       last_was_lf = false;
00068     }
00069   }
00070 }
00071 
00072 bool parser_bits::is_hexadecimal(char look_at)
00073 {
00074   return range_check(look_at, 'a', 'f')
00075       || range_check(look_at, 'A', 'F')
00076       || range_check(look_at, '0', '9');
00077 }
00078 
00079 bool parser_bits::is_hexadecimal(const char *look_at, int len)
00080 {
00081   for (int i = 0; i < len; i++)
00082     if (!is_hexadecimal(look_at[i])) return false;
00083   return true;
00084 }
00085 
00086 bool parser_bits::is_hexadecimal(const istring &look_at, int len)
00087 { return is_hexadecimal(look_at.observe(), len); }
00088 
00089 bool parser_bits::is_alphanumeric(char look_at)
00090 {
00091   return range_check(look_at, 'a', 'z')
00092       || range_check(look_at, 'A', 'Z')
00093       || range_check(look_at, '0', '9');
00094 }
00095 
00096 bool parser_bits::is_alphanumeric(const char *look_at, int len)
00097 {
00098   for (int i = 0; i < len; i++)
00099     if (!is_alphanumeric(look_at[i])) return false;
00100   return true;
00101 }
00102 
00103 bool parser_bits::is_alphanumeric(const istring &look_at, int len)
00104 { return is_alphanumeric(look_at.observe(), len); }
00105 
00106 bool parser_bits::is_identifier(char look_at)
00107 {
00108   return range_check(look_at, 'a', 'z')
00109       || range_check(look_at, 'A', 'Z')
00110       || range_check(look_at, '0', '9')
00111       || (look_at == '_');
00112 }
00113 
00114 bool parser_bits::is_identifier(const char *look_at, int len)
00115 {
00116   if (is_numeric(look_at[0])) return false;
00117   for (int i = 0; i < len; i++)
00118     if (!is_identifier(look_at[i])) return false;
00119   return true;
00120 }
00121 
00122 bool parser_bits::is_identifier(const istring &look_at, int len)
00123 { return is_identifier(look_at.observe(), len); }
00124 
00125 bool parser_bits::is_numeric(char look_at)
00126 {
00127   return range_check(look_at, '0', '9') || (look_at == '-');
00128 }
00129 
00130 bool parser_bits::is_numeric(const char *look_at, int len)
00131 {
00132   for (int i = 0; i < len; i++) {
00133     if (!is_numeric(look_at[i])) return false;
00134     if ( (i > 0) && (look_at[i] == '-') ) return false;
00135   }
00136   return true;
00137 }
00138 
00139 bool parser_bits::is_numeric(const istring &look_at, int len)
00140 { return is_numeric(look_at.observe(), len); }
00141 
00142 istring parser_bits::substitute_env_vars(const istring &to_process,
00143     bool leave_unknown)
00144 {
00145   istring editing = to_process;
00146 
00147   int indy;  // index of the dollar sign in the string.
00148   while (true) {
00149     indy = editing.find('$');
00150     if (negative(indy)) break;  // all done.
00151     int q;
00152     for (q = indy + 1; q < editing.length(); q++) {
00153       if (!parser_bits::is_identifier(editing[q]))
00154         break;  // done getting variable name.
00155     }
00156     if (q != indy + 1) {
00157       // we caught something in our environment variable trap...
00158       istring var_name = editing.substring(indy + 1, q - 1);
00159 //LOG(istring("var name ") + var_name);
00160       istring value_found = portable::env_string(var_name);
00161 //LOG(istring("val found ") + value_found);
00162       if (value_found.t()) {
00163         editing.zap(indy, q - 1);
00164         editing.insert(indy, value_found);
00165       } else {
00166         if (leave_unknown) {
00167           // that lookup failed.  let's mark it.
00168           editing[indy] = '?';
00169             // simple replacement, shows variables that failed.
00170         } else {
00171           // replace it with blankness.
00172           editing.zap(indy, q - 1);
00173         }
00174       }
00175     } else {
00176       // well, we didn't see a valid variable name, but we don't want to leave
00177       // the dollar sign in there.
00178       editing[indy] = '!';  // simple replacement, marks where syntax is bad.
00179     }
00180 
00181   }
00182 
00183   return editing;
00184 }
00185 
00186 
00187 #endif //PARSER_BITS_IMPLEMENTATION_FILE
00188 

Generated on Fri Nov 28 04:29:33 2008 for HOOPLE Libraries by  doxygen 1.5.1