#include #include #include #include #include #include #include "gputil.h" #include "streq.h" #include "int2string.h" void bump_all_in_range(map &m, int lo, int hi, int bump) { while (lo <= hi) m[lo++] += bump; } bool is_all_whitespace(const char *s) { for (int i = 0; s[i] != '\0'; i++) if (!isspace(s[i])) return false; return true; } bool is_all_digits(const char *s) { for (int i = 0; s[i] != '\0'; i++) if (!isdigit(s[i])) return false; return true; } void remove_arg0(int argc, char **argv) { for (int i = 0; i < argc - 1; i++) argv[i] = argv[i + 1]; } void remove_arg(int &argc, char **argv, int n) { assert(n >= 0); remove_arg0(argc-- - n, argv + n); } /* Remove args start through end, inclusive, and modify argc and argv to reflect their removal. */ void remove_args(int &argc, char **argv, int start, int end) { for (int i = start; i <= end; i++) remove_arg(argc, argv, start); } void showargs(int argc, char **argv) { cout << "Args (argc=" << argc << "): "; for (int i = 0; i < argc; i++) cout << ' ' << argv[i]; cout << endl; } /* Search for the first occurence of s in argv. Only search up to the "limit" position, i.e., argv[limit], if limit > 0. If not present, return false. If present, if no arguments follow it then exit with an error; otherwise, the next argument is put in v, and argc and argv are modified so that s and the arg following it are removed, and we return true. Never search beyond an arg that is "--" because that is conventionally used to mean "end of switches." */ bool snaffle_from_args(char *s, char *&v, int &argc, char **argv, int limit) { // cout << "before snaffle: "; // showargs(argc, argv); for (int i = 0; i < argc && (limit < 0 || i <= limit); i++) if (streq(argv[i], "--")) break; else if (streq(s, argv[i])) if (i + 1 < argc) { v = argv[i + 1]; remove_args(argc, argv, i, i + 1); // cout << "after snaffle: "; // showargs(argc, argv); return true; } else { cerr << "Error: no value specified for argument `" << s << "'" << endl; exit(8); } return false; } /* Return a string that is the same as s but with trailing and leading whitespace removed. May modify s. */ char *trim(char *s) { while (isspace(*s)) s++; int l = strlen(s); while (l > 0) if (isspace(s[l - 1])) s[--l] = '\0'; else break; return s; } /* Read characters from a stream until end-of-file or until the given character is found. Result is a zero-terminated character string. If the given character is found, it is the last non-zero character in the result. Callee is responsible for calling delete[] on the return value. If n is non-null then the total number of characters read is stored in *n. */ char *read(istream &s, char t, int *n) { int count = 0; int result_size = 20; char *result = new char[result_size]; assert(result != NULL); char c; result[0] = '\0'; while (s.get(c)) { if (count >= result_size - 1) { int new_result_size = (int) (result_size * 1.3); char *new_result = new char[new_result_size]; assert(new_result != NULL); for (int i = 0; i < result_size; i++) new_result[i] = result[i]; delete[] result; result = new_result; result_size = new_result_size; } result[count++] = c; if (c == t) break; } result[count] = '\0'; if (n != NULL) *n = count; return result; } /* Read up to the first \n character. */ char *readline(istream &s, int *n) { return read(s, '\n', n); } /* Return the largest p in 0 ... n-1 such that s[p] == c. */ /* Except, if n is -1, return findlast(c, s, strlen(s)). */ /* If c is not found, return -1. */ int findlast(char c, char *s, int n) { if (n < 0) { assert(n == -1); n = strlen(s); } for (int p = n - 1; p >= 0; p--) if (s[p] == c) return p; return -1; } /* no_spaces(s) returns a string similar to s but with no spaces in it. Each space is replaced with an underscore and the number of spaces (if any) is appended. */ string no_spaces(const string &s) { const int n = s.size(); int count = 0; string r(s); for (int i = 0; i < n; i++) if (r[i] == ' ') { count++; r[i] = '_'; } return (count > 0) ? (r + i2s(count)) : r; }