/* This file is part of dvi2bitmap; see README for copyrights and licence */ #include #include #ifdef HAVE_CSTD_INCLUDE # include # include # include # include # include # if CCTYPE_IN_STD using std::isspace; using std::isxdigit; # endif #else # include # include # include # include # include #endif #include // this is standard according to single-unix, // how POSIXy is that? How C++? #ifdef HAVE_SYS_WAIT #include #endif // HAVE_SYS_WAIT //#include using STD::ostream; // following are used several times using STD::ends; using STD::endl; using STD::cerr; using STD::strtoul; using STD::strncpy; #include "Util.h" #include "stringstream.h" /** * Various utility functions. */ namespace Util { verbosities verbosity_ = normal; } /** Tokenise string at whitespace. * * @param str the string to be tokenised * @return a list containing the whitespace-separated tokens in the string */ string_list& Util::tokenise_string (string str) { static string_list *l; if (verbosity_ > normal) cerr << "tokenise_string: string=<" << str << ">" << endl; if (l == 0) l = new string_list(); else l->clear(); unsigned int i=0; // skip leading whitespace while (i < str.length() && isspace(str[i])) i++; while (i < str.length()) { unsigned int wstart = i; while (i < str.length() && !isspace(str[i])) i++; string t = str.substr(wstart,i-wstart); if (verbosity_ > normal) cerr << "tokenise:" << t << ":" << endl; l->push_back(t); while (i < str.length() && isspace(str[i])) i++; } return *l; } /** * Parse an RGB specification. This is either a sequence of three integers * separated by slashes (or in fact any non-number character), or else * a string of the form @c \#RRGGBB. Set the `rgb' structure to the * resulting numbers. The integers must be in the range [0,255], and * may be specified in decimal, octal, or hex. * * @param rgb the BitmapColour corresponding to the * s argument * @param s the RGB specification * * @return true if the parse is successful. */ bool Util::parseRGB (Bitmap::BitmapColour& rgb, const char* s) { const char *p = s; unsigned long val; while (*p != '\0' && isspace(*p)) p++; if (*p == '#') { char buf[3]; buf[2] = '\0'; p++; strncpy(buf, p, 2); val = strtoul(buf, 0, 16); if (val > 255) // can't happen, with two hex digits return false; rgb.red = static_cast(val); p += 2; strncpy(buf, p, 2); val = strtoul(buf, 0, 16); if (val > 255) return false; rgb.green = static_cast(val); p += 2; strncpy(buf, p, 2); val = strtoul(buf, 0, 16); if (val > 255) return false; rgb.blue = static_cast(val); } else { val = strtoul (s, const_cast(&p), 0); if (val > 255) return false; rgb.red = static_cast(val); if (p == s) // no digit return false; if (*p == '\0') // end of string return false; s = p; while (!isxdigit(*s)) { if (*s == '\0') return false; s++; } val = strtoul (s, const_cast(&p), 0); if (val > 255) return false; rgb.green = static_cast(val); if (p == s) // no digit return false; if (*p == '\0') // end of string return false; s = p; while (!isxdigit(*s)) { if (*s == '\0') return false; s++; } val = strtoul (s, const_cast(&p), 0); if (val > 255) return false; rgb.blue = static_cast(val); if (p == s) // no digit return false; } return true; } /** * Convert a string_list to a null-terminated array of * character pointers. The resulting array can conveniently be * deleted using {@link #delete_string_array}. * * @param l a string_list * @return a pointer to a null-terminated array of null-terminated * character arrays */ char** Util::string_list_to_array(string_list& l) { int argc = l.size(); char **sl = new char*[argc+1]; int i = 0; for (string_list::const_iterator ci = l.begin(); ci != l.end(); ci++) { string s = *ci; sl[i] = new char[s.size()+1]; STD::strcpy(sl[i], s.c_str()); i++; } sl[i] = 0; return sl; } /** * Deletes the array of strings returned by {@link #string_list_to_array}. * * @param sl a null-terminated array of strings */ void Util::delete_string_array(char** sl) { for (int i=0; sl[i] != 0; i++) delete[] sl[i]; delete[] sl; } /** * Sets the verbosity of the methods in this class * * @param level how verbose the class's methods should be */ void Util::verbosity (const verbosities level) { verbosity_ = level; return; }