예제 #1
0
Csv::Csv(char * file_name , char * param_name ) {

        char * header ;
        char * next_field ;
        int len ;

        fileName_ = file_name ;
        len = strlen(param_name) ;

        if ((fp_ = fopen(file_name , "r")) == 0 ) {
           printf("ERROR:  Couldn't open \"%s\"\n" , file_name ) ;
           exit(-1) ;
        }

        line_ = new char[20480] ;
        header = new char[20480] ;
        fgets( header , 20480 , fp_ );

        // remove trailing newline 
        header[strlen(header)-1] = '\0' ;

        field_num_ = 0 ;
        next_field = strtok( header , "," ) ;

        if ( strncmp(next_field , param_name, len) ) {
                field_num_++ ;
                while ((next_field = strtok( NULL , "," ))) {
                        char *space_loc = strchr(next_field, ' ');
                        int actual_name_len = space_loc - next_field;
                        // need to make sure if the length of the parameter and the length
                        // of the parameter found in the next_field are actually the same,
                        // since strncmp(a.b.c_more, a.b.c, 5) results a.b.c_more equals a.b.c.
                        if ( strncmp(next_field , param_name, len) || actual_name_len != len) {
                                field_num_++ ;
                        }
                        else {
                                /* found the parameter, get the units if there are any */
                                char * start_unit ,  * end_unit ;
                                if ((start_unit = index( next_field , '{' ))) {
                                        end_unit = index( next_field , '}' ) ;
                                        end_unit[0] = '\0' ;
                                        if ( ! strcmp( param_name , "sys.exec.out.time" )) {
                                                unitTimeStr_ = start_unit + 1 ;
                                        }
                                        else {
                                                unitStr_ = map_trick_units_to_udunits(start_unit + 1) ;
                                        }
                                }
                                break ;
                        }
                }
        }

        data_offset_ = ftell(fp_) ;

        delete[]header ;

}
예제 #2
0
int Trick::VariableServerThread::var_units(std::string var_name, std::string units_name) {

    unsigned int ii ;

    for ( ii = 0 ; ii < vars.size() ; ii++ ) {
        if ( ! std::string(vars[ii]->ref->reference).compare(var_name) ) {
            if (!units_name.compare("xx")) {
                vars[ii]->ref->units = strdup(vars[ii]->ref->attr->units);
            }
            else if (!units_name.compare("--")) {
                vars[ii]->ref->units = strdup("1");
            }
            else {
                std::string new_units = map_trick_units_to_udunits(units_name) ;
                if ( units_name.compare(new_units) ) {
                    std::cout << "\033[33mUnits converted from [" << units_name << "] to [" << new_units
                     << "] in Variable Server for " << var_name << "\033[0m" << std::endl ;
                }
                ut_unit * from = ut_parse(Trick::UdUnits::get_u_system(), vars[ii]->ref->attr->units, UT_ASCII) ;
                if ( !from ) {
                    message_publish(MSG_ERROR, "Variable Server Error: var_units Units conversion error for \"%s\".\n",
                     var_name.c_str());
                    return -1 ;
                }
                ut_unit * to = ut_parse(Trick::UdUnits::get_u_system(), new_units.c_str(), UT_ASCII) ;
                if ( !to ) {
                    message_publish(MSG_ERROR, "Variable Server Error: var_units Units conversion error for \"%s\".\n",
                     var_name.c_str());
                    return -1 ;
                }
                cv_converter * conversion_factor = ut_get_converter(from,to) ;
                if ( conversion_factor != NULL ) {
                    // only assign conversion_factor if it is not NULL, otherwise leave previous value.
                    vars[ii]->conversion_factor = conversion_factor ;
                }
                vars[ii]->ref->units = strdup(units_name.c_str());
                ut_free(from) ;
                ut_free(to) ;
            }
        }
    }
    return(0) ;
}
예제 #3
0
/* A private function for parsing log header files.
 * This is responsible for initialize the Log classes as well
 */
