deps/kb_meme/meme-5.0.1/src/seq-reader-from-fasta.c
/******************************************************************************
 * This function attempts to parse genomic coordinates from the
 * current sequence header. If successful it will return the 
 * chromosome name, name length and starting position.
 *
 * There are two supported formats.
 * The first is the UCSC/fastaFromBed style: name:start-stop[(+|-)][_id]
 * e.g., ">chr1:1000-1010(-)_xyz"
 * The second is the Galaxy "Fetch sequence" style: genome_name_start_stop_strand
 * where strand is +|-.
 * e.g., ">mm9_chr18_75759530_7575972_-"
 *
 * Returns true if it was able to find genomic coordinates, false otherwise.
 *****************************************************************************/
This function attempts to parse genomic coordinates from the
current sequence header. If successful it will return the
chromosome name, name length and starting position.

There are two supported formats.

Returns true if it was able to find genomic coordinates, false otherwise.
This function attempts to parse genomic coordinates from the current sequence header . If successful it will return the chromosome name name length and starting position . There are two supported formats . Returns true if it was able to find genomic coordinates false otherwise .
bool parse_genomic_coordinates_helper(
  char*  header,	  
  char** chr_name_ptr,    
  size_t * chr_name_len_ptr,
  int *  start_ptr,	  
  int *  end_ptr	  
) {
  #define NUM_SUBMATCHES 6
  #define ERROR_MESSAGE_SIZE 100
  #define BUFFER_SIZE 512
  static bool first_time = true;
  static regex_t ucsc_header_regex;
  static regex_t galaxy_header_regex;
  static regmatch_t matches[NUM_SUBMATCHES];
  char error_message[ERROR_MESSAGE_SIZE];
  int status = 0;
  if (first_time == true) {
    status = regcomp(
      &ucsc_header_regex, 
      "([^[:space:]:]+):([[:digit:]]+)-([[:digit:]]+)(\\([+-]\\))?(_[^[:space:]]+)?", 
      REG_EXTENDED | REG_ICASE | REG_NEWLINE
    );
    if (status != 0) {
      regerror(status, &ucsc_header_regex, error_message, ERROR_MESSAGE_SIZE);
      die(
        "Error while intitializing regular expression\n"
        "for parsing UCSC style genome coordinates from FASTA header: %s\n", 
        error_message
      );
    }
    status = regcomp(
      &galaxy_header_regex, 
      "([^[:space:]_]+_[^[:space:]_]+)_([[:digit:]]+)_([[:digit:]]+)(_[+-])?", 
      REG_EXTENDED | REG_ICASE | REG_NEWLINE
    );
    if (status != 0) {
      regerror(status, &galaxy_header_regex, error_message, ERROR_MESSAGE_SIZE);
      die(
        "Error while intitializing regular expression\n"
        "for parsing Galaxy style genome coordinates from FASTA header: %s\n", 
        error_message
      );
    }
    first_time = false;
  }
  bool found_coordinates = false;
  status = regexec(&ucsc_header_regex, header, NUM_SUBMATCHES, matches, 0);
  if(status && status != REG_NOMATCH ){
    regerror(status, &ucsc_header_regex, error_message, 100);
    die("Error trying to parse UCSC style genome coordinates from sequence header: %s\n"
        "error message is %s\n",
        header, 
        error_message
    );
  }
  if (status == REG_NOMATCH) {
    status = regexec(&galaxy_header_regex, header, NUM_SUBMATCHES, matches, 0);
    if(status && status != REG_NOMATCH ){
      regerror(status, &ucsc_header_regex, error_message, 100);
      die("Error trying to parse GALAXY style genome coordinates from sequence header: %s\n"
          "error message is %s\n",
          header, 
          error_message
      );
    }
  }
  if(!status) {
    found_coordinates = true;
    char buffer[BUFFER_SIZE];
    int chr_name_len = matches[1].rm_eo - matches[1].rm_so;
    strncpy(buffer, header + matches[1].rm_so, chr_name_len);
    buffer[chr_name_len] = 0;
    char *chr_name = strdup(buffer);
    if (chr_name == NULL) {
      die("Unable to allocate memory while parsing sequence header.\n");
    }
    *chr_name_ptr = chr_name;
    *chr_name_len_ptr = chr_name_len;
    size_t pos_len = matches[2].rm_eo - matches[2].rm_so;
    strncpy(buffer, header + matches[2].rm_so, pos_len);
    buffer[pos_len] = 0;
    *start_ptr = atol(buffer) - 1;
    pos_len = matches[3].rm_eo - matches[3].rm_so;
    strncpy(buffer, header + matches[3].rm_so, pos_len);
    buffer[pos_len] = 0;
    *end_ptr = atol(buffer) - 1;
    if (matches[4].rm_so >= 0) {
      pos_len = matches[4].rm_eo - matches[4].rm_so;
      char strand = *(header + matches[4].rm_so + 1);
    }
    if (matches[5].rm_so >= 0) {
      pos_len = matches[5].rm_eo - matches[5].rm_so;
      strncpy(buffer, header + matches[5].rm_so + 1, pos_len);
      buffer[pos_len] = 0;
    }
  }
  return found_coordinates;
  #undef NUM_SUBMATCHES
  #undef ERROR_MESSAGE_SIZE
  #undef BUFFER_SIZE
}
bool parse_genomic_coordinates_helper ( char * header , char * * chr_name_ptr , size_t * chr_name_len_ptr , int * start_ptr , int * end_ptr ) { #define NUM_SUBMATCHES  6 #define ERROR_MESSAGE_SIZE  100 #define BUFFER_SIZE  512 static bool first_time = true ; static regex_t ucsc_header_regex ; static regex_t galaxy_header_regex ; static regmatch_t matches [ NUM_SUBMATCHES ] ; char error_message [ ERROR_MESSAGE_SIZE ] ; int status = 0 ; if ( first_time == true ) { status = regcomp ( & ucsc_header_regex , " \\ \\ " , REG_EXTENDED | REG_ICASE | REG_NEWLINE ) ; if ( status != 0 ) { regerror ( status , & ucsc_header_regex , error_message , ERROR_MESSAGE_SIZE ) ; die ( " \n " " \n " , error_message ) ; } status = regcomp ( & galaxy_header_regex , " " , REG_EXTENDED | REG_ICASE | REG_NEWLINE ) ; if ( status != 0 ) { regerror ( status , & galaxy_header_regex , error_message , ERROR_MESSAGE_SIZE ) ; die ( " \n " " \n " , error_message ) ; } first_time = false ; } bool found_coordinates = false ; status = regexec ( & ucsc_header_regex , header , NUM_SUBMATCHES , matches , 0 ) ; if ( status && status != REG_NOMATCH ) { regerror ( status , & ucsc_header_regex , error_message , 100 ) ; die ( " \n " " \n " , header , error_message ) ; } if ( status == REG_NOMATCH ) { status = regexec ( & galaxy_header_regex , header , NUM_SUBMATCHES , matches , 0 ) ; if ( status && status != REG_NOMATCH ) { regerror ( status , & ucsc_header_regex , error_message , 100 ) ; die ( " \n " " \n " , header , error_message ) ; } } if ( ! status ) { found_coordinates = true ; char buffer [ BUFFER_SIZE ] ; int chr_name_len = matches [ 1 ] . rm_eo - matches [ 1 ] . rm_so ; strncpy ( buffer , header + matches [ 1 ] . rm_so , chr_name_len ) ; buffer [ chr_name_len ] = 0 ; char * chr_name = strdup ( buffer ) ; if ( chr_name == NULL ) { die ( " \n " ) ; } * chr_name_ptr = chr_name ; * chr_name_len_ptr = chr_name_len ; size_t pos_len = matches [ 2 ] . rm_eo - matches [ 2 ] . rm_so ; strncpy ( buffer , header + matches [ 2 ] . rm_so , pos_len ) ; buffer [ pos_len ] = 0 ; * start_ptr = atol ( buffer ) - 1 ; pos_len = matches [ 3 ] . rm_eo - matches [ 3 ] . rm_so ; strncpy ( buffer , header + matches [ 3 ] . rm_so , pos_len ) ; buffer [ pos_len ] = 0 ; * end_ptr = atol ( buffer ) - 1 ; if ( matches [ 4 ] . rm_so >= 0 ) { pos_len = matches [ 4 ] . rm_eo - matches [ 4 ] . rm_so ; char strand = * ( header + matches [ 4 ] . rm_so + 1 ) ; } if ( matches [ 5 ] . rm_so >= 0 ) { pos_len = matches [ 5 ] . rm_eo - matches [ 5 ] . rm_so ; strncpy ( buffer , header + matches [ 5 ] . rm_so + 1 , pos_len ) ; buffer [ pos_len ] = 0 ; } } return found_coordinates ; #undef  NUM_SUBMATCHES #undef  ERROR_MESSAGE_SIZE #undef  BUFFER_SIZE }
This function attempts to parse genomic coordinates from the
 current sequence header.
This function attempts to parse genomic coordinates from the current sequence header .
// sequence name  // chromosome name ((chr[^:])) // number of characters in chromosome name // start position of sequence (chr:(\d+)-) // end position of sequence (chr:\d+-(\d+)) // Initialize regular express for extracting chromsome coordinates; // Try UCSC style first // UCSC didn't work, try GALAXY style // The sequence header contains genomic coordinates // Get chromosome name (required) // Get chromosome start position (required) // Get chromosome end position (required) // Get the strand (optional) // Get the id tag (optional)