예제 #1
0
/* Parse bond data from line. 
   Return MOLFILE_SUCCESS, if data was sucessfully parsed, 
   MOLFILE_ERROR if an error occured. */
static int vtf_parse_bond(char *line, vtf_data *d) {
  char *s;
  int n;
  int from, to, aid, bid;

  s = line;

  while (1) {
    if (sscanf(s, "%u::%u%n", &from, &to, &n) == 2) {
      /* chain specifier */
      if (from > to) {
	vtf_error("bad chain specifier (from > to):", s); 
	return MOLFILE_ERROR;
      }
      bid = d->nbonds;
      d->nbonds += to-from;
      d->from = realloc(d->from, d->nbonds*sizeof(int));
      d->to = realloc(d->to, d->nbonds*sizeof(int));
      /* TODO: error handling */
      for (aid = from; aid < to; aid++) {
	/*printf("creating bond from %d to %d\n", aid, aid+1);*/
	d->from[bid] = aid+1;
	d->to[bid] = aid+2;
	bid++;
      }
    } else if (sscanf(s, "%u:%u%n", &from, &to, &n) == 2) {
      /* single bond specifier */
      d->nbonds += 1;
      d->from = realloc(d->from, d->nbonds*sizeof(int));
      d->to = realloc(d->to, d->nbonds*sizeof(int));
      /* TODO: error handling */
      d->from[d->nbonds-1] = from+1;
      d->to[d->nbonds-1] = to+1;
    } else {
      vtf_error("bad bond specifier", s);
      return MOLFILE_ERROR;
    }

    s += n;
    
    /* if there is no more to parse, break */
    if (strlen(s) == 0) break;
    
    /* otherwise the next char should be a ',' */
    if (s[0] != ',') {
      vtf_error("bad bond specifier in line", line);
      return MOLFILE_ERROR;
    }
    /* skip the ',' */
    s++;
  }

  return MOLFILE_SUCCESS;
}
예제 #2
0
static int vtf_read_bonds(void *data, 
			  int *nbonds, 
			  int **from, 
			  int **to,
			  float **bondorder, 
			  int **bondtype, 
			  int *nbondtypes, 
			  char ***bondtypename) {
  vtf_data *d;
  if (!data) {
    vtf_error("Internal error: data==NULL in vtf_read_bonds", 0);
    return MOLFILE_ERROR;
  }

  d = (vtf_data*)data;

  *nbonds = d->nbonds;
  *from = d->from;
  *to = d->to;
  *bondorder = NULL;
  *bondtype = NULL;
  *nbondtypes = 0;
  *bondtypename = NULL;

  return MOLFILE_SUCCESS;
}
예제 #3
0
/* Parse periodic boundary condition data from line. Called by
   vtf_parse_structure().  Return MOLFILE_SUCCESS, if data was
   sucessfully parsed, MOLFILE_ERROR if an error occured. */
static int vtf_parse_pbc(char *line, vtf_data *d) {
  char *s;
  int n = 0;

  if (sscanf(line, " %f %f %f%n", &d->A, &d->B, &d->C, &n) < 3) {
    s = line;
    vtf_error("Couldn't parse unit cell dimensions", s);
    return MOLFILE_ERROR;
  }
  s = line + n;

  n = sscanf(s, " %f %f %f", &d->alpha, &d->beta, &d->gamma);
  if (n > 0 && n < 3) {
    vtf_error("Couldn't parse unit cell angles", line);
    return MOLFILE_ERROR;
  }
  return MOLFILE_SUCCESS;
} 
예제 #4
0
/* Parse timestep command from line. 
   Return MOLFILE_SUCCESS, if it was sucessfully parsed, 
   MOLFILE_ERROR if an error occured. */