int LogGroup::parseLogHeaders()
{

        int nVars;
        int lineNum;
        char *line;
        char *str1;
        char *str2;
        char *str3;
        char *str4;
        char *headerName;
        int i;
        int headerSize;
        int len;

        LogData *currLogData;
        Var *currVar;


        // Foreach log header
        for (i = 0; i < nHeaders_; i++) {

                // Allocate headerName
                len = strlen(pathToBinaryData_) + strlen(headers_[i]) + 2;
                headerName = new char[len];

                // Full path of log header
                sprintf(headerName, "%s/%s", pathToBinaryData_, headers_[i]);

                // Open log header
                if ((fp_ = fopen(headerName, "r")) == NULL) {
                        fprintf(stderr,
                                "\nERROR:\nCouldn't open file \"%s\" \n",
                                headerName);
                        return (-1);
                }
                // Allocate strings, we know that buffers can't be
                // longer than file!
                // Since headers are typically small, allocate them at ]
                // the header size
                fseek(fp_, 0, SEEK_END);
                headerSize = ftell(fp_);
                ::rewind(fp_);
                line = new char[headerSize + 1];        // Not sure about +1 :)
                str1 = new char[headerSize + 1];
                str2 = new char[headerSize + 1];
                str3 = new char[headerSize + 1];
                str4 = new char[headerSize + 1];

                // Parse rest of file
                lineNum = 0;
                while (fgets(line, headerSize, fp_) != NULL) {

                        lineNum++;

                        /* <log_file_name> <data_type> <units>    <param_name>
                           or
                           <log_file_name>  byte_order    is   [lit|big]_endian
                         */
                        if ( sscanf(line, "%s %s %s %s", str1, str2, str3, str4) == 4 ) {

                                // Byte order statement and top of a log group?
                                if (!strcmp(str2, "byte_order")) {

                                        LogData *ld = new LogData;
                                        log.push_back(ld);
                                        currLogData = log[nGroups_];
                                        nGroups_++;

                                        // New binary file
                                        currLogData->setBinaryFileName(str1);

                                        // Set byte order
                                        if (!strcmp(str4, "big_endian")) {
                                                currLogData->dataByteOrder = 1;
                                        } else {
                                                currLogData->dataByteOrder = 0;
                                        }

                                        continue;
                                }
                                // Check for binary file name mismatches
                                if (strcmp(str1, currLogData->getBinaryFileName())) {
                                        printf("ERROR: Parsing log header \"%s\".\n"
                                               "       Line %d. Binary file name "
                                               "mismatch with \"%s\".\n"
                                               "       May need little/big endian "
                                               "specification.\n\n",
                                               headerName, lineNum,
                                               currLogData->getBinaryFileName());
                                        return (-1);
                                }
                                // New variable
                                Var *v = new Var;
                                currLogData->vars.push_back(v);
                                nVars = currLogData->getNumVars();
                                currVar = currLogData->vars[nVars];
                                nVars++;
                                currLogData->setNumVars(nVars);

                                // Set Type
                                if (currVar->setType(str2) < 0) {
                                        printf("ERROR: In log header \"%s\".\n"
                                               "       Line %d. Type \"%s\" is "
                                               "not supported.\n",
                                               headerName, lineNum, str2);
                                        return (-1);
                                }

                                // For Release-07 we need to convert the old unit specs by
                                // adding explicit asterisk for multiplication. )
                                {
                                        char new_units_spec[100];
                                        new_units_spec[0] = 0;
                                        if ( convert_units_spec (str3, new_units_spec) != 0 ) {
                                                printf (" ERROR: Attempt to convert old units-spec, \"%s\" failed.\n\n",str3);
                                                return (-1);
                                        }
                                        delete [] str3;
                                        len = strlen(new_units_spec);
                                        str3 = new char[len + 1] ;
                                        strcpy(str3, new_units_spec);
                                }

                                // Initialize Unit class
                                if ( ! strcmp(str3,"--")) {
                                    currVar->setUnit(str3);
                                } else {
                                    currVar->setUnit(map_trick_units_to_udunits(str3));
                                }

                                // Set Var Name
                                currVar->setVarName(str4) ;
                                if (currVar->getSize() < 0) {
                                        printf("ERROR: In log header \"%s\".\n"
                                               "       Line %d. Problem with var "
                                               "name \"%s\" . \n",
                                               headerName, lineNum, str4);
                                        return (-1);
                                }
                        }
                }

                fclose(fp_);
                delete[]line;
                delete[]str1;
                delete[]str2;
                delete[]str3;
                delete[]str4;
                delete[]headerName;
        }

        return 1;
}
예제 #4
0
void FieldDescription::parseComment(std::string comment) {
    std::string ret_str ;

    bool units_found = false ;
    bool io_found = false ;
    bool chkpnt_io_found = false ;
    unsigned int chkpnt_io ;

    if ( comment.empty() ) {
        // If the comment is empty default all I/O enabled.
        io = 15 ;
        return ;
    }

    if ( debug_level >= 5 ) {
        std::cout << "comment before " << comment << std::endl ;
    }

    // remove open comment chars
    comment = get_regex_field(comment , "^(//|/\\*)(.*)" , 2) ;
    //std::cout << "1. " << comment << std::endl ;

    // remove optional doxygen comment chars
    // Note: I had to use [ \t\n\r] for \s because the Mac don't understand!
    comment = get_regex_field(comment , "^((\\*|!)<)?[ \t\n\r]*(.*)" , 3) ;
    //std::cout << "2. " << comment << std::endl ;

    // remove optional doxygen keyword
    comment = get_regex_field(comment , "(\\\\\\w+[ \t\n\r]*)?(.*)" , 2) ;
    //std::cout << "3. " << comment << std::endl ;

    ret_str = get_regex_field(comment , "@?trick_chkpnt_io[\\({]([^\\)}]+)[\\)}]" , 1) ;
    if ( ! ret_str.empty()) {
        chkpnt_io = io_map[ret_str] ;
        //std::cout << "go for trick_chkpnt_io " <<  io << std::endl ;
        chkpnt_io_found = true ;
        comment = get_regex_field(comment , "(.*)@?trick_chkpnt_io[\\({]([^\\)}]+)[\\)}]" , 1) +
         get_regex_field(comment , "@?trick_chkpnt_io[\\({]([^\\)}]+)[\\)}](.*)" , 2) ;
    }

    ret_str = get_regex_field(comment , "@?trick_io[\\({]([^\\)}]+)[\\)}]" , 1) ;
    if ( ! ret_str.empty()) {
        io = io_map[ret_str] ;
        //std::cout << "go for trick_io " <<  io << std::endl ;
        io_found = true ;
        comment = get_regex_field(comment , "(.*)@?trick_io[\\({]([^\\)}]+)[\\)}]" , 1) +
         get_regex_field(comment , "@?trick_io[\\({]([^\\)}]+)[\\)}](.*)" , 2) ;
    }

    /*
       Units can include parenthesis now.  We need to match the parenthesis in
       trick_units() to get the whole units string.
     */
    std::size_t tu_string = comment.find("trick_units") ;
    if ( tu_string != std::string::npos ) {
        std::size_t ustart = tu_string + std::string("trick_units").length() ;
        std::size_t uend = ustart + 1 ;
        std::stack<char> parens ;
        parens.push( comment[ustart]);
        while ( ! parens.empty() and (uend < comment.length())) {
            switch ( comment[uend] ) {
                case '(':
                    parens.push('(') ;
                    break ;
                case ')':
                    if (parens.top() == '(') {
                        parens.pop() ;
                    }
                    break ;
                case '}':
                    if (parens.top() == '{') {
                        parens.pop() ;
                    }
                    break ;
            }
            uend++ ;
        }
        if ( parens.empty() ) {
            units = comment.substr(ustart + 1 , uend - ustart - 2) ;
            units_found = true ;
            // If we have "@trick_units" include the "@" sign for erasure.
            if ( tu_string > 0 and comment[tu_string-1] == '@' ) {
                tu_string -= 1 ;
            }
            comment.erase(tu_string , uend - tu_string) ;
        } else {
            std::cout << "unmatched parenthesis for trick_units" << std::endl ;
        }
    }

    if ( ! io_found ) {
        // Note: I had to use [ \t\n\r] for \s because the Mac don't understand!
        ret_str = get_regex_field(comment , "^[ \t\n\r]*(\\*io|\\*oi|\\*i|\\*o|\\*\\*)" , 1) ;
        //std::cout << "3. " << ret_str << std::endl ;
        if ( ! ret_str.empty()) {
            io = io_map[ret_str] ;
            //std::cout << "stand-alone io " <<  io << std::endl ;
            io_found = true ;
            comment = get_regex_field(comment , "^[ \t\n\r]*(\\*io|\\*oi|\\*i|\\*o|\\*\\*)[ \t\n\r]*(.*)" , 2) ;
        }
    }

    //std::cout << "3. " << comment << std::endl ;
    if ( ! units_found ) {
        ret_str = get_regex_field(comment , "^[ \t\n\r]*\\(([^\\)]*)\\)" , 1) ;
        if ( ! ret_str.empty()) {
            units = ret_str ;
            //std::cout << "stand-alone units " << units << std::endl ;
            units_found = true ;
            comment = get_regex_field(comment , "^[ \t\n\r]*\\(([^\\)]*)\\)(.*)" , 2) ;
        } else {
            ret_str = get_regex_field(comment , "^[ \t\n\r]*([^ \t\n\r)]*)" , 1) ;
            if ( ! ret_str.empty()) {
                units = ret_str ;
                //std::cout << "stand-alone units " << units << " " << comment << std::endl ;
                units_found = true ;
                comment = get_regex_field(comment , "^[ \t\n\r]*([^ \t\n\r)]*)(.*)" , 2) ;
            }
        }
    }


    // Test if we have valid units.  We need to have found a units string and an io spec not zero
    // Possible todo is to create a map of valid units so we don't have to retest each string.
    if ( units_found and io != 0 and (valid_units.find(units) == valid_units.end())) {
        // remove spaces
        units.erase(remove_if(units.begin(), units.end(), isspace), units.end());
        if ( !units.compare("--") ) {
            units = "1" ;
        } else {
            // map old unit names to new names
            std::string new_units = map_trick_units_to_udunits(units) ;
            if ( units.compare(new_units) ) {
                if ( ! units_truth_is_scary ) {
                    std::cout << "\033[33mUnits converted from [" << units << "] to [" << new_units << "] "
                     << file_name << ":" << line_no << "\033[0m" << std::endl ;
                }
                units = new_units ;
            }
            ut_unit * test_units = ut_parse(u_system, units.c_str() , UT_ASCII) ;
            if ( test_units == NULL ) {
                // If the units are invalid write an error message and change the units to "1"
                std::cout << "\033[31mBad units specification [" << units << "] " << file_name << ":" << line_no
                 << "\033[0m" << std::endl ;
                units = "1" ;
            } else {
                // If the units are valid, free the memory allocated by new_units.
                ut_free(test_units) ;
                valid_units.insert(units) ;
            }
        }
    }

    if ( io == 4 ) {
        std::cout << "\033[33mWarning: " << file_name << ": line " << line_no << ": " <<
         "\"--\" is not a valid trick_io value. Setting to *io (3)\033[0m" << std::endl ;
        io = 3 ;
    }

    if ( chkpnt_io_found == true ) {
        // If a checkpoint I/O spec is found add it to the io field.
        io |= (chkpnt_io << 2 ) ;
    } else {
        // else duplicated the io field to the chkpnt io field.
        io |= (io << 2 ) ;
    }

    // The rest of the comment is the description of the variable.

    // remove the c comment end marker.
    comment = get_regex_field(comment , "(.*)\\*/" , 1) ;

    // posix c regular expressions are terrible. the regexes above will leave "@" signs because
    // the regular expressions are so greedy.
    comment = get_regex_field(comment , "^[ \t\n\r@]+(.*)" , 1) ;

    // remove leading and trailing whitespace
    comment = trim(comment) ;

    // escape special characters, convert tabs and newlines to spaces, remove multiple spaces.
    std::ostringstream ss ;
    bool is_space = false ;
    for (std::string::iterator it = comment.begin(); it != comment.end(); it++) {
        switch (*it) {
            case '\\': ss << "\\\\"; is_space = false ; break;
            case '"': ss << "\\\""; is_space = false ; break;
            case '\b': ss << "\\b"; is_space = false ; break;
            case '\f': ss << "\\f"; is_space = false ; break;
            case '\n':
            case '\r':
            case '\t':
            case ' ': if ( ! is_space ) ss << " "; is_space = true ; break;
            default: ss << *it; is_space = false ; break;
        }
    }

    description = ss.str() ;

}