diff --git a/src/.clang-format b/src/.clang-format index 6c4e83a112..d5bb8c37a3 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -16,7 +16,7 @@ BraceWrapping: BreakBeforeBraces: Custom BreakConstructorInitializers: AfterColon BreakInheritanceList: AfterColon -ColumnLimit: 80 +ColumnLimit: 100 IndentCaseLabels: true IndentWidth: 2 NamespaceIndentation: Inner diff --git a/src/main.cpp b/src/main.cpp index a5ce79cd42..1e1540241f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://lammps.sandia.gov/, Sandia National Laboratories @@ -13,19 +12,17 @@ ------------------------------------------------------------------------- */ #include "lammps.h" + #include "input.h" - -#include -#include - -#if defined(LAMMPS_TRAP_FPE) && defined(_GNU_SOURCE) -#include -#endif - #if defined(LAMMPS_EXCEPTIONS) #include "exceptions.h" #endif +#include +#if defined(LAMMPS_TRAP_FPE) && defined(_GNU_SOURCE) +#include +#endif + using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- @@ -34,11 +31,11 @@ using namespace LAMMPS_NS; int main(int argc, char **argv) { - MPI_Init(&argc,&argv); + MPI_Init(&argc, &argv); -// enable trapping selected floating point exceptions. -// this uses GNU extensions and is only tested on Linux -// therefore we make it depend on -D_GNU_SOURCE, too. + // enable trapping selected floating point exceptions. + // this uses GNU extensions and is only tested on Linux + // therefore we make it depend on -D_GNU_SOURCE, too. #if defined(LAMMPS_TRAP_FPE) && defined(_GNU_SOURCE) fesetenv(FE_NOMASK_ENV); @@ -50,27 +47,27 @@ int main(int argc, char **argv) #ifdef LAMMPS_EXCEPTIONS try { - LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD); + LAMMPS *lammps = new LAMMPS(argc, argv, MPI_COMM_WORLD); lammps->input->file(); delete lammps; - } catch(LAMMPSAbortException &ae) { + } catch (LAMMPSAbortException &ae) { MPI_Abort(ae.universe, 1); - } catch(LAMMPSException &e) { + } catch (LAMMPSException &e) { MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); exit(1); - } catch(fmt::format_error &fe) { - fprintf(stderr,"fmt::format_error: %s\n", fe.what()); + } catch (fmt::format_error &fe) { + fprintf(stderr, "fmt::format_error: %s\n", fe.what()); MPI_Abort(MPI_COMM_WORLD, 1); exit(1); } #else try { - LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD); + LAMMPS *lammps = new LAMMPS(argc, argv, MPI_COMM_WORLD); lammps->input->file(); delete lammps; - } catch(fmt::format_error &fe) { - fprintf(stderr,"fmt::format_error: %s\n", fe.what()); + } catch (fmt::format_error &fe) { + fprintf(stderr, "fmt::format_error: %s\n", fe.what()); MPI_Abort(MPI_COMM_WORLD, 1); exit(1); } diff --git a/src/tabular_function.cpp b/src/tabular_function.cpp index b29aa3e8a6..15d1f9d329 100644 --- a/src/tabular_function.cpp +++ b/src/tabular_function.cpp @@ -19,9 +19,8 @@ using namespace LAMMPS_NS; TabularFunction::TabularFunction() : - size(0), xmin(0.0), xmax(0.0), xmaxsq(0.0), rdx(0.0), vmax(0.0), - xs(nullptr), ys(nullptr), ys1(nullptr), ys2(nullptr), ys3(nullptr), - ys4(nullptr), ys5(nullptr), ys6(nullptr) + size(0), xmin(0.0), xmax(0.0), xmaxsq(0.0), rdx(0.0), vmax(0.0), xs(nullptr), ys(nullptr), + ys1(nullptr), ys2(nullptr), ys3(nullptr), ys4(nullptr), ys5(nullptr), ys6(nullptr) { } diff --git a/src/utils.cpp b/src/utils.cpp index 13ea7014ed..992f5cec56 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://lammps.sandia.gov/, Sandia National Laboratories @@ -29,7 +28,7 @@ #include #if defined(__linux__) -#include // for readlink +#include // for readlink #endif /*! \file utils.cpp */ @@ -65,24 +64,22 @@ * '(abc)+' Groups */ -extern "C" -{ - /** Match text against a (simplified) regular expression +extern "C" { +/** Match text against a (simplified) regular expression * (regexp will be compiled automatically). */ - static int re_match(const char *text, const char *pattern); +static int re_match(const char *text, const char *pattern); - /** Match find substring that matches a (simplified) regular expression +/** Match find substring that matches a (simplified) regular expression * (regexp will be compiled automatically). */ - static int re_find(const char *text, const char *pattern, int *matchlen); +static int re_find(const char *text, const char *pattern, int *matchlen); } //////////////////////////////////////////////////////////////////////// // Merge sort support functions -static void do_merge(int *idx, int *buf, int llo, int lhi, int rlo, int rhi, - void *ptr, int (*comp)(int, int, void *)); -static void insertion_sort(int *index, int num, void *ptr, - int (*comp)(int, int, void*)); +static void do_merge(int *idx, int *buf, int llo, int lhi, int rlo, int rhi, void *ptr, + int (*comp)(int, int, void *)); +static void insertion_sort(int *index, int num, void *ptr, int (*comp)(int, int, void *)); //////////////////////////////////////////////////////////////////////// @@ -105,7 +102,7 @@ using namespace LAMMPS_NS; */ bool utils::strmatch(const std::string &text, const std::string &pattern) { - const int pos = re_match(text.c_str(),pattern.c_str()); + const int pos = re_match(text.c_str(), pattern.c_str()); return (pos >= 0); } @@ -117,9 +114,9 @@ bool utils::strmatch(const std::string &text, const std::string &pattern) std::string utils::strfind(const std::string &text, const std::string &pattern) { int matchlen; - const int pos = re_find(text.c_str(),pattern.c_str(),&matchlen); - if ((pos >=0) && (matchlen > 0)) - return text.substr(pos,matchlen); + const int pos = re_find(text.c_str(), pattern.c_str(), &matchlen); + if ((pos >= 0) && (matchlen > 0)) + return text.substr(pos, matchlen); else return ""; } @@ -128,17 +125,16 @@ std::string utils::strfind(const std::string &text, const std::string &pattern) void utils::logmesg(LAMMPS *lmp, const std::string &mesg) { - if (lmp->screen) fputs(mesg.c_str(), lmp->screen); + if (lmp->screen) fputs(mesg.c_str(), lmp->screen); if (lmp->logfile) fputs(mesg.c_str(), lmp->logfile); } -void utils::fmtargs_logmesg(LAMMPS *lmp, fmt::string_view format, - fmt::format_args args) +void utils::fmtargs_logmesg(LAMMPS *lmp, fmt::string_view format, fmt::format_args args) { try { logmesg(lmp, fmt::vformat(format, args)); } catch (fmt::format_error &e) { - logmesg(lmp, std::string(e.what())+"\n"); + logmesg(lmp, std::string(e.what()) + "\n"); } } @@ -158,15 +154,15 @@ std::string utils::getsyserror() */ const char *utils::guesspath(char *buf, int len, FILE *fp) { - memset(buf,0,len); + memset(buf, 0, len); #if defined(__linux__) int fd = fileno(fp); // get pathname from /proc or copy (unknown) - if (readlink(fmt::format("/proc/self/fd/{}",fd).c_str(),buf,len-1) <= 0) - strncpy(buf,"(unknown)",len-1); + if (readlink(fmt::format("/proc/self/fd/{}", fd).c_str(), buf, len - 1) <= 0) + strncpy(buf, "(unknown)", len - 1); #else - strncpy(buf,"(unknown)",len-1); + strncpy(buf, "(unknown)", len - 1); #endif return buf; } @@ -178,7 +174,7 @@ char *utils::fgets_trunc(char *buf, int size, FILE *fp) { constexpr int MAXDUMMY = 256; char dummy[MAXDUMMY]; - char *ptr = fgets(buf,size,fp); + char *ptr = fgets(buf, size, fp); // EOF if (!ptr) return nullptr; @@ -186,22 +182,25 @@ char *utils::fgets_trunc(char *buf, int size, FILE *fp) int n = strlen(buf); // line is shorter than buffer, append newline if needed, - if (n < size-2) { - if (buf[n-1] != '\n') { + if (n < size - 2) { + if (buf[n - 1] != '\n') { buf[n] = '\n'; - buf[n+1] = '\0'; + buf[n + 1] = '\0'; } return buf; // line fits exactly. overwrite last but one character. - } else buf[size-2] = '\n'; + } else + buf[size - 2] = '\n'; // continue reading into dummy buffer until end of line or file do { - ptr = fgets(dummy,MAXDUMMY,fp); - if (ptr) n = strlen(ptr); - else n = 0; - } while (n == MAXDUMMY-1 && ptr[MAXDUMMY-1] != '\n'); + ptr = fgets(dummy, MAXDUMMY, fp); + if (ptr) + n = strlen(ptr); + else + n = 0; + } while (n == MAXDUMMY - 1 && ptr[MAXDUMMY - 1] != '\n'); // return first chunk return buf; @@ -209,17 +208,16 @@ char *utils::fgets_trunc(char *buf, int size, FILE *fp) #define MAXPATHLENBUF 1024 /* like fgets() but aborts with an error or EOF is encountered */ -void utils::sfgets(const char *srcname, int srcline, char *s, int size, - FILE *fp, const char *filename, Error *error) +void utils::sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp, + const char *filename, Error *error) { - char *rv = fgets(s,size,fp); - if (rv == nullptr) { // something went wrong + char *rv = fgets(s, size, fp); + if (rv == nullptr) { // something went wrong char buf[MAXPATHLENBUF]; std::string errmsg; // try to figure out the file name from the file pointer - if (!filename) - filename = guesspath(buf,MAXPATHLENBUF,fp); + if (!filename) filename = guesspath(buf, MAXPATHLENBUF, fp); if (feof(fp)) { errmsg = "Unexpected end of file while reading file '"; @@ -231,24 +229,23 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size, errmsg += filename; errmsg += "'"; - if (error) error->one(srcname,srcline,errmsg); - if (s) *s = '\0'; // truncate string to empty in case error is null pointer + if (error) error->one(srcname, srcline, errmsg); + if (s) *s = '\0'; // truncate string to empty in case error is null pointer } return; } /* like fread() but aborts with an error or EOF is encountered */ -void utils::sfread(const char *srcname, int srcline, void *s, size_t size, - size_t num, FILE *fp, const char *filename, Error *error) +void utils::sfread(const char *srcname, int srcline, void *s, size_t size, size_t num, FILE *fp, + const char *filename, Error *error) { - size_t rv = fread(s,size,num,fp); - if (rv != num) { // something went wrong + size_t rv = fread(s, size, num, fp); + if (rv != num) { // something went wrong char buf[MAXPATHLENBUF]; std::string errmsg; // try to figure out the file name from the file pointer - if (!filename) - filename = guesspath(buf,MAXPATHLENBUF,fp); + if (!filename) filename = guesspath(buf, MAXPATHLENBUF, fp); if (feof(fp)) { errmsg = "Unexpected end of file while reading file '"; @@ -260,7 +257,7 @@ void utils::sfread(const char *srcname, int srcline, void *s, size_t size, errmsg += filename; errmsg += "'"; - if (error) error->one(srcname,srcline,errmsg); + if (error) error->one(srcname, srcline, errmsg); } return; } @@ -268,8 +265,7 @@ void utils::sfread(const char *srcname, int srcline, void *s, size_t size, /* ------------------------------------------------------------------ */ /* read N lines and broadcast */ -int utils::read_lines_from_file(FILE *fp, int nlines, int nmax, - char *buffer, int me, MPI_Comm comm) +int utils::read_lines_from_file(FILE *fp, int nlines, int nmax, char *buffer, int me, MPI_Comm comm) { char *ptr = buffer; *ptr = '\0'; @@ -277,8 +273,8 @@ int utils::read_lines_from_file(FILE *fp, int nlines, int nmax, if (me == 0) { if (fp) { for (int i = 0; i < nlines; i++) { - ptr = fgets_trunc(ptr,nmax,fp); - if (!ptr) break; // EOF? + ptr = fgets_trunc(ptr, nmax, fp); + if (!ptr) break; // EOF? // advance ptr to end of string ptr += strlen(ptr); // ensure buffer is null terminated. null char is start of next line. @@ -288,23 +284,22 @@ int utils::read_lines_from_file(FILE *fp, int nlines, int nmax, } int n = strlen(buffer); - MPI_Bcast(&n,1,MPI_INT,0,comm); + MPI_Bcast(&n, 1, MPI_INT, 0, comm); if (n == 0) return 1; - MPI_Bcast(buffer,n+1,MPI_CHAR,0,comm); + MPI_Bcast(buffer, n + 1, MPI_CHAR, 0, comm); return 0; } /* ------------------------------------------------------------------ */ -std::string utils::check_packages_for_style(const std::string &style, - const std::string &name, +std::string utils::check_packages_for_style(const std::string &style, const std::string &name, LAMMPS *lmp) { std::string errmsg = "Unrecognized " + style + " style '" + name + "'"; - const char *pkg = lmp->match_style(style.c_str(),name.c_str()); + const char *pkg = lmp->match_style(style.c_str(), name.c_str()); if (pkg) { - errmsg += fmt::format(" is part of the {} package",pkg); + errmsg += fmt::format(" is part of the {} package", pkg); if (lmp->is_installed_pkg(pkg)) errmsg += ", but seems to be missing because of a dependency"; else @@ -313,26 +308,24 @@ std::string utils::check_packages_for_style(const std::string &style, return errmsg; } - /* ---------------------------------------------------------------------- read a floating point value from a string generate an error if not a legitimate floating point value called by various commands to check validity of their arguments ------------------------------------------------------------------------- */ -double utils::numeric(const char *file, int line, const char *str, - bool do_abort, LAMMPS *lmp) +double utils::numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) { int n = 0; if (str) n = strlen(str); if (n == 0) { const char msg[] = "Expected floating point parameter instead of" - " NULL or empty string in input script or data file"; + " NULL or empty string in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } std::string buf(str); @@ -342,9 +335,9 @@ double utils::numeric(const char *file, int line, const char *str, std::string msg("Expected floating point parameter instead of '"); msg += buf + "' in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } return atof(buf.c_str()); @@ -356,19 +349,18 @@ double utils::numeric(const char *file, int line, const char *str, called by various commands to check validity of their arguments ------------------------------------------------------------------------- */ -int utils::inumeric(const char *file, int line, const char *str, - bool do_abort, LAMMPS *lmp) +int utils::inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) { int n = 0; if (str) n = strlen(str); if (n == 0) { const char msg[] = "Expected integer parameter instead of" - " NULL or empty string in input script or data file"; + " NULL or empty string in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } std::string buf(str); @@ -378,9 +370,9 @@ int utils::inumeric(const char *file, int line, const char *str, std::string msg("Expected integer parameter instead of '"); msg += buf + "' in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } return atoi(buf.c_str()); @@ -392,19 +384,18 @@ int utils::inumeric(const char *file, int line, const char *str, called by various commands to check validity of their arguments ------------------------------------------------------------------------- */ -bigint utils::bnumeric(const char *file, int line, const char *str, - bool do_abort, LAMMPS *lmp) +bigint utils::bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) { int n = 0; if (str) n = strlen(str); if (n == 0) { const char msg[] = "Expected integer parameter instead of" - " NULL or empty string in input script or data file"; + " NULL or empty string in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } std::string buf(str); @@ -414,9 +405,9 @@ bigint utils::bnumeric(const char *file, int line, const char *str, std::string msg("Expected integer parameter instead of '"); msg += buf + "' in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } return ATOBIGINT(buf.c_str()); @@ -428,19 +419,18 @@ bigint utils::bnumeric(const char *file, int line, const char *str, called by various commands to check validity of their arguments ------------------------------------------------------------------------- */ -tagint utils::tnumeric(const char *file, int line, const char *str, - bool do_abort, LAMMPS *lmp) +tagint utils::tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) { int n = 0; if (str) n = strlen(str); if (n == 0) { const char msg[] = "Expected integer parameter instead of" - " NULL or empty string in input script or data file"; + " NULL or empty string in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } std::string buf(str); @@ -450,9 +440,9 @@ tagint utils::tnumeric(const char *file, int line, const char *str, std::string msg("Expected integer parameter instead of '"); msg += buf + "' in input script or data file"; if (do_abort) - lmp->error->one(file,line,msg); + lmp->error->one(file, line, msg); else - lmp->error->all(file,line,msg); + lmp->error->all(file, line, msg); } return ATOTAGINT(buf.c_str()); @@ -461,7 +451,8 @@ tagint utils::tnumeric(const char *file, int line, const char *str, /* ---------------------------------------------------------------------- compute bounds implied by numeric str with a possible wildcard asterisk ------------------------------------------------------------------------- */ -template +// clang-format off +template void utils::bounds(const char *file, int line, const std::string &str, bigint nmin, bigint nmax, TYPE &nlo, TYPE &nhi, Error *error) { @@ -470,40 +461,40 @@ void utils::bounds(const char *file, int line, const std::string &str, // check for illegal charcters size_t found = str.find_first_not_of("*-0123456789"); if (found != std::string::npos) { - if (error) error->all(file,line,fmt::format("Invalid range string: {}",str)); + if (error) error->all(file, line, fmt::format("Invalid range string: {}", str)); return; } found = str.find_first_of("*"); if (found == std::string::npos) { // contains no '*' - nlo = nhi = strtol(str.c_str(),nullptr,10); - } else if (str.size() == 1) { // is only '*' + nlo = nhi = strtol(str.c_str(), nullptr, 10); + } else if (str.size() == 1) { // is only '*' nlo = nmin; nhi = nmax; - } else if (found == 0) { // is '*j' + } else if (found == 0) { // is '*j' nlo = nmin; - nhi = strtol(str.substr(1).c_str(),nullptr,10); - } else if (str.size() == found+1) { // is 'i*' - nlo = strtol(str.c_str(),nullptr,10); + nhi = strtol(str.substr(1).c_str(), nullptr, 10); + } else if (str.size() == found + 1) { // is 'i*' + nlo = strtol(str.c_str(), nullptr, 10); nhi = nmax; - } else { // is 'i*j' - nlo = strtol(str.c_str(),nullptr,10); - nhi = strtol(str.substr(found+1).c_str(),nullptr,10); + } else { // is 'i*j' + nlo = strtol(str.c_str(), nullptr, 10); + nhi = strtol(str.substr(found + 1).c_str(), nullptr, 10); } if (error) { - if ((nlo <= 0) || (nhi <=0)) - error->all(file,line,fmt::format("Invalid range string: {}",str)); + if ((nlo <= 0) || (nhi <= 0)) + error->all(file, line, fmt::format("Invalid range string: {}", str)); if (nlo < nmin) - error->all(file,line,fmt::format("Numeric index {} is out of bounds " - "({}-{})",nlo,nmin,nmax)); + error->all(file, line, fmt::format("Numeric index {} is out of bounds " + "({}-{})", nlo, nmin, nmax)); else if (nhi > nmax) - error->all(file,line,fmt::format("Numeric index {} is out of bounds " - "({}-{})",nhi,nmin,nmax)); + error->all(file, line, fmt::format("Numeric index {} is out of bounds " + "({}-{})", nhi, nmin, nmax)); else if (nlo > nhi) - error->all(file,line,fmt::format("Numeric index {} is out of bounds " - "({}-{})",nlo,nmin,nhi)); + error->all(file, line, fmt::format("Numeric index {} is out of bounds " + "({}-{})", nlo, nmin, nhi)); } } @@ -513,19 +504,20 @@ template void utils::bounds<>(const char *, int, const std::string &, bigint, bigint, long &, long &, Error *); template void utils::bounds<>(const char *, int, const std::string &, bigint, bigint, long long &, long long &, Error *); +// clang-format on /* ------------------------------------------------------------------------- Expand list of arguments in arg to earg if arg contains wildcards ------------------------------------------------------------------------- */ -int utils::expand_args(const char *file, int line, int narg, char **arg, - int mode, char **&earg, LAMMPS *lmp) +int utils::expand_args(const char *file, int line, int narg, char **arg, int mode, char **&earg, + LAMMPS *lmp) { int iarg; char *ptr = nullptr; for (iarg = 0; iarg < narg; iarg++) { - ptr = strchr(arg[iarg],'*'); + ptr = strchr(arg[iarg], '*'); if (ptr) break; } @@ -536,8 +528,8 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, // maxarg should always end up equal to newarg, so caller can free earg - int maxarg = narg-iarg; - earg = (char **) lmp->memory->smalloc(maxarg*sizeof(char *),"input:earg"); + int maxarg = narg - iarg; + earg = (char **) lmp->memory->smalloc(maxarg * sizeof(char *), "input:earg"); int newarg = 0, expandflag, nlo, nhi, nmax; std::string id, wc, tail; @@ -549,14 +541,14 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, // only match compute/fix reference with a '*' wildcard // number range in the first pair of square brackets - if (strmatch(word,"^[cf]_\\w+\\[\\d*\\*\\d*\\]")) { + if (strmatch(word, "^[cf]_\\w+\\[\\d*\\*\\d*\\]")) { // split off the compute/fix ID, the wildcard and trailing text size_t first = word.find("["); - size_t second = word.find("]",first+1); - id = word.substr(2,first-2); - wc = word.substr(first+1,second-first-1); - tail = word.substr(second+1); + size_t second = word.find("]", first + 1); + id = word.substr(2, first - 2); + wc = word.substr(first + 1, second - first - 1); + tail = word.substr(second + 1); if (word[0] == 'c') { int icompute = lmp->modify->find_compute(id); @@ -607,18 +599,16 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, if (expandflag) { // expand wild card string to nlo/nhi numbers - utils::bounds(file,line,wc,1,nmax,nlo,nhi,lmp->error); + utils::bounds(file, line, wc, 1, nmax, nlo, nhi, lmp->error); - if (newarg+nhi-nlo+1 > maxarg) { - maxarg += nhi-nlo+1; - earg = (char **) - lmp->memory->srealloc(earg,maxarg*sizeof(char *),"input:earg"); + if (newarg + nhi - nlo + 1 > maxarg) { + maxarg += nhi - nlo + 1; + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); } for (int index = nlo; index <= nhi; index++) { // assemble and duplicate expanded string - earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}",word[0], - id,index,tail)); + earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); newarg++; } @@ -626,8 +616,7 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, // no expansion: duplicate original string if (newarg == maxarg) { maxarg++; - earg = (char **) - lmp->memory->srealloc(earg,maxarg*sizeof(char *),"input:earg"); + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); } earg[newarg] = utils::strdup(word); newarg++; @@ -648,8 +637,8 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, char *utils::strdup(const std::string &text) { - char *tmp = new char[text.size()+1]; - strcpy(tmp,text.c_str()); + char *tmp = new char[text.size() + 1]; + strcpy(tmp, text.c_str()); return tmp; } @@ -659,12 +648,12 @@ char *utils::strdup(const std::string &text) std::string utils::trim(const std::string &line) { - int beg = re_match(line.c_str(),"\\S+"); - int end = re_match(line.c_str(),"\\s+$"); + int beg = re_match(line.c_str(), "\\S+"); + int end = re_match(line.c_str(), "\\s+$"); if (beg < 0) beg = 0; if (end < 0) end = line.size(); - return line.substr(beg,end-beg); + return line.substr(beg, end - beg); } /* ---------------------------------------------------------------------- @@ -674,9 +663,7 @@ std::string utils::trim(const std::string &line) std::string utils::trim_comment(const std::string &line) { auto end = line.find_first_of("#"); - if (end != std::string::npos) { - return line.substr(0, end); - } + if (end != std::string::npos) { return line.substr(0, end); } return std::string(line); } @@ -686,101 +673,75 @@ std::string utils::trim_comment(const std::string &line) std::string utils::utf8_subst(const std::string &line) { - const unsigned char * const in = (const unsigned char *)line.c_str(); + const unsigned char *const in = (const unsigned char *) line.c_str(); const int len = line.size(); std::string out; - for (int i=0; i < len; ++i) { + for (int i = 0; i < len; ++i) { // UTF-8 2-byte character if ((in[i] & 0xe0U) == 0xc0U) { - if ((i+1) < len) { + if ((i + 1) < len) { // NON-BREAKING SPACE (U+00A0) - if ((in[i] == 0xc2U) && (in[i+1] == 0xa0U)) - out += ' ', ++i; + if ((in[i] == 0xc2U) && (in[i + 1] == 0xa0U)) out += ' ', ++i; // MODIFIER LETTER PLUS SIGN (U+02D6) - if ((in[i] == 0xcbU) && (in[i+1] == 0x96U)) - out += '+', ++i; + if ((in[i] == 0xcbU) && (in[i + 1] == 0x96U)) out += '+', ++i; // MODIFIER LETTER MINUS SIGN (U+02D7) - if ((in[i] == 0xcbU) && (in[i+1] == 0x97U)) - out += '-', ++i; + if ((in[i] == 0xcbU) && (in[i + 1] == 0x97U)) out += '-', ++i; } - // UTF-8 3-byte character + // UTF-8 3-byte character } else if ((in[i] & 0xf0U) == 0xe0U) { - if ((i+2) < len) { + if ((i + 2) < len) { // EN QUAD (U+2000) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x80U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x80U)) out += ' ', i += 2; // EM QUAD (U+2001) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x81U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x81U)) out += ' ', i += 2; // EN SPACE (U+2002) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x82U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x82U)) out += ' ', i += 2; // EM SPACE (U+2003) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x83U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x83U)) out += ' ', i += 2; // THREE-PER-EM SPACE (U+2004) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x84U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x84U)) out += ' ', i += 2; // FOUR-PER-EM SPACE (U+2005) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x85U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x85U)) out += ' ', i += 2; // SIX-PER-EM SPACE (U+2006) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x86U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x86U)) out += ' ', i += 2; // FIGURE SPACE (U+2007) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x87U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x87U)) out += ' ', i += 2; // PUNCTUATION SPACE (U+2008) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x88U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x88U)) out += ' ', i += 2; // THIN SPACE (U+2009) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x89U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x89U)) out += ' ', i += 2; // HAIR SPACE (U+200A) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x8aU)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x8aU)) out += ' ', i += 2; // ZERO WIDTH SPACE (U+200B) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x8bU)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x8bU)) out += ' ', i += 2; // LEFT SINGLE QUOTATION MARK (U+2018) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x98U)) - out += '\'', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x98U)) out += '\'', i += 2; // RIGHT SINGLE QUOTATION MARK (U+2019) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x99U)) - out += '\'', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x99U)) out += '\'', i += 2; // LEFT DOUBLE QUOTATION MARK (U+201C) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x9cU)) - out += '"', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x9cU)) out += '"', i += 2; // RIGHT DOUBLE QUOTATION MARK (U+201D) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0x9dU)) - out += '"', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0x9dU)) out += '"', i += 2; // NARROW NO-BREAK SPACE (U+202F) - if ((in[i] == 0xe2U) && (in[i+1] == 0x80U) && (in[i+2] == 0xafU)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x80U) && (in[i + 2] == 0xafU)) out += ' ', i += 2; // WORD JOINER (U+2060) - if ((in[i] == 0xe2U) && (in[i+1] == 0x81U) && (in[i+2] == 0xa0U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x81U) && (in[i + 2] == 0xa0U)) out += ' ', i += 2; // INVISIBLE SEPARATOR (U+2063) - if ((in[i] == 0xe2U) && (in[i+1] == 0x81U) && (in[i+2] == 0xa3U)) - out += ' ', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x81U) && (in[i + 2] == 0xa3U)) out += ' ', i += 2; // INVISIBLE PLUS (U+2064) - if ((in[i] == 0xe2U) && (in[i+1] == 0x81U) && (in[i+2] == 0xa4U)) - out += '+', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x81U) && (in[i + 2] == 0xa4U)) out += '+', i += 2; // MINUS SIGN (U+2212) - if ((in[i] == 0xe2U) && (in[i+1] == 0x88U) && (in[i+2] == 0x92U)) - out += '-', i += 2; + if ((in[i] == 0xe2U) && (in[i + 1] == 0x88U) && (in[i + 2] == 0x92U)) out += '-', i += 2; // ZERO WIDTH NO-BREAK SPACE (U+FEFF) - if ((in[i] == 0xefU) && (in[i+1] == 0xbbU) && (in[i+2] == 0xbfU)) - out += ' ', i += 2; + if ((in[i] == 0xefU) && (in[i + 1] == 0xbbU) && (in[i + 2] == 0xbfU)) out += ' ', i += 2; } - // UTF-8 4-byte character + // UTF-8 4-byte character } else if ((in[i] & 0xf8U) == 0xf0U) { - if ((i+3) < len) { - ; - } - } else out += in[i]; + if ((i + 3) < len) { ; } + } else + out += in[i]; } return out; } @@ -789,13 +750,14 @@ std::string utils::utf8_subst(const std::string &line) return number of words ------------------------------------------------------------------------- */ -size_t utils::count_words(const char *text) { +size_t utils::count_words(const char *text) +{ size_t count = 0; - const char * buf = text; + const char *buf = text; char c = *buf; while (c) { - if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { c = *++buf; continue; }; @@ -804,9 +766,7 @@ size_t utils::count_words(const char *text) { c = *++buf; while (c) { - if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { - break; - } + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { break; } c = *++buf; } } @@ -818,7 +778,8 @@ size_t utils::count_words(const char *text) { return number of words ------------------------------------------------------------------------- */ -size_t utils::count_words(const std::string &text) { +size_t utils::count_words(const std::string &text) +{ return utils::count_words(text.c_str()); } @@ -826,7 +787,8 @@ size_t utils::count_words(const std::string &text) { Return number of words ------------------------------------------------------------------------- */ -size_t utils::count_words(const std::string &text, const std::string &separators) { +size_t utils::count_words(const std::string &text, const std::string &separators) +{ size_t count = 0; size_t start = text.find_first_not_of(separators); @@ -847,7 +809,8 @@ size_t utils::count_words(const std::string &text, const std::string &separators Trim comment from string and return number of words ------------------------------------------------------------------------- */ -size_t utils::trim_and_count_words(const std::string &text, const std::string &separators) { +size_t utils::trim_and_count_words(const std::string &text, const std::string &separators) +{ return utils::count_words(utils::trim_comment(text), separators); } @@ -866,23 +829,22 @@ std::vector utils::split_words(const std::string &text) while (c) { // leading whitespace - if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') { c = *++buf; ++beg; continue; }; len = 0; - // handle escaped/quoted text. - quoted: + // handle escaped/quoted text. + quoted: // handle single quote if (c == '\'') { ++beg; add = 1; c = *++buf; - while (((c != '\'') && (c != '\0')) - || ((c == '\\') && (buf[1] == '\''))) { + while (((c != '\'') && (c != '\0')) || ((c == '\\') && (buf[1] == '\''))) { if ((c == '\\') && (buf[1] == '\'')) { ++buf; ++len; @@ -898,8 +860,7 @@ std::vector utils::split_words(const std::string &text) ++beg; add = 1; c = *++buf; - while (((c != '"') && (c != '\0')) - || ((c == '\\') && (buf[1] == '"'))) { + while (((c != '"') && (c != '\0')) || ((c == '\\') && (buf[1] == '"'))) { if ((c == '\\') && (buf[1] == '"')) { ++buf; ++len; @@ -921,11 +882,10 @@ std::vector utils::split_words(const std::string &text) c = *++buf; ++len; } - if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') - || (c == '\f') || (c == '\0')) { - list.push_back(text.substr(beg,len)); - beg += len + add; - break; + if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') || (c == '\f') || (c == '\0')) { + list.push_back(text.substr(beg, len)); + beg += len + add; + break; } c = *++buf; ++len; @@ -946,10 +906,9 @@ std::vector utils::split_lines(const std::string &text) Return whether string is a valid integer number ------------------------------------------------------------------------- */ -bool utils::is_integer(const std::string &str) { - if (str.empty()) { - return false; - } +bool utils::is_integer(const std::string &str) +{ + if (str.empty()) return false; for (auto c : str) { if (isdigit(c) || c == '-' || c == '+') continue; @@ -962,10 +921,9 @@ bool utils::is_integer(const std::string &str) { Return whether string is a valid floating-point number ------------------------------------------------------------------------- */ -bool utils::is_double(const std::string &str) { - if (str.empty()) { - return false; - } +bool utils::is_double(const std::string &str) +{ + if (str.empty()) return false; for (auto c : str) { if (isdigit(c)) continue; @@ -980,10 +938,9 @@ bool utils::is_double(const std::string &str) { Return whether string is a valid ID string ------------------------------------------------------------------------- */ -bool utils::is_id(const std::string &str) { - if (str.empty()) { - return false; - } +bool utils::is_id(const std::string &str) +{ + if (str.empty()) return false; for (auto c : str) { if (isalnum(c) || (c == '_')) continue; @@ -996,7 +953,8 @@ bool utils::is_id(const std::string &str) { strip off leading part of path, return just the filename ------------------------------------------------------------------------- */ -std::string utils::path_basename(const std::string &path) { +std::string utils::path_basename(const std::string &path) +{ #if defined(_WIN32) size_t start = path.find_last_of("/\\"); #else @@ -1016,7 +974,8 @@ std::string utils::path_basename(const std::string &path) { Return only the leading part of a path, return just the directory ------------------------------------------------------------------------- */ -std::string utils::path_dirname(const std::string &path) { +std::string utils::path_dirname(const std::string &path) +{ #if defined(_WIN32) size_t start = path.find_last_of("/\\"); #else @@ -1025,27 +984,29 @@ std::string utils::path_dirname(const std::string &path) { if (start == std::string::npos) return "."; - return path.substr(0,start); + return path.substr(0, start); } /* ---------------------------------------------------------------------- join two paths ------------------------------------------------------------------------- */ -std::string utils::path_join(const std::string &a, const std::string &b) { - #if defined(_WIN32) - return fmt::format("{}\\{}", a, b); - #else - return fmt::format("{}/{}", a, b); - #endif +std::string utils::path_join(const std::string &a, const std::string &b) +{ +#if defined(_WIN32) + return fmt::format("{}\\{}", a, b); +#else + return fmt::format("{}/{}", a, b); +#endif } /* ---------------------------------------------------------------------- try to open file for reading ------------------------------------------------------------------------- */ -bool utils::file_is_readable(const std::string &path) { - FILE * fp = fopen(path.c_str(), "r"); +bool utils::file_is_readable(const std::string &path) +{ + FILE *fp = fopen(path.c_str(), "r"); if (fp) { fclose(fp); return true; @@ -1064,7 +1025,8 @@ bool utils::file_is_readable(const std::string &path) { #define OS_PATH_VAR_SEP ":" #endif -std::string utils::get_potential_file_path(const std::string &path) { +std::string utils::get_potential_file_path(const std::string &path) +{ std::string filepath = path; std::string filename = utils::path_basename(path); @@ -1075,16 +1037,14 @@ std::string utils::get_potential_file_path(const std::string &path) { const char *var = getenv("LAMMPS_POTENTIALS"); if (var != nullptr) { - Tokenizer dirs(var,OS_PATH_VAR_SEP); + Tokenizer dirs(var, OS_PATH_VAR_SEP); while (dirs.has_next()) { auto pot = utils::path_basename(filepath); auto dir = dirs.next(); filepath = utils::path_join(dir, pot); - if (utils::file_is_readable(filepath)) { - return filepath; - } + if (utils::file_is_readable(filepath)) { return filepath; } } } } @@ -1097,7 +1057,8 @@ std::string utils::get_potential_file_path(const std::string &path) { if it has a DATE field, return the following word ------------------------------------------------------------------------- */ -std::string utils::get_potential_date(const std::string &path, const std::string &potential_name) { +std::string utils::get_potential_date(const std::string &path, const std::string &potential_name) +{ TextFileReader reader(path, potential_name); reader.ignore_comments = false; @@ -1117,7 +1078,8 @@ std::string utils::get_potential_date(const std::string &path, const std::string if it has UNITS field, return following word ------------------------------------------------------------------------- */ -std::string utils::get_potential_units(const std::string &path, const std::string &potential_name) { +std::string utils::get_potential_units(const std::string &path, const std::string &potential_name) +{ TextFileReader reader(path, potential_name); reader.ignore_comments = false; @@ -1137,10 +1099,10 @@ std::string utils::get_potential_units(const std::string &path, const std::strin ------------------------------------------------------------------------- */ int utils::get_supported_conversions(const int property) { - if (property == ENERGY) { + if (property == ENERGY) return METAL2REAL | REAL2METAL; - } - return NOCONVERT; + else + return NOCONVERT; } /* ---------------------------------------------------------------------- @@ -1156,7 +1118,7 @@ double utils::get_conversion_factor(const int property, const int conversion) } else if (conversion == METAL2REAL) { return 23.060549; } else if (conversion == REAL2METAL) { - return 1.0/23.060549; + return 1.0 / 23.060549; } } return 0.0; @@ -1167,8 +1129,7 @@ double utils::get_conversion_factor(const int property, const int conversion) if fails, search in dir specified by env variable LAMMPS_POTENTIALS ------------------------------------------------------------------------- */ -FILE *utils::open_potential(const std::string &name, LAMMPS *lmp, - int *auto_convert) +FILE *utils::open_potential(const std::string &name, LAMMPS *lmp, int *auto_convert) { auto error = lmp->error; auto me = lmp->comm->me; @@ -1177,38 +1138,35 @@ FILE *utils::open_potential(const std::string &name, LAMMPS *lmp, if (!filepath.empty()) { std::string unit_style = lmp->update->unit_style; - std::string date = get_potential_date(filepath, "potential"); - std::string units = get_potential_units(filepath, "potential"); + std::string date = get_potential_date(filepath, "potential"); + std::string units = get_potential_units(filepath, "potential"); if (!date.empty() && (me == 0)) - logmesg(lmp,"Reading potential file {} with DATE: {}\n", name, date); + logmesg(lmp, "Reading potential file {} with DATE: {}\n", name, date); if (auto_convert == nullptr) { if (!units.empty() && (units != unit_style) && (me == 0)) { - error->one(FLERR, "Potential file {} requires {} units " - "but {} units are in use", name, units, - unit_style); + error->one(FLERR, "Potential file {} requires {} units but {} units are in use", name, + units, unit_style); return nullptr; } } else { if (units.empty() || units == unit_style) { *auto_convert = NOCONVERT; } else { - if ((units == "metal") && (unit_style == "real") - && (*auto_convert & METAL2REAL)) { + if ((units == "metal") && (unit_style == "real") && (*auto_convert & METAL2REAL)) { *auto_convert = METAL2REAL; - } else if ((units == "real") && (unit_style == "metal") - && (*auto_convert & REAL2METAL)) { + } else if ((units == "real") && (unit_style == "metal") && (*auto_convert & REAL2METAL)) { *auto_convert = REAL2METAL; } else { - error->one(FLERR, "Potential file {} requires {} units but {} units " - "are in use", name, units, unit_style); + error->one(FLERR, "Potential file {} requires {} units but {} units are in use", name, + units, unit_style); return nullptr; } } if ((*auto_convert != NOCONVERT) && (me == 0)) - error->warning(FLERR, "Converting potential file in {} units to {} " - "units", units, unit_style); + error->warning(FLERR, "Converting potential file in {} units to {} units", units, + unit_style); } return fopen(filepath.c_str(), "r"); } @@ -1242,8 +1200,10 @@ double utils::timespec2seconds(const std::string ×pec) return -1.0; } - if (i == 3) return (vals[0]*60 + vals[1])*60 + vals[2]; - else if (i == 2) return vals[0]*60 + vals[1]; + if (i == 3) + return (vals[0] * 60 + vals[1]) * 60 + vals[2]; + else if (i == 2) + return vals[0] * 60 + vals[1]; return vals[0]; } @@ -1254,24 +1214,36 @@ double utils::timespec2seconds(const std::string ×pec) int utils::date2num(const std::string &date) { std::size_t found = date.find_first_not_of("0123456789 "); - int num = strtol(date.substr(0,found).c_str(),nullptr,10); + int num = strtol(date.substr(0, found).c_str(), nullptr, 10); auto month = date.substr(found); found = month.find_first_of("0123456789 "); - num += strtol(month.substr(found).c_str(),nullptr,10)*10000; + num += strtol(month.substr(found).c_str(), nullptr, 10) * 10000; if (num < 1000000) num += 20000000; - if (strmatch(month,"^Jan")) num += 100; - else if (strmatch(month,"^Feb")) num += 200; - else if (strmatch(month,"^Mar")) num += 300; - else if (strmatch(month,"^Apr")) num += 400; - else if (strmatch(month,"^May")) num += 500; - else if (strmatch(month,"^Jun")) num += 600; - else if (strmatch(month,"^Jul")) num += 700; - else if (strmatch(month,"^Aug")) num += 800; - else if (strmatch(month,"^Sep")) num += 900; - else if (strmatch(month,"^Oct")) num += 1000; - else if (strmatch(month,"^Nov")) num += 1100; - else if (strmatch(month,"^Dec")) num += 1200; + if (strmatch(month, "^Jan")) + num += 100; + else if (strmatch(month, "^Feb")) + num += 200; + else if (strmatch(month, "^Mar")) + num += 300; + else if (strmatch(month, "^Apr")) + num += 400; + else if (strmatch(month, "^May")) + num += 500; + else if (strmatch(month, "^Jun")) + num += 600; + else if (strmatch(month, "^Jul")) + num += 700; + else if (strmatch(month, "^Aug")) + num += 800; + else if (strmatch(month, "^Sep")) + num += 900; + else if (strmatch(month, "^Oct")) + num += 1000; + else if (strmatch(month, "^Nov")) + num += 1100; + else if (strmatch(month, "^Dec")) + num += 1200; return num; } @@ -1280,19 +1252,18 @@ int utils::date2num(const std::string &date) * Pre-sort small sublists with insertion sort for better overall performance. ------------------------------------------------------------------------- */ -void utils::merge_sort(int *index, int num, void *ptr, - int (*comp)(int, int, void *)) +void utils::merge_sort(int *index, int num, void *ptr, int (*comp)(int, int, void *)) { if (num < 2) return; - int chunk,i,j; + int chunk, i, j; // do insertion sort on chunks of up to 64 elements chunk = 64; - for (i=0; i < num; i += chunk) { - j = (i+chunk > num) ? num-i : chunk; - insertion_sort(index+i,j,ptr,comp); + for (i = 0; i < num; i += chunk) { + j = (i + chunk > num) ? num - i : chunk; + insertion_sort(index + i, j, ptr, comp); } // already done? @@ -1313,27 +1284,29 @@ void utils::merge_sort(int *index, int num, void *ptr, // swap hold and destination buffer - int *tmp = dest; dest = hold; hold = tmp; + int *tmp = dest; + dest = hold; + hold = tmp; // merge from hold array to destination array - for (i=0; i < num-1; i += 2*chunk) { - j = i + 2*chunk; - if (j > num) j=num; - m = i+chunk; - if (m > num) m=num; - do_merge(dest,hold,i,m,m,j,ptr,comp); + for (i = 0; i < num - 1; i += 2 * chunk) { + j = i + 2 * chunk; + if (j > num) j = num; + m = i + chunk; + if (m > num) m = num; + do_merge(dest, hold, i, m, m, j, ptr, comp); } // copy all indices not handled by the chunked merge sort loop - for (; i < num ; i++) dest[i] = hold[i]; + for (; i < num; i++) dest[i] = hold[i]; chunk *= 2; } // if the final sorted data is in buf, copy back to index - if (dest == buf) memcpy(index,buf,sizeof(int)*num); + if (dest == buf) memcpy(index, buf, sizeof(int) * num); delete[] buf; } @@ -1344,17 +1317,16 @@ void utils::merge_sort(int *index, int num, void *ptr, * Merge sort part 2: Insertion sort for pre-sorting of small chunks ------------------------------------------------------------------------- */ -void insertion_sort(int *index, int num, void *ptr, - int (*comp)(int, int, void*)) +void insertion_sort(int *index, int num, void *ptr, int (*comp)(int, int, void *)) { if (num < 2) return; - for (int i=1; i < num; ++i) { + for (int i = 1; i < num; ++i) { int tmp = index[i]; - for (int j=i-1; j >= 0; --j) { - if ((*comp)(index[j],tmp,ptr) > 0) { - index[j+1] = index[j]; + for (int j = i - 1; j >= 0; --j) { + if ((*comp)(index[j], tmp, ptr) > 0) { + index[j + 1] = index[j]; } else { - index[j+1] = tmp; + index[j + 1] = tmp; break; } if (j == 0) index[0] = tmp; @@ -1366,16 +1338,17 @@ void insertion_sort(int *index, int num, void *ptr, * Merge sort part 3: Merge two sublists ------------------------------------------------------------------------- */ -static void do_merge(int *idx, int *buf, int llo, int lhi, int rlo, int rhi, - void *ptr, int (*comp)(int, int, void *)) +static void do_merge(int *idx, int *buf, int llo, int lhi, int rlo, int rhi, void *ptr, + int (*comp)(int, int, void *)) { int i = llo; int l = llo; int r = rlo; while ((l < lhi) && (r < rhi)) { - if ((*comp)(buf[l],buf[r],ptr) < 0) + if ((*comp)(buf[l], buf[r], ptr) < 0) idx[i++] = buf[l++]; - else idx[i++] = buf[r++]; + else + idx[i++] = buf[r++]; } while (l < lhi) idx[i++] = buf[l++]; @@ -1386,143 +1359,190 @@ static void do_merge(int *idx, int *buf, int llo, int lhi, int rlo, int rhi, extern "C" { - /* Typedef'd pointer to get abstract datatype. */ - typedef struct regex_t *re_t; - typedef struct regex_context_t *re_ctx_t; +/* Typedef'd pointer to get abstract datatype. */ +typedef struct regex_t *re_t; +typedef struct regex_context_t *re_ctx_t; - /* Compile regex string pattern to a regex_t-array. */ - static re_t re_compile(re_ctx_t context, const char *pattern); +/* Compile regex string pattern to a regex_t-array. */ +static re_t re_compile(re_ctx_t context, const char *pattern); - /* Find matches of the compiled pattern inside text. */ - static int re_matchp(const char *text, re_t pattern, int *matchlen); +/* Find matches of the compiled pattern inside text. */ +static int re_matchp(const char *text, re_t pattern, int *matchlen); /* Definitions: */ #define MAX_REGEXP_OBJECTS 30 /* Max number of regex symbols in expression. */ #define MAX_CHAR_CLASS_LEN 40 /* Max length of character-class buffer in. */ +enum { + UNUSED, + DOT, + BEGIN, + END, + QUESTIONMARK, + STAR, + PLUS, + CHAR, + CHAR_CLASS, + INV_CHAR_CLASS, + DIGIT, + NOT_DIGIT, + INTEGER, + NOT_INTEGER, + FLOAT, + NOT_FLOAT, + ALPHA, + NOT_ALPHA, + WHITESPACE, + NOT_WHITESPACE /*, BRANCH */ +}; - enum { UNUSED, DOT, BEGIN, END, QUESTIONMARK, STAR, PLUS, - CHAR, CHAR_CLASS, INV_CHAR_CLASS, DIGIT, NOT_DIGIT, - INTEGER, NOT_INTEGER, FLOAT, NOT_FLOAT, - ALPHA, NOT_ALPHA, WHITESPACE, NOT_WHITESPACE /*, BRANCH */ }; +typedef struct regex_t { + unsigned char type; /* CHAR, STAR, etc. */ + union { + unsigned char ch; /* the character itself */ + unsigned char *ccl; /* OR a pointer to characters in class */ + } u; +} regex_t; - typedef struct regex_t { - unsigned char type; /* CHAR, STAR, etc. */ - union { - unsigned char ch; /* the character itself */ - unsigned char *ccl; /* OR a pointer to characters in class */ - } u; - } regex_t; - - typedef struct regex_context_t { - /* MAX_REGEXP_OBJECTS is the max number of symbols in the expression. +typedef struct regex_context_t { + /* MAX_REGEXP_OBJECTS is the max number of symbols in the expression. MAX_CHAR_CLASS_LEN determines the size of buffer for chars in all char-classes in the expression. */ - regex_t re_compiled[MAX_REGEXP_OBJECTS]; - unsigned char ccl_buf[MAX_CHAR_CLASS_LEN]; - } regex_context_t; + regex_t re_compiled[MAX_REGEXP_OBJECTS]; + unsigned char ccl_buf[MAX_CHAR_CLASS_LEN]; +} regex_context_t; - int re_match(const char *text, const char *pattern) - { - regex_context_t context; - int dummy; - return re_matchp(text, re_compile(&context, pattern), &dummy); - } +int re_match(const char *text, const char *pattern) +{ + regex_context_t context; + int dummy; + return re_matchp(text, re_compile(&context, pattern), &dummy); +} - int re_find(const char *text, const char *pattern, int *matchlen) - { - regex_context_t context; - return re_matchp(text, re_compile(&context, pattern), matchlen); - } +int re_find(const char *text, const char *pattern, int *matchlen) +{ + regex_context_t context; + return re_matchp(text, re_compile(&context, pattern), matchlen); +} /* Private function declarations: */ - static int matchpattern(regex_t *pattern, const char *text, int *matchlen); - static int matchcharclass(char c, const char *str); - static int matchstar(regex_t p, regex_t *pattern, const char *text, int *matchlen); - static int matchplus(regex_t p, regex_t *pattern, const char *text, int *matchlen); - static int matchone(regex_t p, char c); - static int matchdigit(char c); - static int matchint(char c); - static int matchfloat(char c); - static int matchalpha(char c); - static int matchwhitespace(char c); - static int matchmetachar(char c, const char *str); - static int matchrange(char c, const char *str); - static int matchdot(char c); - static int ismetachar(char c); +static int matchpattern(regex_t *pattern, const char *text, int *matchlen); +static int matchcharclass(char c, const char *str); +static int matchstar(regex_t p, regex_t *pattern, const char *text, int *matchlen); +static int matchplus(regex_t p, regex_t *pattern, const char *text, int *matchlen); +static int matchone(regex_t p, char c); +static int matchdigit(char c); +static int matchint(char c); +static int matchfloat(char c); +static int matchalpha(char c); +static int matchwhitespace(char c); +static int matchmetachar(char c, const char *str); +static int matchrange(char c, const char *str); +static int matchdot(char c); +static int ismetachar(char c); /* Semi-public functions: */ - int re_matchp(const char *text, re_t pattern, int *matchlen) - { - *matchlen = 0; - if (pattern != 0) { - if (pattern[0].type == BEGIN) { - return ((matchpattern(&pattern[1], text, matchlen)) ? 0 : -1); - } else { - int idx = -1; +int re_matchp(const char *text, re_t pattern, int *matchlen) +{ + *matchlen = 0; + if (pattern != 0) { + if (pattern[0].type == BEGIN) { + return ((matchpattern(&pattern[1], text, matchlen)) ? 0 : -1); + } else { + int idx = -1; - do { - idx += 1; + do { + idx += 1; - if (matchpattern(pattern, text, matchlen)) { - if (text[0] == '\0') - return -1; + if (matchpattern(pattern, text, matchlen)) { + if (text[0] == '\0') return -1; - return idx; - } + return idx; } - while (*text++ != '\0'); - } + } while (*text++ != '\0'); } - return -1; } + return -1; +} - re_t re_compile(re_ctx_t context, const char *pattern) - { - regex_t * const re_compiled = context->re_compiled; - unsigned char * const ccl_buf = context->ccl_buf; - int ccl_bufidx = 1; +re_t re_compile(re_ctx_t context, const char *pattern) +{ + regex_t *const re_compiled = context->re_compiled; + unsigned char *const ccl_buf = context->ccl_buf; + int ccl_bufidx = 1; - char c; /* current char in pattern */ - int i = 0; /* index into pattern */ - int j = 0; /* index into re_compiled */ + char c; /* current char in pattern */ + int i = 0; /* index into pattern */ + int j = 0; /* index into re_compiled */ - while (pattern[i] != '\0' && (j+1 < MAX_REGEXP_OBJECTS)) { - c = pattern[i]; + while (pattern[i] != '\0' && (j + 1 < MAX_REGEXP_OBJECTS)) { + c = pattern[i]; - switch (c) { + switch (c) { /* Meta-characters: */ - case '^': { re_compiled[j].type = BEGIN; } break; - case '$': { re_compiled[j].type = END; } break; - case '.': { re_compiled[j].type = DOT; } break; - case '*': { re_compiled[j].type = STAR; } break; - case '+': { re_compiled[j].type = PLUS; } break; - case '?': { re_compiled[j].type = QUESTIONMARK; } break; + case '^': { + re_compiled[j].type = BEGIN; + } break; + case '$': { + re_compiled[j].type = END; + } break; + case '.': { + re_compiled[j].type = DOT; + } break; + case '*': { + re_compiled[j].type = STAR; + } break; + case '+': { + re_compiled[j].type = PLUS; + } break; + case '?': { + re_compiled[j].type = QUESTIONMARK; + } break; /* Escaped character-classes (\s \w ...): */ case '\\': { - if (pattern[i+1] != '\0') { + if (pattern[i + 1] != '\0') { /* Skip the escape-char '\\' */ i += 1; /* ... and check the next */ switch (pattern[i]) { - /* Meta-character: */ - case 'd': { re_compiled[j].type = DIGIT; } break; - case 'D': { re_compiled[j].type = NOT_DIGIT; } break; - case 'i': { re_compiled[j].type = INTEGER; } break; - case 'I': { re_compiled[j].type = NOT_INTEGER; } break; - case 'f': { re_compiled[j].type = FLOAT; } break; - case 'F': { re_compiled[j].type = NOT_FLOAT; } break; - case 'w': { re_compiled[j].type = ALPHA; } break; - case 'W': { re_compiled[j].type = NOT_ALPHA; } break; - case 's': { re_compiled[j].type = WHITESPACE; } break; - case 'S': { re_compiled[j].type = NOT_WHITESPACE; } break; + /* Meta-character: */ + case 'd': { + re_compiled[j].type = DIGIT; + } break; + case 'D': { + re_compiled[j].type = NOT_DIGIT; + } break; + case 'i': { + re_compiled[j].type = INTEGER; + } break; + case 'I': { + re_compiled[j].type = NOT_INTEGER; + } break; + case 'f': { + re_compiled[j].type = FLOAT; + } break; + case 'F': { + re_compiled[j].type = NOT_FLOAT; + } break; + case 'w': { + re_compiled[j].type = ALPHA; + } break; + case 'W': { + re_compiled[j].type = NOT_ALPHA; + } break; + case 's': { + re_compiled[j].type = WHITESPACE; + } break; + case 'S': { + re_compiled[j].type = NOT_WHITESPACE; + } break; - /* Escaped character, e.g. '.' or '$' */ - default: { - re_compiled[j].type = CHAR; - re_compiled[j].u.ch = pattern[i]; - } break; + /* Escaped character, e.g. '.' or '$' */ + default: { + re_compiled[j].type = CHAR; + re_compiled[j].u.ch = pattern[i]; + } break; } } /* '\\' as last char in pattern -> invalid regular expression. */ @@ -1534,10 +1554,10 @@ extern "C" { int buf_begin = ccl_bufidx; /* Look-ahead to determine if negated */ - if (pattern[i+1] == '^') { + if (pattern[i + 1] == '^') { re_compiled[j].type = INV_CHAR_CLASS; - i += 1; /* Increment i to avoid including '^' in the char-buffer */ - if (pattern[i+1] == 0) /* incomplete pattern, missing non-zero char after '^' */ + i += 1; /* Increment i to avoid including '^' in the char-buffer */ + if (pattern[i + 1] == 0) /* incomplete pattern, missing non-zero char after '^' */ { return 0; } @@ -1549,13 +1569,11 @@ extern "C" { while ((pattern[++i] != ']') && (pattern[i] != '\0')) { /* Missing ] */ if (pattern[i] == '\\') { - if (ccl_bufidx >= MAX_CHAR_CLASS_LEN - 1) { + if (ccl_bufidx >= MAX_CHAR_CLASS_LEN - 1) { return 0; } + if (pattern[i + 1] == 0) /* incomplete pattern, missing non-zero char after '\\' */ + { return 0; } - if (pattern[i+1] == 0) /* incomplete pattern, missing non-zero char after '\\' */ - { - return 0; - } ccl_buf[ccl_bufidx++] = pattern[i++]; } else if (ccl_bufidx >= MAX_CHAR_CLASS_LEN) { return 0; @@ -1572,221 +1590,225 @@ extern "C" { } break; /* Other characters: */ - default: - { + default: { re_compiled[j].type = CHAR; re_compiled[j].u.ch = c; } break; - } - /* no buffer-out-of-bounds access on invalid patterns - see https://github.com/kokke/tiny-regex-c/commit/1a279e04014b70b0695fba559a7c05d55e6ee90b */ - if (pattern[i] == 0) - { - return 0; - } - - i += 1; - j += 1; } - /* 'UNUSED' is a sentinel used to indicate end-of-pattern */ - re_compiled[j].type = UNUSED; + /* no buffer-out-of-bounds access on invalid patterns - + * see https://github.com/kokke/tiny-regex-c/commit/1a279e04014b70b0695fba559a7c05d55e6ee90b */ + if (pattern[i] == 0) { return 0; } - return (re_t) re_compiled; + i += 1; + j += 1; } + /* 'UNUSED' is a sentinel used to indicate end-of-pattern */ + re_compiled[j].type = UNUSED; + return (re_t) re_compiled; +} /* Private functions: */ - static int matchdigit(char c) - { - return ((c >= '0') && (c <= '9')); - } +static int matchdigit(char c) +{ + return ((c >= '0') && (c <= '9')); +} - static int matchint(char c) - { - return (matchdigit(c) || (c == '-') || (c == '+')); - } +static int matchint(char c) +{ + return (matchdigit(c) || (c == '-') || (c == '+')); +} - static int matchfloat(char c) - { - return (matchint(c) || (c == '.') || (c == 'e') || (c == 'E')); - } +static int matchfloat(char c) +{ + return (matchint(c) || (c == '.') || (c == 'e') || (c == 'E')); +} - static int matchalpha(char c) - { - return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); - } +static int matchalpha(char c) +{ + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); +} - static int matchwhitespace(char c) - { - return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\f') || (c == '\v')); - } +static int matchwhitespace(char c) +{ + return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\f') || (c == '\v')); +} - static int matchalphanum(char c) - { - return ((c == '_') || matchalpha(c) || matchdigit(c)); - } +static int matchalphanum(char c) +{ + return ((c == '_') || matchalpha(c) || matchdigit(c)); +} - static int matchrange(char c, const char *str) - { - return ((c != '-') && (str[0] != '\0') - && (str[0] != '-') && (str[1] == '-') - && (str[1] != '\0') && (str[2] != '\0') - && ((c >= str[0]) && (c <= str[2]))); - } +static int matchrange(char c, const char *str) +{ + return ((c != '-') && (str[0] != '\0') && (str[0] != '-') && (str[1] == '-') && + (str[1] != '\0') && (str[2] != '\0') && ((c >= str[0]) && (c <= str[2]))); +} - static int matchdot(char c) - { +static int matchdot(char c) +{ #if defined(RE_DOT_MATCHES_NEWLINE) && (RE_DOT_MATCHES_NEWLINE == 1) - (void)c; - return 1; + (void) c; + return 1; #else - return c != '\n' && c != '\r'; + return c != '\n' && c != '\r'; #endif - } +} - static int ismetachar(char c) - { - return ((c == 's') || (c == 'S') - || (c == 'w') || (c == 'W') - || (c == 'd') || (c == 'D')); - } +static int ismetachar(char c) +{ + return ((c == 's') || (c == 'S') || (c == 'w') || (c == 'W') || (c == 'd') || (c == 'D')); +} - static int matchmetachar(char c, const char *str) - { - switch (str[0]) { - case 'd': return matchdigit(c); - case 'D': return !matchdigit(c); - case 'i': return matchint(c); - case 'I': return !matchint(c); - case 'f': return matchfloat(c); - case 'F': return !matchfloat(c); - case 'w': return matchalphanum(c); - case 'W': return !matchalphanum(c); - case 's': return matchwhitespace(c); - case 'S': return !matchwhitespace(c); - default: return (c == str[0]); - } +static int matchmetachar(char c, const char *str) +{ + switch (str[0]) { + case 'd': + return matchdigit(c); + case 'D': + return !matchdigit(c); + case 'i': + return matchint(c); + case 'I': + return !matchint(c); + case 'f': + return matchfloat(c); + case 'F': + return !matchfloat(c); + case 'w': + return matchalphanum(c); + case 'W': + return !matchalphanum(c); + case 's': + return matchwhitespace(c); + case 'S': + return !matchwhitespace(c); + default: + return (c == str[0]); } +} - static int matchcharclass(char c, const char *str) - { - do { - if (matchrange(c, str)) { +static int matchcharclass(char c, const char *str) +{ + do { + if (matchrange(c, str)) { + return 1; + } else if (str[0] == '\\') { + /* Escape-char: increment str-ptr and match on next char */ + str += 1; + if (matchmetachar(c, str)) { + return 1; + } else if ((c == str[0]) && !ismetachar(c)) { return 1; - } else if (str[0] == '\\') { - /* Escape-char: increment str-ptr and match on next char */ - str += 1; - if (matchmetachar(c, str)) { - return 1; - } else if ((c == str[0]) && !ismetachar(c)) { - return 1; - } - } else if (c == str[0]) { - if (c == '-') { - return ((str[-1] == '\0') || (str[1] == '\0')); - } else { - return 1; - } } - } - while (*str++ != '\0'); - - return 0; - } - - static int matchone(regex_t p, char c) - { - switch (p.type) { - case DOT: return matchdot(c); - case CHAR_CLASS: return matchcharclass(c, (const char *)p.u.ccl); - case INV_CHAR_CLASS: return !matchcharclass(c, (const char *)p.u.ccl); - case DIGIT: return matchdigit(c); - case NOT_DIGIT: return !matchdigit(c); - case INTEGER: return matchint(c); - case NOT_INTEGER: return !matchint(c); - case FLOAT: return matchfloat(c); - case NOT_FLOAT: return !matchfloat(c); - case ALPHA: return matchalphanum(c); - case NOT_ALPHA: return !matchalphanum(c); - case WHITESPACE: return matchwhitespace(c); - case NOT_WHITESPACE: return !matchwhitespace(c); - default: return (p.u.ch == c); - } - } - - static int matchstar(regex_t p, regex_t *pattern, const char *text, int *matchlen) - { - int prelen = *matchlen; - const char *prepos = text; - while ((text[0] != '\0') && matchone(p, *text)) - { - text++; - (*matchlen)++; - } - while (text >= prepos) - { - if (matchpattern(pattern, text--, matchlen)) - return 1; - (*matchlen)--; - } - - *matchlen = prelen; - return 0; - } - - static int matchplus(regex_t p, regex_t *pattern, const char *text, int *matchlen) - { - const char *prepos = text; - while ((text[0] != '\0') && matchone(p, *text)) - { - text++; - (*matchlen)++; - } - while (text > prepos) - { - if (matchpattern(pattern, text--, matchlen)) - return 1; - (*matchlen)--; - } - return 0; - } - - static int matchquestion(regex_t p, regex_t *pattern, const char *text, int *matchlen) - { - if (p.type == UNUSED) - return 1; - if (matchpattern(pattern, text, matchlen)) - return 1; - if (*text && matchone(p, *text++)) - { - if (matchpattern(pattern, text, matchlen)) - { - (*matchlen)++; + } else if (c == str[0]) { + if (c == '-') { + return ((str[-1] == '\0') || (str[1] == '\0')); + } else { return 1; } } - return 0; + } while (*str++ != '\0'); + + return 0; +} + +static int matchone(regex_t p, char c) +{ + switch (p.type) { + case DOT: + return matchdot(c); + case CHAR_CLASS: + return matchcharclass(c, (const char *) p.u.ccl); + case INV_CHAR_CLASS: + return !matchcharclass(c, (const char *) p.u.ccl); + case DIGIT: + return matchdigit(c); + case NOT_DIGIT: + return !matchdigit(c); + case INTEGER: + return matchint(c); + case NOT_INTEGER: + return !matchint(c); + case FLOAT: + return matchfloat(c); + case NOT_FLOAT: + return !matchfloat(c); + case ALPHA: + return matchalphanum(c); + case NOT_ALPHA: + return !matchalphanum(c); + case WHITESPACE: + return matchwhitespace(c); + case NOT_WHITESPACE: + return !matchwhitespace(c); + default: + return (p.u.ch == c); } +} + +static int matchstar(regex_t p, regex_t *pattern, const char *text, int *matchlen) +{ + int prelen = *matchlen; + const char *prepos = text; + while ((text[0] != '\0') && matchone(p, *text)) { + text++; + (*matchlen)++; + } + while (text >= prepos) { + if (matchpattern(pattern, text--, matchlen)) return 1; + (*matchlen)--; + } + + *matchlen = prelen; + return 0; +} + +static int matchplus(regex_t p, regex_t *pattern, const char *text, int *matchlen) +{ + const char *prepos = text; + while ((text[0] != '\0') && matchone(p, *text)) { + text++; + (*matchlen)++; + } + while (text > prepos) { + if (matchpattern(pattern, text--, matchlen)) return 1; + (*matchlen)--; + } + return 0; +} + +static int matchquestion(regex_t p, regex_t *pattern, const char *text, int *matchlen) +{ + if (p.type == UNUSED) return 1; + if (matchpattern(pattern, text, matchlen)) return 1; + if (*text && matchone(p, *text++)) { + if (matchpattern(pattern, text, matchlen)) { + (*matchlen)++; + return 1; + } + } + return 0; +} /* Iterative matching */ - static int matchpattern(regex_t *pattern, const char *text, int *matchlen) - { - int pre = *matchlen; - do { - if ((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK)) { - return matchquestion(pattern[0], &pattern[2], text, matchlen); - } else if (pattern[1].type == STAR) { - return matchstar(pattern[0], &pattern[2], text, matchlen); - } else if (pattern[1].type == PLUS) { - return matchplus(pattern[0], &pattern[2], text, matchlen); - } else if ((pattern[0].type == END) && pattern[1].type == UNUSED) { - return (text[0] == '\0'); - } - (*matchlen)++; +static int matchpattern(regex_t *pattern, const char *text, int *matchlen) +{ + int pre = *matchlen; + do { + if ((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK)) { + return matchquestion(pattern[0], &pattern[2], text, matchlen); + } else if (pattern[1].type == STAR) { + return matchstar(pattern[0], &pattern[2], text, matchlen); + } else if (pattern[1].type == PLUS) { + return matchplus(pattern[0], &pattern[2], text, matchlen); + } else if ((pattern[0].type == END) && pattern[1].type == UNUSED) { + return (text[0] == '\0'); } - while ((text[0] != '\0') && matchone(*pattern++, *text++)); - - *matchlen = pre; - return 0; - } + (*matchlen)++; + } while ((text[0] != '\0') && matchone(*pattern++, *text++)); + *matchlen = pre; + return 0; +} }