git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10310 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2013-07-23 19:01:37 +00:00
parent 4b21fc7c81
commit cb7f385d43
9 changed files with 245 additions and 226 deletions

View File

@ -82,6 +82,17 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
variable = new Variable(lmp);
// fill map with commands listed in style_command.h
command_map = new std::map<std::string,CommandCreator>();
#define COMMAND_CLASS
#define CommandStyle(key,Class) \
(*command_map)[#key] = &command_creator<Class>;
#include "style_command.h"
#undef CommandStyle
#undef COMMAND_CLASS
// process command-line args
// check for args "-var" and "-echo"
// caller has already checked that sufficient arguments exist
@ -101,7 +112,7 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
echo();
arg = tmp;
iarg += 2;
} else iarg++;
} else iarg++;
}
}
@ -129,13 +140,13 @@ Input::~Input()
void Input::file()
{
int m,n;
while (1) {
// read a line from input script
// n = length of line including str terminator, 0 if end of file
// if line ends in continuation char '&', concatenate next line
if (me == 0) {
m = 0;
while (1) {
@ -147,7 +158,7 @@ void Input::file()
}
m = strlen(line);
if (line[m-1] != '\n') continue;
m--;
while (m >= 0 && isspace(line[m])) m--;
if (m < 0 || line[m] != '&') {
@ -157,13 +168,13 @@ void Input::file()
}
}
}
// bcast the line
// if n = 0, end-of-file
// error if label_active is set, since label wasn't encountered
// if original input file, code is done
// else go back to previous input file
MPI_Bcast(&n,1,MPI_INT,0,world);
if (n == 0) {
if (label_active) error->all(FLERR,"Label wasn't found in input script");
@ -176,29 +187,29 @@ void Input::file()
if (me == 0) infile = infiles[nfile-1];
continue;
}
if (n > maxline) reallocate(line,maxline,n);
MPI_Bcast(line,n,MPI_CHAR,0,world);
// echo the command unless scanning for label
if (me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s\n",line);
if (echo_log && logfile) fprintf(logfile,"%s\n",line);
}
// parse the line
// if no command, skip to next line in input script
parse();
if (command == NULL) continue;
// if scanning for label, skip command unless it's a label command
if (label_active && strcmp(command,"label") != 0) continue;
// execute the command
if (execute_command()) {
char *str = new char[maxline+32];
sprintf(str,"Unknown command: %s",line);
@ -210,18 +221,18 @@ void Input::file()
/* ----------------------------------------------------------------------
process all input from filename
called from library interface
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void Input::file(const char *filename)
{
// error if another nested file still open, should not be possible
// open new filename and set infile, infiles[0], nfile
// call to file() will close filename and decrement nfile
if (me == 0) {
if (nfile > 1)
error->one(FLERR,"Invalid use of library file() function");
infile = fopen(filename,"r");
if (infile == NULL) {
char str[128];
@ -231,46 +242,46 @@ void Input::file(const char *filename)
infiles[0] = infile;
nfile = 1;
}
file();
}
/* ----------------------------------------------------------------------
copy command in single to line, parse and execute it
return command name to caller
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
char *Input::one(const char *single)
{
int n = strlen(single) + 1;
if (n > maxline) reallocate(line,maxline,n);
strcpy(line,single);
// echo the command unless scanning for label
if (me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s\n",line);
if (echo_log && logfile) fprintf(logfile,"%s\n",line);
}
// parse the line
// if no command, just return NULL
parse();
if (command == NULL) return NULL;
// if scanning for label, skip command unless it's a label command
if (label_active && strcmp(command,"label") != 0) return NULL;
// execute the command and return its name
if (execute_command()) {
char *str = new char[maxline+32];
sprintf(str,"Unknown command: %s",line);
error->all(FLERR,str);
}
return command;
}
@ -282,19 +293,19 @@ char *Input::one(const char *single)
narg = # of args
arg[] = individual args
treat text between single/double quotes as one arg
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void Input::parse()
{
// 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
// do not strip # inside single/double quotes
char quote = '\0';
char *ptr = copy;
while (*ptr) {
@ -306,22 +317,22 @@ void Input::parse()
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
ptr++;
}
// perform $ variable substitution (print changes)
// except if searching for a label since earlier variable may not be defined
if (!label_active) substitute(copy,work,maxcopy,maxwork,1);
// command = 1st arg in copy string
char *next;
command = nextword(copy,&next);
if (command == NULL) return;
// 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;
ptr = next;
while (ptr) {
@ -341,20 +352,20 @@ void Input::parse()
insert 0 at end of word
ignore leading whitespace
treat text between single/double quotes as one arg
matching quote must be followed by whitespace char if not end of string
strip quotes from returned word
matching quote must be followed by whitespace char if not end of string
strip quotes from returned word
return ptr to start of word
return next = ptr after word or NULL if word ended with 0
return NULL if no word in string
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
char *Input::nextword(char *str, char **next)
{
char *start,*stop;
start = &str[strspn(str," \t\n\v\f\r")];
if (*start == '\0') return NULL;
if (*start == '"' || *start == '\'') {
stop = strchr(&start[1],*start);
if (!stop) error->all(FLERR,"Unbalanced quotes in input line");
@ -362,7 +373,7 @@ char *Input::nextword(char *str, char **next)
error->all(FLERR,"Input line quote not followed by whitespace");
start++;
} else stop = &start[strcspn(start," \t\n\v\f\r")];
if (*stop == '\0') *next = NULL;
else *next = stop+1;
*stop = '\0';
@ -374,7 +385,7 @@ char *Input::nextword(char *str, char **next)
reallocate str/str2 to hold expanded version if necessary & reset max/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, char *&str2, int &max, int &max2, int flag)
{
@ -385,61 +396,61 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
// if $ is followed by '{', trailing '}' becomes NULL
// else $x becomes x followed by NULL
// beyond = points to text following variable
int i,n,paren_count;
char immediate[256];
char *var,*value,*beyond;
char quote = '\0';
char *ptr = str;
n = strlen(str) + 1;
if (n > max2) reallocate(str2,max2,n);
*str2 = '\0';
char *ptr2 = str2;
while (*ptr) {
// variable substitution
if (*ptr == '$' && !quote) {
// value = ptr to expanded variable
// variable name between curly braces, e.g. ${a}
if (*(ptr+1) == '{') {
var = ptr+2;
i = 0;
while (var[i] != '\0' && var[i] != '}') i++;
if (var[i] == '\0') error->one(FLERR,"Invalid variable name");
var[i] = '\0';
beyond = ptr + strlen(var) + 3;
value = variable->retrieve(var);
// immediate variable between parenthesis, e.g. $(1/2)
// immediate variable between parenthesis, e.g. $(1/2)
} else if (*(ptr+1) == '(') {
var = ptr+2;
paren_count = 0;
i = 0;
while (var[i] != '\0' && !(var[i] == ')' && paren_count == 0)) {
switch (var[i]) {
case '(': paren_count++; break;
case ')': paren_count--; break;
default: ;
case '(': paren_count++; break;
case ')': paren_count--; break;
default: ;
}
i++;
}
if (var[i] == '\0') error->one(FLERR,"Invalid immediate variable");
var[i] = '\0';
beyond = ptr + strlen(var) + 3;
sprintf(immediate,"%.20g",variable->compute_equal(var));
value = immediate;
// single character variable name, e.g. $a
// single character variable name, e.g. $a
} else {
var = ptr;
var[0] = var[1];
@ -447,40 +458,40 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
beyond = ptr + 2;
value = variable->retrieve(var);
}
if (value == NULL) error->one(FLERR,"Substitution for illegal variable");
// check if storage in str2 needs to be expanded
// re-initialize ptr and ptr2 to the point beyond the variable.
n = strlen(str2) + strlen(value) + strlen(beyond) + 1;
if (n > max2) reallocate(str2,max2,n);
strcat(str2,value);
ptr2 = str2 + strlen(str2);
ptr = beyond;
// output substitution progress if requested
if (flag && me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s%s\n",str2,beyond);
if (echo_log && logfile) fprintf(logfile,"%s%s\n",str2,beyond);
}
continue;
}
if (*ptr == quote) quote = '\0';
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
// copy current character into str2
*ptr2++ = *ptr++;
*ptr2 = '\0';
}
// set length of input str to length of work str2
// copy work string back to input str
if (max2 > max) reallocate(str,max,max2);
strcpy(str,str2);
}
@ -489,26 +500,26 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
rellocate a string
if n > 0: set max >= n in increments of DELTALINE
if n = 0: 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
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
int Input::execute_command()
{
int flag = 1;
if (!strcmp(command,"clear")) clear();
else if (!strcmp(command,"echo")) echo();
else if (!strcmp(command,"if")) ifthenelse();
@ -522,7 +533,7 @@ int Input::execute_command()
else if (!strcmp(command,"quit")) quit();
else if (!strcmp(command,"shell")) shell();
else if (!strcmp(command,"variable")) variable_command();
else if (!strcmp(command,"angle_coeff")) angle_coeff();
else if (!strcmp(command,"angle_style")) angle_style();
else if (!strcmp(command,"atom_modify")) atom_modify();
@ -574,32 +585,37 @@ int Input::execute_command()
else if (!strcmp(command,"undump")) undump();
else if (!strcmp(command,"unfix")) unfix();
else if (!strcmp(command,"units")) units();
else flag = 0;
// return if command was listed above
if (flag) return 0;
// check if command is added via style.h
if (0) return 0; // dummy line to enable else-if macro expansion
#define COMMAND_CLASS
#define CommandStyle(key,Class) \
else if (strcmp(command,#key) == 0) { \
Class key(lmp); \
key.command(narg,arg); \
return 0; \
// invoke commands added via style_command.h
if (command_map->find(command) != command_map->end()) {
CommandCreator command_creator = (*command_map)[command];
command_creator(lmp,narg,arg);
return 0;
}
#include "style_command.h"
#undef COMMAND_CLASS
// unrecognized command
return -1;
}
/* ----------------------------------------------------------------------
one instance per command in style_command.h
------------------------------------------------------------------------- */
template <typename T>
void Input::command_creator(LAMMPS *lmp, int narg, char **arg)
{
T cmd(lmp);
cmd.command(narg,arg);
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */