diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp index 25377ae82827307e8c9e66c98e32382788222221..acd35a1b9c5ee533b1dcc6e256cfd1048fde9e05 100644 --- a/src/DIPOLE/atom_vec_dipole.cpp +++ b/src/DIPOLE/atom_vec_dipole.cpp @@ -41,7 +41,7 @@ AtomVecDipole::AtomVecDipole(LAMMPS *lmp, int narg, char **arg) : size_border = 11; size_velocity = 3; size_data_atom = 9; - size_data_vel = 7; + size_data_vel = 4; xcol_data = 4; atom->q_flag = atom->mu_flag = 1; diff --git a/src/fix_print.cpp b/src/fix_print.cpp index 614dbc4c5c3e8c292ee26f84477225f21c3f222e..5db6b096da4217a61478481098b334c80a114053 100644 --- a/src/fix_print.cpp +++ b/src/fix_print.cpp @@ -18,13 +18,12 @@ #include "input.h" #include "modify.h" #include "variable.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; -#define MAXLINE 1024 - /* ---------------------------------------------------------------------- */ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : @@ -40,6 +39,10 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : string = new char[n]; strcpy(string,arg[4]); + copy = (char *) memory->smalloc(n*sizeof(char),"fix/print:copy"); + work = (char *) memory->smalloc(n*sizeof(char),"fix/print:work"); + maxcopy = maxwork = n; + // parse optional args fp = NULL; @@ -85,9 +88,6 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : delete [] title; - copy = new char[MAXLINE]; - work = new char[MAXLINE]; - // add nfirst to all computes that store invocation times // since don't know a priori which are invoked via variables by this fix // once in end_of_step() can set timestep for ones actually invoked @@ -101,8 +101,8 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : FixPrint::~FixPrint() { delete [] string; - delete [] copy; - delete [] work; + memory->sfree(copy); + memory->sfree(work); if (fp && me == 0) fclose(fp); } @@ -128,16 +128,15 @@ void FixPrint::end_of_step() modify->clearstep_compute(); strcpy(copy,string); - input->substitute(copy,0); - strcat(copy,"\n"); + input->substitute(copy,work,maxcopy,maxwork,0); modify->addstep_compute(update->ntimestep + nevery); if (me == 0) { - if (screenflag && screen) fprintf(screen,"%s",copy); - if (screenflag && logfile) fprintf(logfile,"%s",copy); + if (screenflag && screen) fprintf(screen,"%s\n",copy); + if (screenflag && logfile) fprintf(logfile,"%s\n",copy); if (fp) { - fprintf(fp,"%s",copy); + fprintf(fp,"%s\n",copy); fflush(fp); } } diff --git a/src/fix_print.h b/src/fix_print.h index 35c18d78f213a36203682f37a993ffeaef6bd4d1..8cba1093cdf0094876a466832f24f38b177ac92f 100644 --- a/src/fix_print.h +++ b/src/fix_print.h @@ -36,6 +36,7 @@ class FixPrint : public Fix { int me,screenflag; FILE *fp; char *string,*copy,*work; + int maxcopy,maxwork; }; } diff --git a/src/input.cpp b/src/input.cpp index 3ec89cd44b81232160b0462c09890459d877e845..e1ce2851859e0288482c4356dad2db876875c1d7 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -52,7 +52,7 @@ using namespace LAMMPS_NS; -#define MAXLINE 8192 +#define DELTALINE 256 #define DELTA 4 /* ---------------------------------------------------------------------- */ @@ -61,9 +61,8 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp) { MPI_Comm_rank(world,&me); - line = new char[MAXLINE]; - copy = new char[MAXLINE]; - work = new char[MAXLINE]; + maxline = maxcopy = maxwork = 0; + line = copy = work = NULL; narg = maxarg = 0; arg = NULL; @@ -112,13 +111,13 @@ Input::~Input() // don't free command and arg strings // they just point to other allocated memory - delete variable; - delete [] line; - delete [] copy; - delete [] work; + memory->sfree(line); + memory->sfree(copy); + memory->sfree(work); if (labelstr) delete [] labelstr; memory->sfree(arg); memory->sfree(infiles); + delete variable; } /* ---------------------------------------------------------------------- @@ -133,19 +132,28 @@ void Input::file() while (1) { // read a line from input script - // if line ends in continuation char '&', concatenate next line(s) // n = length of line including str terminator, 0 if end of file - // m = position of last printable char in line or -1 if blank line + // if line ends in continuation char '&', concatenate next line if (me == 0) { m = 0; while (1) { - if (fgets(&line[m],MAXLINE-m,infile) == NULL) n = 0; - else n = strlen(line) + 1; - if (n == 0) break; - m = n-2; + if (maxline-m < 2) reallocate(line,maxline,0); + if (fgets(&line[m],maxline-m,infile) == NULL) { + if (m) n = strlen(line) + 1; + else n = 0; + break; + } + m = strlen(line); + if (line[m-1] != '\n') continue; + + m--; while (m >= 0 && isspace(line[m])) m--; - if (m < 0 || line[m] != '&') break; + if (m < 0 || line[m] != '&') { + line[m+1] = '\0'; + n = m+2; + break; + } } } @@ -168,16 +176,9 @@ void Input::file() continue; } + if (n > maxline) reallocate(line,maxline,n); MPI_Bcast(line,n,MPI_CHAR,0,world); - // if n = MAXLINE, line is too long - - if (n == MAXLINE) { - char str[MAXLINE+32]; - sprintf(str,"Input line too long: %s",line); - error->all(FLERR,str); - } - // echo the command unless scanning for label if (me == 0 && label_active == 0) { @@ -198,7 +199,7 @@ void Input::file() // execute the command if (execute_command()) { - char str[MAXLINE]; + char str[maxline+32]; sprintf(str,"Unknown command: %s",line); error->all(FLERR,str); } @@ -260,7 +261,7 @@ char *Input::one(const char *single) // execute the command and return its name if (execute_command()) { - char str[MAXLINE]; + char str[maxline+32]; sprintf(str,"Unknown command: %s",line); error->all(FLERR,str); } @@ -269,7 +270,7 @@ char *Input::one(const char *single) } /* ---------------------------------------------------------------------- - parse copy of command line + parse copy of command line by inserting string terminators strip comment = all chars from # on replace all $ via variable substitution command = first word @@ -280,8 +281,10 @@ char *Input::one(const char *single) void Input::parse() { - // make a copy to work on + // duplicate line into copy string to break into words + int n = strlen(line) + 1; + if (n > maxcopy) reallocate(copy,maxcopy,n); strcpy(copy,line); // strip any # comment by replacing it with 0 @@ -302,16 +305,16 @@ void Input::parse() // perform $ variable substitution (print changes) // except if searching for a label since earlier variable may not be defined - if (!label_active) substitute(copy,1); + if (!label_active) substitute(copy,work,maxcopy,maxwork,1); - // command = 1st arg + // command = 1st arg in copy string char *next; command = nextword(copy,&next); if (command == NULL) return; - // point arg[] at each subsequent arg - // nextword() inserts zeroes in copy to delimit args + // point arg[] at each subsequent arg in copy string + // nextword() inserts string terminators into copy string to delimit args // nextword() treats text between single/double quotes as one arg narg = 0; @@ -363,23 +366,29 @@ char *Input::nextword(char *str, char **next) /* ---------------------------------------------------------------------- substitute for $ variables in str and return it - str assumed to be long enough to hold expanded version + reallocate str/str2 to hold expanded version if necessary & reset max1/max2 print updated string if flag is set and not searching for label + label_active will be 0 if called from external class ------------------------------------------------------------------------- */ -void Input::substitute(char *str, int flag) +void Input::substitute(char *&str, char *&str2, int &max1, int &max2, int flag) { - // use work[] as scratch space to expand str, then copy back to str + // use str2 as scratch space to expand str, then copy back to str + // reallocate str and str2 as necessary // do not replace $ inside single/double quotes // var = pts at variable name, ended by NULL // if $ is followed by '{', trailing '}' becomes NULL // else $x becomes x followed by NULL // beyond = pts at text following variable + int n; char *var,*value,*beyond; char quote = '\0'; char *ptr = str; + n = strlen(str) + 1; + if (n > max2) reallocate(str2,max2,n); + while (*ptr) { if (*ptr == '$' && !quote) { if (*(ptr+1) == '{') { @@ -399,14 +408,13 @@ void Input::substitute(char *str, int flag) if (value == NULL) error->one(FLERR,"Substitution for illegal variable"); *ptr = '\0'; - strcpy(work,str); - if (strlen(work)+strlen(value) >= MAXLINE) - error->one(FLERR,"Input line too long after variable substitution"); - strcat(work,value); - if (strlen(work)+strlen(beyond) >= MAXLINE) - error->one(FLERR,"Input line too long after variable substitution"); - strcat(work,beyond); - strcpy(str,work); + strcpy(str2,str); + n = strlen(str2) + strlen(value) + strlen(beyond) + 1; + if (n > max1) reallocate(str,max1,n); + if (n > max2) reallocate(str2,max2,n); + strcat(str2,value); + strcat(str2,beyond); + strcpy(str,str2); ptr += strlen(value); if (flag && me == 0 && label_active == 0) { if (echo_screen && screen) fprintf(screen,"%s",str); @@ -420,6 +428,21 @@ void Input::substitute(char *str, int flag) } } +/* ---------------------------------------------------------------------- + rellocate a string + if n > 0: set max >= n in increments of DELTALINE + else just increment max by DELTALINE +------------------------------------------------------------------------- */ + +void Input::reallocate(char *&str, int &max, int n) +{ + if (n) { + while (n > max) max += DELTALINE; + } else max += DELTALINE; + + str = (char *) memory->srealloc(str,max*sizeof(char),"input:str"); +} + /* ---------------------------------------------------------------------- process a single parsed command return 0 if successful, -1 if did not recognize command @@ -565,13 +588,14 @@ void Input::ifthenelse() // in case expression was enclosed in quotes // must substitute on copy of arg else will step on subsequent args - char *scopy = new char[MAXLINE]; - strcpy(scopy,arg[0]); - substitute(scopy,0); + int n = strlen(arg[0]) + 1; + if (n > maxline) reallocate(line,maxline,n); + strcpy(line,arg[0]); + substitute(line,work,maxline,maxwork,0); // evaluate Boolean expression for "if" - double btest = variable->evaluate_boolean(scopy); + double btest = variable->evaluate_boolean(line); // bound "then" commands @@ -606,17 +630,13 @@ void Input::ifthenelse() for (int i = 0; i < ncommands; i++) delete [] commands[i]; delete [] commands; - delete [] scopy; return; } // done if no "elif" or "else" - if (iarg == narg) { - delete [] scopy; - return; - } + if (iarg == narg) return; // check "elif" or "else" until find commands to execute // substitute for variables and evaluate Boolean expression for "elif" @@ -626,9 +646,11 @@ void Input::ifthenelse() while (1) { if (iarg+2 > narg) error->all(FLERR,"Illegal if command"); if (strcmp(arg[iarg],"elif") == 0) { - strcpy(scopy,arg[iarg+1]); - substitute(scopy,0); - btest = variable->evaluate_boolean(scopy); + n = strlen(arg[iarg+1]) + 1; + if (n > maxline) reallocate(line,maxline,n); + strcpy(line,arg[iarg+1]); + substitute(line,work,maxline,maxwork,0); + btest = variable->evaluate_boolean(line); first = iarg+2; } else { btest = 1.0; @@ -664,7 +686,6 @@ void Input::ifthenelse() for (int i = 0; i < ncommands; i++) delete [] commands[i]; delete [] commands; - delete [] scopy; return; } @@ -801,12 +822,18 @@ void Input::print() { if (narg != 1) error->all(FLERR,"Illegal print command"); + // copy 1st arg back into line (copy is being used) + // check maxline since arg[0] could have been exanded by variables // substitute for $ variables (no printing) and print arg - substitute(arg[0],0); + int n = strlen(arg[0]) + 1; + if (n > maxline) reallocate(line,maxline,n); + strcpy(line,arg[0]); + substitute(line,work,maxline,maxwork,0); + if (me == 0) { - if (screen) fprintf(screen,"%s\n",arg[0]); - if (logfile) fprintf(logfile,"%s\n",arg[0]); + if (screen) fprintf(screen,"%s\n",line); + if (logfile) fprintf(logfile,"%s\n",line); } } @@ -850,15 +877,20 @@ void Input::shell() if (me == 0) for (int i = 1; i < narg; i++) rmdir(arg[i]); - // use work to concat args back into one string separated by spaces + // use work string to concat args back into one string separated by spaces // invoke string in shell via system() } else { + int n = 0; + for (int i = 0; i < narg; i++) n += strlen(arg[i]) + 1; + if (n > maxwork) reallocate(work,maxwork,n); + strcpy(work,arg[0]); for (int i = 1; i < narg; i++) { strcat(work," "); strcat(work,arg[i]); } + if (me == 0) system(work); } } diff --git a/src/input.h b/src/input.h index fb0fce2d15402bc366c51cf61d754a4f1e55aade..36e6c0c0dd1968caa3883793bae642efe0b271a7 100644 --- a/src/input.h +++ b/src/input.h @@ -30,13 +30,15 @@ class Input : protected Pointers { void file(); // process all input void file(const char *); // process an input script char *one(const char *); // process a single command - void substitute(char *, int); // substitute for variables in a string + void substitute(char *&, char *&, int &, int &, int); + // substitute for variables in a string private: int me; // proc ID char *command; // ptr to current command int maxarg; // max # of args in arg - char *line,*copy,*work; // input line & copy of it + char *line,*copy,*work; // input line & copy and work string + int maxline,maxcopy,maxwork; // max lengths of char strings int echo_screen; // 0 = no, 1 = yes int echo_log; // 0 = no, 1 = yes int nfile,maxfile; // current # and max # of open input files @@ -46,9 +48,10 @@ class Input : protected Pointers { FILE **infiles; // list of open input files - void parse(); // parse an input text line - char *nextword(char *, char **); // find next word in string, with quotes - int execute_command(); // execute a single command + void parse(); // parse an input text line + char *nextword(char *, char **); // find next word in string with quotes + void reallocate(char *&, int &, int); // reallocate a char string + int execute_command(); // execute a single command void clear(); // input script commands void echo(); diff --git a/src/thermo.cpp b/src/thermo.cpp index 763e1a175dd69955f5fdfef3d6ecb555470cab7b..0909153adb563fc75331aa466599c07bf1a7938d 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -67,7 +67,6 @@ enum{SCALAR,VECTOR,ARRAY}; #define INVOKED_VECTOR 2 #define INVOKED_ARRAY 4 -#define MAXLINE 32768 // make this 4x longer than Input::MAXLINE #define DELTA 8 /* ---------------------------------------------------------------------- */ @@ -89,12 +88,19 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) lostbefore = 0; flushflag = 0; + // line string used for 3 tasks + // concat of custom style args + // one-time thermo output of header line + // each line of numeric thermo output + // 256 = extra for ONE or MULTI string or multi formatting + // 32 = max per-arg chars in header or numeric output + + line = new char[256+32*narg]; + // set style and corresponding lineflag // custom style builds its own line of keywords // customize a new thermo style by adding to if statement - line = new char[MAXLINE]; - if (strcmp(style,"one") == 0) { strcpy(line,ONE); } else if (strcmp(style,"multi") == 0) { @@ -337,9 +343,6 @@ void Thermo::compute(int flag) } } - // kludge for RedStorm timing issue - // if (ntimestep == 100) return; - // print line to screen and logfile if (me == 0) {