diff --git a/src/input.cpp b/src/input.cpp index 7201b69578..dc2c140fd7 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -15,6 +15,7 @@ #include "stdio.h" #include "stdlib.h" #include "string.h" +#include "ctype.h" #include "input.h" #include "style_command.h" #include "universe.h" @@ -117,20 +118,24 @@ Input::~Input() void Input::file() { - int n; + int m,n; while (1) { - // read one line from input script + // read a line from input script // if line ends in continuation char '&', concatenate next line(s) - // n = str length of line - + // 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 (me == 0) { - if (fgets(line,MAXLINE,infile) == NULL) n = 0; - else n = strlen(line) + 1; - while (n >= 3 && line[n-3] == '&') { - if (fgets(&line[n-3],MAXLINE-n+3,infile) == NULL) n = 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; + while (m >= 0 && isspace(line[m])) m--; + if (m < 0 || line[m] != '&') break; } } @@ -516,7 +521,10 @@ void Input::echo() void Input::ifthenelse() { - if (narg != 5 && narg != 7) error->all("Illegal if command"); + if (narg < 5) error->all("Illegal if command"); + + // flag = 0 for "then" + // flag = 1 for "else" int flag = 0; if (strcmp(arg[1],"==") == 0) { @@ -533,16 +541,35 @@ void Input::ifthenelse() if (atof(arg[0]) >= atof(arg[2])) flag = 1; } else error->all("Illegal if command"); + // first = arg index of first "then" or "else" command + // last = arg index of last "then" or "else" command + + int iarg,first,last; + if (strcmp(arg[3],"then") != 0) error->all("Illegal if command"); - if (narg == 7 && strcmp(arg[5],"else") != 0) - error->all("Illegal if command"); + if (flag) { + iarg = first = 4; + while (iarg < narg && strcmp(arg[iarg],"else") != 0) iarg++; + last = iarg-1; + } else { + iarg = 4; + while (iarg < narg && strcmp(arg[iarg],"else") != 0) iarg++; + if (iarg == narg) error->all("Illegal if command"); + first = iarg+1; + last = narg-1; + } - char str[128] = "\0"; - if (flag) strcpy(str,arg[4]); - else if (narg == 7) strcpy(str,arg[6]); - strcat(str,"\n"); + if (last-first < 0) error->all("Illegal if command"); - if (strlen(str) > 1) char *tmp = one(str); + // execute the list of commands + + char str[256]; + for (int i = first; i <= last; i++) { + if (strlen(arg[i]) == 0) error->all("Illegal if command"); + strcpy(str,arg[i]); + strcat(str,"\n"); + char *tmp = one(str); + } } /* ---------------------------------------------------------------------- */ @@ -638,15 +665,22 @@ void Input::next_command() void Input::print() { - if (narg != 1) error->all("Illegal print command"); + if (narg == 0) error->all("Illegal print command"); // substitute for $ variables (no printing) + // print args one at a time, separated by spaces - substitute(arg[0],0); + for (int i = 0; i < narg; i++) { + substitute(arg[i],0); + if (me == 0) { + if (screen) fprintf(screen,"%s ",arg[i]); + if (logfile) fprintf(logfile,"%s ",arg[i]); + } + } if (me == 0) { - if (screen) fprintf(screen,"%s\n",arg[0]); - if (logfile) fprintf(logfile,"%s\n",arg[0]); + if (screen) fprintf(screen,"\n"); + if (logfile) fprintf(logfile,"\n"); } } diff --git a/src/run.cpp b/src/run.cpp index ef38951736..029761a895 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -55,7 +55,7 @@ void Run::command(int narg, char **arg) int preflag = 1; int postflag = 1; int nevery = 0; - char *commandstr = NULL; + int first,last,ncommands; int iarg = 1; while (iarg < narg) { @@ -86,24 +86,18 @@ void Run::command(int narg, char **arg) else error->all("Illegal run command"); iarg += 2; - // generate commandstr if last arg is not NULL - // commandstr = concatenation of all remaining args - // if an arg has spaces, enclose in quotes since input parser removed them + // all remaining args are commands + // first,last = arg index of first/last commands + // set ncommands = 0 if single command and it is NULL } else if (strcmp(arg[iarg],"every") == 0) { if (iarg+3 > narg) error->all("Illegal run command"); nevery = atoi(arg[iarg+1]); if (nevery <= 0) error->all("Illegal run command"); - if (strcmp(arg[iarg+2],"NULL") != 0) { - commandstr = new char[MAXLINE]; - commandstr[0] = '\0'; - for (int jarg = iarg+2; jarg < narg; jarg++) { - if (strchr(arg[jarg],' ')) strcat(commandstr,"\""); - strcat(commandstr,arg[jarg]); - if (strchr(arg[jarg],' ')) strcat(commandstr,"\""); - strcat(commandstr," "); - } - } + first = iarg+2; + last = narg-1; + ncommands = last-first + 1; + if (ncommands == 1 && strcmp(arg[first],"NULL") == 0) ncommands = 0; iarg = narg; } else error->all("Illegal run command"); } @@ -112,6 +106,21 @@ void Run::command(int narg, char **arg) if (uptoflag) nsteps -= update->ntimestep; + // if nevery, make copies of arg strings that are commands + // required because re-parsing commands during run will wipe out args + + char **commands = NULL; + if (nevery && ncommands > 0) { + commands = new char*[ncommands]; + ncommands = 0; + for (int i = first; i <= last; i++) { + int n = strlen(arg[i]) + 1; + commands[ncommands] = new char[n]; + strcpy(commands[ncommands],arg[i]); + ncommands++; + } + } + // error check if (uptoflag && nsteps < 0) @@ -156,7 +165,7 @@ void Run::command(int narg, char **arg) Finish finish(lmp); finish.end(postflag); - // perform multiple runs optionally interleaved with invocation of a command + // perform multiple runs optionally interleaved with invocation command(s) // use start/stop to set begin/end step // if pre or 1st iteration of multiple runs, do System init/setup, // else just init timer and setup output @@ -195,12 +204,13 @@ void Run::command(int narg, char **arg) if (postflag || nleft <= nsteps) finish.end(1); else finish.end(0); - // command string may invoke computes via command with variable - // so wrap with clearstep/addstep + // wrap command invocation with clearstep/addstep + // since a command may invoke computes via variables - if (commandstr) { + if (ncommands) { modify->clearstep_compute(); - char *command = input->one(commandstr); + for (int i = 0; i < ncommands; i++) + char *command = input->one(commands[i]); modify->addstep_compute(update->ntimestep + nevery); } @@ -212,5 +222,9 @@ void Run::command(int narg, char **arg) update->whichflag = 0; update->firststep = update->laststep = 0; update->beginstep = update->endstep = 0; - delete [] commandstr; + + if (commands) { + for (int i = 0; i < ncommands; i++) delete [] commands[i]; + delete [] commands; + } }