static int vtf_parse_timestep(char *line, vtf_data *d) {
  if (strlen(line) == 0) {
    d->timestep_mode = TIMESTEP_ORDERED;
  } else {
    switch (tolower(line[0])) {
    case 'o': { d->timestep_mode = TIMESTEP_ORDERED; break; }
    case 'i': { d->timestep_mode = TIMESTEP_INDEXED; break; }
    default: {
      vtf_error("bad timestep line", line);
      return MOLFILE_ERROR;
    }
    }
  }
  return MOLFILE_SUCCESS;
}
예제 #5
0
static int vtf_read_next_timestep(void *data, 
				  int natoms, 
				  molfile_timestep_t *ts) {
  vtf_data *d;
  char *line;
  static char s[255];
  float x,y,z;
  unsigned int aid;
  int n;

  if (data == NULL) {
    vtf_error("Internal error: data==NULL in vtf_read_next_timestep", 0);
    return MOLFILE_ERROR;
  }

  if (natoms <= 0) {
    vtf_error("Internal error: natoms <= 0 in vtf_read_next_timestep", 0);
    return MOLFILE_ERROR;
  }

  errno = 0;

  d = (vtf_data*)data;

  aid = 0;

  if (feof(d->file)) return MOLFILE_EOF;

  if (d->coords == NULL) {
    /* initialize coords */
    d->coords = malloc(natoms*3*sizeof(float));
    /* TODO: error handling */
    for (n = 0; n < natoms*3; n++)
      d->coords[n] = 0.0;
  } 
  
  /* read in the data, until the next timestep or EOF is reached */
  do {
    line = vtf_getline(d->file);

    if (line == NULL) {
      if (errno != 0) {
	perror("vtfplugin");
	return MOLFILE_ERROR;
      }
      break;
    } 

    /* At the beginning of a vcf file, skip a timestep line */
    if (d->timestep_mode == TIMESTEP_VCFSTART) {
      switch (tolower(line[0])) {
      case 'c': 
      case 't':
	/* Remove the "timestep" or "coordinates" keyword */
	sscanf(line, "%255s %n", s, &n);
	line += n;
      case 'i': 
      case 'o': 
	if (vtf_parse_timestep(line, d) != MOLFILE_SUCCESS)
	  return MOLFILE_ERROR;
	line = vtf_getline(d->file);
	break;
      default:
	/* if this is already a coordinate line, expect an ordered block */
	d->timestep_mode = TIMESTEP_ORDERED;
      }
    }

    /* parse timestep data */
    if (d->timestep_mode == TIMESTEP_ORDERED 
	&& sscanf(line, " %f %f %f", &x, &y, &z) == 3) {
      if (aid < natoms) {
	d->coords[aid*3] = x;
	d->coords[aid*3+1] = y;
	d->coords[aid*3+2] = z;
	aid++;
      } else {
	vtf_error("too many atom coordinates in ordered timestep block", line);
	return MOLFILE_ERROR;
      }
    } else if (d->timestep_mode == TIMESTEP_INDEXED 
	       && sscanf(line, " %u %f %f %f", 
			 &aid, &x, &y, &z) == 4) {
      if (aid < natoms) {
	d->coords[aid*3] = x;
	d->coords[aid*3+1] = y;
	d->coords[aid*3+2] = z;
      } else {
	vtf_error("atom id too large in indexed timestep block", line);
	return MOLFILE_ERROR;
      }
    } else switch (tolower(line[0])) {
      /* PBC/UNITCELL RECORD */
    case 'u':
    case 'p': {
      /* Remove the "pbc" or "unitcell" keyword */
      sscanf(line, "%255s %n", s, &n);
      line += n;
      if (vtf_parse_pbc(line, d) != MOLFILE_SUCCESS) 
	return MOLFILE_ERROR;
      break;
    }
      
      /* TIMESTEP RECORD*/
    case 'c': 
    case 't': {
      /* Remove the "timestep" or "coordinates" keyword */
      sscanf(line, "%255s %n", s, &n);
      line += n;
    }
    case 'i': 
    case 'o': { 
      if (vtf_parse_timestep(line, d) != MOLFILE_SUCCESS)
	return MOLFILE_ERROR;
      line = NULL; /* indicate end of this timestep */
      break;
    }

    default: { 
      if (d->timestep_mode == TIMESTEP_INDEXED)
	vtf_error("unknown line in indexed timestep block", line);
      else
	vtf_error("unknown line in ordered timestep block", line);
      return MOLFILE_ERROR;
    }
    }

    if (line == NULL) break;
  } while (1);

  if (ts != NULL) {
    /* copy the ts data */
    ts->A = d->A;
    ts->B = d->B;
    ts->C = d->C;
    ts->alpha = d->alpha;
    ts->beta = d->beta;
    ts->gamma = d->gamma;
    memcpy(ts->coords, d->coords, natoms*3*sizeof(float));
    ts->velocities = NULL;
    ts->physical_time = 0.0;
  }
  
  return MOLFILE_SUCCESS;
}
예제 #6
0
static void vtf_parse_structure(vtf_data *d) {
  char *line;			/* next line in the file */
  char s[255];
  int n;
  
  /* initialize the default atom */
  strcpy(default_atom.name, "X");
  strcpy(default_atom.type, "X");
  strcpy(default_atom.resname, "X");
  default_atom.resid = 0;
  strcpy(default_atom.segid, "");
  strcpy(default_atom.chain, "");

  strcpy(default_atom.altloc, "");
  strcpy(default_atom.insertion, "");
  default_atom.occupancy = 1.0;
  default_atom.bfactor = 1.0;
  default_atom.mass = 1.0;
  default_atom.charge = 0.0;
  default_atom.radius = 1.0;

  do {
    line = vtf_getline(d->file);
    if (line == NULL) break;
    switch (tolower(line[0])) {
      /* ATOM RECORD */
    case 'a': {
      /* Remove the "atom" keyword" */
      sscanf(line, "%255s %n", s, &n);
      line += n;
    }
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':	
    case 'd': { 
      /* parse atom */
      d->return_code = vtf_parse_atom(line, d);
      break; 
    }

      /* BOND RECORD */
    case 'b': {
      /* Remove the "bond" keyword" */
      sscanf(line, "%255s %n", s, &n);
      line += n;
      d->return_code = vtf_parse_bond(line, d);
      break;
    }

      /* PBC/UNITCELL RECORD */
    case 'u':
    case 'p': {
      /* Remove the "pbc" or "unitcell" keyword */
      sscanf(line, "%255s %n", s, &n);
      line += n;
      d->return_code = vtf_parse_pbc(line, d);
      break;
    }

      /* TIMESTEP RECORD*/
    case 'c': 
    case 't': {
      /* Remove the "timestep" or "coordinates" keyword */
      sscanf(line, "%255s %n", s, &n);
      line += n;
      
    }
    case 'i': 
    case 'o': { 
      d->return_code = vtf_parse_timestep(line, d);
      line = NULL; /* indicate the end of the structure block */
      break; 
    }

      /* UNKNOWN RECORD */
    default: {
      vtf_error("unknown line type", line);
      d->return_code = MOLFILE_ERROR;
      break;
    }
    }
  } while (line != NULL && 
	   d->return_code == MOLFILE_SUCCESS);

  /* test if structure data was parsed */
  if (d->atoms == NULL && 
      d->return_code == MOLFILE_SUCCESS) {
    d->return_code = MOLFILE_NOSTRUCTUREDATA;
  }

  /* test whether another error has occured */
  if (errno != 0) {
    perror("vtfplugin");
    d->return_code = MOLFILE_ERROR;
  }
}
예제 #7
0
/* Parse atom data from line. 
   Return MOLFILE_SUCCESS, if data was sucessfully parsed, 
   MOLFILE_ERROR if an error occured. */
