int stringCompareIgnoreCase( const char *inStringA, const char *inStringB ) { char *lowerA = stringToLowerCase( inStringA ); char *lowerB = stringToLowerCase( inStringB ); int returnVal = strcmp( lowerA, lowerB ); delete [] lowerB; delete [] lowerA; return returnVal; }
char *stringLocateIgnoreCase( const char *inHaystack, const char *inNeedle ) { int haypos; int needlepos; haypos = 0; while (inHaystack[haypos]) { if (tolower (inHaystack[haypos]) == tolower (inNeedle[0])) { needlepos = 1; while ( (inNeedle[needlepos]) && (tolower (inHaystack[haypos+needlepos]) == tolower (inNeedle[needlepos])) ) ++needlepos; if (!inNeedle[needlepos]) return stringToLowerCase(inHaystack+haypos); } ++haypos; } return NULL; }
/* * assemble * * Calls firstParse to replace symbols. * * params: char * String location of assembly file * * return: start location of instructions */ unsigned int assemble (char * loc_assem_file, unsigned int * instructions_array) { FILE * rfp; //read file pointer // FILE * wfp; int line_buffer_size = sizeof(char) * 100; unsigned int start_loc; unsigned int opcode; int line_num = 0; char * loc_object_file; char * line_ptr = malloc(line_buffer_size); char * line_ptr_copy; char * line_malloc_loc = line_ptr; char * token; char * token2; ssize_t num_char_read; unsigned int token_in_bits; //uint32_t token_in_bits; unsigned int bit_instruct_32; //uint32_t bit_instruct_32; map_t map_clone; //open assembly source rfp = fopen(loc_assem_file, "r"); if (rfp == NULL) exit(EXIT_FAILURE); //create file name for output object file loc_object_file = malloc(sizeof(char) * 100); strcpy(loc_object_file, strtok(loc_assem_file, ".")); strcat(loc_object_file, ".object"); //open object file to write to // wfp = fopen("./test.object", "w"); // if (wfp == NULL) // exit(EXIT_FAILURE); ASSEMBLER_STR_p this = ASSEMBLER_constructor(); //first parse (for labels) firstParse(this, rfp); while (fgets(line_ptr, line_buffer_size, rfp)) { line_ptr = trimwhitespace(line_ptr); //if contains label, remove label if (strstr(line_ptr, ":") != '\0') { strsep(&line_ptr, ":"); //if instructions follow ":", don't use "continue" line_ptr = trimwhitespace(line_ptr); if (line_ptr == '\0' || line_ptr[0] == ';') { continue; } } //skip directives and comments if (line_ptr[0] == '.' || line_ptr[0] == ';' || line_ptr[0] == '\0') { continue; } line_ptr_copy = line_ptr; bit_instruct_32 = 0; token = strsep(&line_ptr_copy, " "); stringToLowerCase(token); line_ptr = line_ptr_copy; //take opcode, put it in bit form map_clone = this->operations_map; hashmap_get(map_clone, token, &token_in_bits); //bitshift to appropriate position in 32 bit bitcode opcode = token_in_bits; bit_instruct_32 = token_in_bits << 28; //bits 0-3 line_ptr_copy = line_ptr; int bitshift = 24; while (line_ptr_copy != NULL) { if (strstr(line_ptr_copy, ",") != NULL) { //if contains comma token = strsep(&line_ptr_copy, ","); stringToLowerCase(token); line_ptr_copy = trimwhitespace(line_ptr_copy); line_ptr = line_ptr_copy; } else { //in the case of last element if (strstr(line_ptr_copy, ";") != NULL) { //if contains comment ";" token = strsep(&line_ptr_copy, ";"); } else { token = line_ptr_copy; } token = trimwhitespace(token); stringToLowerCase(token); line_ptr_copy = NULL; } if (line_ptr_copy == NULL && (opcode == 3 || opcode == 4)) { //lw and sw instructions like lw $a0, 20($a1) line_ptr_copy = token; line_ptr = line_ptr_copy; token = strsep(&line_ptr_copy, "("); token2 = strsep(&line_ptr_copy, ")"); map_clone = this->registers_map; hashmap_get(map_clone, token2, &token_in_bits); line_ptr_copy = line_ptr; bit_instruct_32 = bit_instruct_32 | (token_in_bits << bitshift); token_in_bits = atoi(token); bit_instruct_32 = bit_instruct_32 | token_in_bits; line_ptr_copy = NULL; } else if (line_ptr_copy == NULL && opcode == 5) { //if last object is label line_ptr = line_ptr_copy; int *label_line_offset; stringToLowerCase(token); map_clone = this->symbol_table_map; hashmap_get(map_clone, token, &label_line_offset); //printf("%d\n\n",*label_line_offset); line_ptr_copy = line_ptr; bit_instruct_32 = bit_instruct_32 | (0x0000FFFF & (*label_line_offset - line_num - 1)); //copy offset from current instruct line num into bit_instruct_32 line_ptr_copy = NULL; } else if (line_ptr_copy == NULL && opcode == 6) { //if instruction is jalr line_ptr = line_ptr_copy; int *label_line_offset; stringToLowerCase(token); map_clone = this->registers_map; hashmap_get(map_clone, token, &token_in_bits); line_ptr_copy = line_ptr; bit_instruct_32 = bit_instruct_32 | (0x0F000000 & (token_in_bits << bitshift)); line_ptr_copy = NULL; }else if (token[0] != '$') { //if immediate value line_ptr = line_ptr_copy; token_in_bits = atoi(token); //write 16 bit number into last 32 bits of bit_instruct_32 token_in_bits = token_in_bits & 0x0000FFFF; bit_instruct_32 = bit_instruct_32 | token_in_bits; line_ptr_copy = line_ptr; } else { // else if register line_ptr = line_ptr_copy; stringToLowerCase(token); map_clone = this->registers_map; hashmap_get(map_clone, token, &token_in_bits); bit_instruct_32 = bit_instruct_32 | (token_in_bits << bitshift); line_ptr_copy = line_ptr; } bitshift -= 4; //printf("%d\n", this->start_loc); } //write bitcode to object file // fprintf(wfp, "%08x", bit_instruct_32); // printf("%08x\n", bit_instruct_32); instructions_array[line_num] = bit_instruct_32; line_num += 1; line_ptr = line_malloc_loc; } start_loc = this->start_loc; fclose(rfp); // fclose(wfp); //free(line_ptr); //free(loc_object_file); ASSEMBLER_destructor(this); //print_keyset(this->operations_map); //print_keyset(this->symbol_table_map); //print_keyset(this->registers_map); return start_loc; }
int VirtualMachine::openFileInWorkingDirectory(std::FILE*& f, std::string& baseName_, const char *mode, bool createOnly_) { f = (std::FILE *) 0; try { std::string fullName; bool haveFileName = false; if (baseName_.length() > 0) { haveFileName = true; // convert file name to lower case, replace invalid characters with '_' std::string baseName(baseName_); stringToLowerCase(baseName); for (size_t i = 0; i < baseName.length(); i++) { const std::string& s = baseName; if (!((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= '0' && s[i] <= '9') || s[i] == '.' || s[i] == '+' || s[i] == '-' || s[i] == '_')) baseName[i] = '_'; } fullName = fileIOWorkingDirectory + baseName; } else { if (fileNameCallback) fileNameCallback(fileNameCallbackUserData, fullName); if (fullName.length() == 0) return -2; // error: invalid file name baseName_ = fullName; } // attempt to stat() file #ifndef WIN32 struct stat st; std::memset(&st, 0, sizeof(struct stat)); int err = stat(fullName.c_str(), &st); if (err != 0 && haveFileName) { // not found, try case insensitive file search std::string tmpName(fullName); tmpName[0] = tmpName.c_str()[0]; // unshare string DIR *dir_; dir_ = opendir(fileIOWorkingDirectory.c_str()); if (dir_) { do { struct dirent *ent_ = readdir(dir_); if (!ent_) break; bool foundMatch = true; size_t offs = fileIOWorkingDirectory.length(); const char *s1 = fullName.c_str() + offs; const char *s2 = &(ent_->d_name[0]); size_t i = 0; while (!(s1[i] == '\0' && s2[i] == '\0')) { if (s1[i] != s2[i]) { if (!(s2[i] >= 'A' && s2[i] <= 'Z' && s1[i] == (s2[i] + ('a' - 'A')))) { foundMatch = false; break; } } tmpName[offs + i] = s2[i]; i++; } if (foundMatch) { std::memset(&st, 0, sizeof(struct stat)); err = stat(tmpName.c_str(), &st); } } while (err != 0); closedir(dir_); } if (err == 0) fullName = tmpName; } #else struct _stat st; std::memset(&st, 0, sizeof(struct _stat)); int err = _stat(fullName.c_str(), &st); #endif if (err != 0) { if (mode == (char *) 0 || mode[0] != 'w') return -3; // error: cannot find file } else { #ifndef WIN32 if (!(S_ISREG(st.st_mode))) return -4; // error: not a regular file #else if (!(st.st_mode & _S_IFREG)) return -4; // error: not a regular file #endif if (createOnly_) return -6; // error: the file already exists } // FIXME: the file may possibly be created, changed, or removed between // calling stat() and fopen() f = std::fopen(fullName.c_str(), mode); if (!f) return -5; // error: cannot open file } catch (...) { if (f) { std::fclose(f); f = (std::FILE *) 0; } return -1; } return 0; }