static int vtf_parse_atom(char *line, vtf_data *d) {
  static molfile_atom_t atom;
  static char aid_specifier[255];
  static char keyword[255];
  static char msg[255];
  char *s;
  int n;
  int ignorerest;
  unsigned int from, to, aid;

  atom = default_atom;
  s = line;

  /* save the aid specifier */
  if (sscanf(s, "%255s %n", aid_specifier, &n) < 1) {
    vtf_error("atom specifier is missing", line);
    return MOLFILE_ERROR;
  }
  s += n;
  ignorerest = 0;
  
  /* handle the keywords */
  while (sscanf(s, "%255s %n", keyword, &n) == 1) {
    if (ignorerest) break;
    s += n;
    switch (tolower(keyword[0])) {
    case 'n': {
      /* name */
      if (sscanf(s, "%16s %n", &atom.name, &n) < 1) {
	vtf_error("could not get name in atom record", line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 't': {
      /* type */
      if (sscanf(s, "%16s %n", &atom.type, &n) < 1) {
	vtf_error("could not get type in atom record", line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'r': {
      /* resname, resid, radius */
      if (strlen(keyword) == 1 || 
	  strncmp(keyword, "rad", 3) == 0) { 
	/* radius */
	if (sscanf(s, "%f %n", &atom.radius, &n) < 1) {
	  vtf_error("could not get radius in atom record", line);
	  return MOLFILE_ERROR;
	}
	d->optflags |= MOLFILE_RADIUS;
      } else if (strcmp(keyword, "resid") == 0) {
	/* resid */
	if (sscanf(s, "%d %n", &atom.resid, &n) < 1) {
	  vtf_error("could not get resid in atom record", line);
	  return MOLFILE_ERROR;
	}
      } else if (strcmp(keyword, "res") == 0 || 
		 strcmp(keyword, "resname") == 0) {
	/* resname */
	if (sscanf(s, "%8s %n", &atom.resname, &n) < 1) {
	  vtf_error("could not get resname in atom record", line);
	  return MOLFILE_ERROR;
	}
      } else {
	strcpy(msg, "unrecognized keyword in atom record: ");
	strncat(msg, keyword, 200);
	vtf_error(msg, line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 's': {
      /* segid */
      if (sscanf(s, "%8s %n", &atom.segid, &n) < 1) {
	vtf_error("could not get segid in atom record", line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'i': {
      /* insertion */
      if (sscanf(s, "%2s %n", &atom.insertion, &n) < 1) {
	vtf_error("could not get insertion in atom record", line);
	return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_INSERTION;
      s += n;
      break;
    }
    case 'c': {
      /* chain, charge */
      if (strlen(keyword) == 1 || 
	  strcmp(keyword, "chain") == 0) {
	if (sscanf(s, "%2s %n", &atom.chain, &n) < 1) {
	  vtf_error("could not get chain in atom record", line);
	  return MOLFILE_ERROR;
	}
      }
    } /* if "chain" is not recognized, continue with next case */
    case 'q': {
      /* q and charge */
      if (strlen(keyword) == 1 ||
	  strcmp(keyword, "charge") == 0) {
	if (sscanf(s, "%f %n", &atom.charge, &n) < 1) {
	  vtf_error("could not get charge in atom record", line);
	  return MOLFILE_ERROR;
	}
	d->optflags |= MOLFILE_CHARGE;
      } else {
	strcpy(msg, "unrecognized keyword in atom record: ");
	strncat(msg, keyword, 200);
	vtf_error(msg, line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'a': {
      /* altloc, atomicnumber */
      if (strlen(keyword)== 1 || 
	  strcmp(keyword, "atomicnumber") == 0) {
	if (sscanf(s, "%d %n", &atom.atomicnumber, &n) < 1) {
	  vtf_error("could not get atomicnumber in atom record", line);
	  return MOLFILE_ERROR;
	}
	d->optflags |= MOLFILE_ATOMICNUMBER;
      } else if (strcmp(keyword, "altloc")) {
	if (sscanf(s, "%2s %n", &atom.altloc, &n) < 1) {
	  vtf_error("could not get altloc in atom record", line);
	  return MOLFILE_ERROR;
	}
	d->optflags |= MOLFILE_ALTLOC;
      } else { 
	strcpy(msg, "unrecognized keyword in atom record: ");
	strncat(msg, keyword, 200);
	vtf_error(msg, line);
	return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'o': {
      /* occupancy */
      if (sscanf(s, "%f %n", &atom.occupancy, &n) < 1) {
	vtf_error("could not get occupancy in atom record", line);
	return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_OCCUPANCY;
      s += n;
      break;
    }
    case 'b': {
      /* bfactor */
      if (sscanf(s, "%f %n", &atom.bfactor, &n) < 1) {
	vtf_error("could not get bfactor in atom record", line);
	return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_BFACTOR;
      s += n;
      break;
    }
    case 'm': {
      /* mass */
      if (sscanf(s, "%f %n", &atom.mass, &n) < 1) {
	vtf_error("could not get mass in atom record", line);
	return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_MASS;
      s += n;
      break;
    }
    case 'u': {
      /* user data: ignore rest of the line */
      ignorerest = 1;
      break;
    }
    default: { 
      /* unrecognized */
      strcpy(msg, "unrecognized keyword in atom record: ");
      strncat(msg, keyword, 200);
      vtf_error(msg, line);
      return MOLFILE_ERROR;
    }
    }
  }

  /* handle the aid specifier */

  /* if the specifier is "default", set the default_atom */
  if (aid_specifier[0] == 'd') {
    default_atom = atom;
  } else {
    /* otherwise parse the aid specifier */
    s = aid_specifier;
    while (1) {
      from = d->natoms;
      if (sscanf(s, "%u:%u%n", &from, &to, &n) == 2) {
	/* range given */
	if (from > to) { 
	  vtf_error("bad range specifier (from > to):", s); 
	  return MOLFILE_ERROR;
	}
	d->atoms = realloc(d->atoms, (to+1)*sizeof(molfile_atom_t));
	/* TODO: error handling */
	/* fill up with default atoms */
	for (aid = d->natoms; aid < to; aid++)
	  d->atoms[aid] = default_atom;
	/* create new atoms */
	if (to+1 > d->natoms) d->natoms = to+1;
	/* TODO: error handling */
	for (aid = from; aid <= to; aid++)
	  d->atoms[aid] = atom;
      } else if (sscanf(s, "%u%n", &to, &n) == 1) {
	/* single aid given */
	d->atoms = realloc(d->atoms, (to+1)*sizeof(molfile_atom_t));
	/* TODO: error handling */
	/* fill up with default atoms */
	for (aid = d->natoms; aid < to; aid++)
	  d->atoms[aid] = default_atom;
	/* create the new atom */
	if (to+1 > d->natoms) d->natoms = to+1;
	d->atoms[to] = atom;
      } else {
	vtf_error("bad atom specifier", s);
	return MOLFILE_ERROR;
      }

      /* advance s */
      s += n;

      /* if there is no more to parse, break */
      if (strlen(s) == 0) break;

      /* otherwise the next char should be a ',' */
      if (s[0] != ',') {
	vtf_error("bad atom specifier in line", line);
	return MOLFILE_ERROR;
      }
      /* skip the ',' */
      s++;
    };
  }

  return MOLFILE_SUCCESS;
}
예제 #8
0
/* Parse atom data from line. 
   Return MOLFILE_SUCCESS, if data was sucessfully parsed, 
   MOLFILE_ERROR if an error occured. */
static int vtf_parse_atom(char *line, vtf_data *d) {
  static molfile_atom_t atom;
  static char keyword[255];
  static char msg[255];
  static char aid_specifier[255];
  int n;
  char *s;
  int rest_is_userdata;
  int *aid_list = NULL;

  atom = default_atom;
  s = line;

#ifdef DEBUG
  printf("\tatom record\n");
  printf("line: %s\n", s);
#endif

  /* HANDLE THE AID SPECIFIER */

  /* save the aid specifier */
  if (sscanf(s, " %255s%n", aid_specifier, &n) < 1) {
    vtf_error("atom specifier is missing", line);
    return MOLFILE_ERROR;
  }
  s += n;

  aid_list = vtf_parse_aid_specifier(aid_specifier, d);
  if (aid_list == NULL) return MOLFILE_ERROR;

  /* A -1 in the aid_list denotes the end of the list */
#define AIDLOOP(assignment)                                             \
  {                                                                     \
    int *aid_ptr;                                                       \
    for (aid_ptr = aid_list; *aid_ptr != -1; aid_ptr++) {               \
      int aid = *aid_ptr;                                               \
      molfile_atom_t *cur_atom = &d->atoms[aid];                        \
      assignment;                                                       \
    }                                                                   \
  }
  
  /* handle the keywords */
  rest_is_userdata = 0;
  while (sscanf(s, " %255s%n", keyword, &n) == 1) {
    s += n;
#ifdef DEBUG
    printf("keyword: \"%s\" rest: \"%s\"\n", keyword, s);
#endif
    switch (tolower(keyword[0])) {
    case 'n': {
      /* name */
      if (sscanf(s, " %16s%n", atom.name, &n) == 1) {
        AIDLOOP(strcpy(cur_atom->name, atom.name));
      } else {
        vtf_error("could not get name in atom record", line);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 't': {
      /* type */
      if (sscanf(s, " %16s%n", atom.type, &n) == 1) {
        AIDLOOP(strcpy(cur_atom->type, atom.type));
      } else {
        vtf_error("could not get type in atom record", line);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'r': {
      /* resname, resid, radius */
      if (strlen(keyword) == 1 || 
          strncmp(keyword, "rad", 3) == 0) { 
        /* radius */
        if (sscanf(s, " %f%n", &atom.radius, &n) == 1) {
          AIDLOOP(cur_atom->radius = atom.radius);
        } else {
          vtf_error("could not get radius in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
        d->optflags |= MOLFILE_RADIUS;
      } else if (strcmp(keyword, "resid") == 0) {
        /* resid */
        if (sscanf(s, " %d%n", &atom.resid, &n) == 1) {
          AIDLOOP(cur_atom->resid = atom.resid);
        } else {
          vtf_error("could not get resid in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
      } else if (strcmp(keyword, "res") == 0 || 
                 strcmp(keyword, "resname") == 0) {
        /* resname */
        if (sscanf(s, " %8s%n", atom.resname, &n) == 1) {
          AIDLOOP(strcpy(cur_atom->resname, atom.resname));
        } else {
          vtf_error("could not get resname in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
      } else {
        strcpy(msg, "unrecognized keyword in atom record: ");
        strncat(msg, keyword, 200);
        vtf_error(msg, line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 's': {
      /* segid */
      if (sscanf(s, " %8s%n", atom.segid, &n) == 1) {
        AIDLOOP(strcpy(cur_atom->segid, atom.segid));
      } else {
        vtf_error("could not get segid in atom record", line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'i': {
      /* insertion */
      if (sscanf(s, " %2s%n", atom.insertion, &n) == 1) {
        AIDLOOP(strcpy(cur_atom->insertion, atom.insertion));
      } else {
        vtf_error("could not get insertion in atom record", line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_INSERTION;
      s += n;
      break;
    }
    case 'c': {
      /* chain, charge */
      if (strlen(keyword) == 1 || 
          strcmp(keyword, "chain") == 0) {
        if (sscanf(s, " %2s%n", atom.chain, &n) == 1) {
          AIDLOOP(strcpy(cur_atom->chain, atom.chain));
          s += n;
          break;
        } else {
          vtf_error("could not get chain in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
      }
    } /* if "chain" is not recognized, continue with next case */
    case 'q': {
      /* q and charge */
      if (strlen(keyword) == 1 ||
          strcmp(keyword, "charge") == 0) {
        if (sscanf(s, " %f%n", &atom.charge, &n) == 1) {
          AIDLOOP(cur_atom->charge = atom.charge);
        } else {
          vtf_error("could not get charge in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
        d->optflags |= MOLFILE_CHARGE;
      } else {
        strcpy(msg, "unrecognized keyword in atom record: ");
        strncat(msg, keyword, 200);
        vtf_error(msg, line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'a': {
      /* altloc, atomicnumber */
      if (strlen(keyword)== 1 || 
          strcmp(keyword, "atomicnumber") == 0) {
        if (sscanf(s, " %d%n", &atom.atomicnumber, &n) == 1) {
          AIDLOOP(cur_atom->atomicnumber = atom.atomicnumber);
        } else {
          vtf_error("could not get atomicnumber in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
        d->optflags |= MOLFILE_ATOMICNUMBER;
      } else if (strcmp(keyword, "altloc")) {
        if (sscanf(s, " %2s%n", atom.altloc, &n) == 1) {
          AIDLOOP(strcpy(cur_atom->altloc, atom.altloc));
        } else {
          vtf_error("could not get altloc in atom record", line);
          sfree(aid_list);
          return MOLFILE_ERROR;
        }
        d->optflags |= MOLFILE_ALTLOC;
      } else { 
        strcpy(msg, "unrecognized keyword in atom record: ");
        strncat(msg, keyword, 200);
        vtf_error(msg, line);
          sfree(aid_list);
        return MOLFILE_ERROR;
      }
      s += n;
      break;
    }
    case 'o': {
      /* occupancy */
      if (sscanf(s, " %f%n", &atom.occupancy, &n) == 1) {
        AIDLOOP(cur_atom->occupancy = atom.occupancy);
      } else {
        vtf_error("could not get occupancy in atom record", line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_OCCUPANCY;
      s += n;
      break;
    }
    case 'b': {
      /* bfactor */
      if (sscanf(s, " %f%n", &atom.bfactor, &n) == 1) {
        AIDLOOP(cur_atom->bfactor = atom.bfactor);
      } else {
        vtf_error("could not get bfactor in atom record", line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_BFACTOR;
      s += n;
      break;
    }
    case 'm': {
      /* mass */
      if (sscanf(s, " %f%n", &atom.mass, &n) == 1) {
        AIDLOOP(cur_atom->mass = atom.mass);
      } else {
        vtf_error("could not get mass in atom record", line);
        sfree(aid_list);
        return MOLFILE_ERROR;
      }
      d->optflags |= MOLFILE_MASS;
      s += n;
      break;
    }
    case 'u': {
      /* userdata: the rest of the line is user data */
      rest_is_userdata = 1;
#ifdef _USE_TCL
      if (d->read_mode != VTF_MOLFILE) {
        AIDLOOP(vtf_set_atom_userdata(aid, s));
      }
#endif
      break;
    }
    default: { 
      /* unrecognized */
      strcpy(msg, "unrecognized keyword in atom record: ");
      strncat(msg, keyword, 200);
      vtf_error(msg, line);
      sfree(aid_list);
      return MOLFILE_ERROR;
    }
    }
    if (rest_is_userdata) break;
  }

  /* if the aid_list is empty, modify the default atom */
  if (*aid_list == -1) {
      default_atom = atom;
      if (d->read_mode != VTF_MOLFILE) {
        sfree(default_userdata);
        default_userdata = strdup(s);
      }
  }

  sfree(aid_list);

#ifdef DEBUG
  printf("\tparsed keywords\n");
#endif

  return MOLFILE_SUCCESS;
}
예제 #9
0
/* Parse the aid specifier.
   Return an integer list of the aids that need to be modifed. The
   list is terminated by -1. If the list is NULL, an error occured. If
   the list is empty (i.e. it only contains -1), the default atom is
   to be modified.
 */
static int *vtf_parse_aid_specifier(char *s, vtf_data *d) {
  int n;
  unsigned int aid, from, to, offset;
  unsigned int size = 0;
  int *aid_list = NULL;

  if (s[0] == 'd') {
    /* DEFAULT */
    /* if the specifier is "default", just leave the list empty! */
#ifdef DEBUG
    printf("%s", "\tdefine default atom\n");
#endif
  } else {
    /* otherwise parse the aid specifier */
    while (1) {
      from = d->natoms;

      if (sscanf(s, " %u:%u%n", &from, &to, &n) == 2) {
        /* RANGE */
        if (from > to) { 
          vtf_error("bad range specifier (from > to):", s); 
          sfree(aid_list);
          return NULL;
        }
        vtf_create_atoms_as_needed(to, d);
        /* add the range to the aid list */
        offset = size;
        size += to-from+1;
        aid_list = realloc(aid_list, size*sizeof(int));
        for (aid = from; aid <= to; aid++) {
          aid_list[offset] = aid;
          offset++;
        }

      } else if (sscanf(s, " %u%n", &to, &n) == 1) {
        /* SINGLE AID */
        vtf_create_atoms_as_needed(to, d);
        /* add the aid to the aid_list */
        size += 1;
        aid_list = realloc(aid_list, size*sizeof(int));
        aid_list[size - 1] = to;

      } else {
        /* ERROR */
        vtf_error("bad aid specifier", s);
        sfree(aid_list);
        return NULL;
      }

      /* advance s */
      s += n;

      /* if there is no more to parse, break */
      if (s[0] == '\0') break;

      /* otherwise the next char should be a ',' */
      if (s[0] != ',') {
        vtf_error("bad aid specifier", s);
        sfree(aid_list);
        return NULL;
      }
      /* skip the ',' */
      s++;
    };
  }

  /* Terminate the list with -1 */
  aid_list = realloc(aid_list, (size+1)*sizeof(int));
  aid_list[size] = -1;
  return aid_list;
}