#include #include #include #include #include #include #include "scolor.hpp" using namespace std; #define DATADIR "/usr/share/games/wesnoth/1.14/data/core/units/" size_t data_hash(string s){ size_t res = 1; for(auto c : s) res *= c; return res; } #include "hash_table.h" class CharacterClass { string id = "", description = "", level = "", cost = "", usage = "", movement = ""; public: CharacterClass(string filename) { ifstream infile; infile.open(filename); string line; while(infile.good()){ getline(infile, line); int start = -1, equals = -1; for(int i = 0; i < line.length(); i++){ if(isalnum(line[i]) && start == -1) start = i; if(line[i] == '=') equals = i; } if(equals == -1) continue; string attr = line.substr(start, equals-start); string val = line.substr(equals+1, string::npos); if(attr == "id") id = val; if(attr == "description" && description == "") description = val.substr(2, string::npos); if(attr == "level") level = val; if(attr == "cost") cost = val; if(attr == "usage") usage = val; if(attr == "movement") movement = val; } if(id == "") cout << "Oh no! The ID wasn't found for file " << filename << "!\n"; } string get_id(){ return id; } friend ostream& operator<<(ostream& os, const CharacterClass &c){ os << PURPLE("Name: ") << c.id << endl; os << PURPLE("Description: ") << c.description << endl; os << PURPLE("Level: ") << c.level << endl; os << PURPLE("Cost: ") << c.cost << endl; os << PURPLE("Usage: ") << c.usage << endl; os << PURPLE("Movement: ") << c.movement << endl; return os; } }; /* This is from CS253 * Take a look at use_getoutput.c in the CS253 examples * However, I've updated the bits that cause problems in C++ */ char* getoutput(const char* cmd){ int pipe_ends[2]; int read_end; int write_end; int backup_stdout = dup(1); pipe(pipe_ends); read_end = pipe_ends[0]; write_end = pipe_ends[1]; pid_t pid = fork(); if(pid == 0){ // We're the child dup2(write_end, 1); close(read_end); execl("/bin/sh", "sh", "-c", cmd, (char *) 0); printf("Command was probably wrong\n"); } // We must be the parent close(write_end); char *buffer = (char*)malloc(1024); size_t buffer_size = 1024; size_t totallen = 0; while(1){ size_t readlen = read(read_end, buffer + totallen, buffer_size - totallen); // Out of the pipe here totallen += readlen; if(readlen < 1) break; if(buffer_size - totallen == 0){ buffer = (char*)realloc(buffer, buffer_size + 1024); buffer_size += 1024; } } buffer[totallen] = 0; close(read_end); return buffer; } int main(){ HashTable all_classes; char *t_filenames = getoutput((string("ls ") + DATADIR + "*/* | grep -v deprecated | grep -v fake").c_str()); string all_filenames = t_filenames; free(t_filenames); stringstream af_stream(all_filenames); string fn; while(af_stream >> fn){ // if(string::npos != fn.find("dunefolk") || string::npos != fn.find("fake/Fog")) // continue; CharacterClass cc(fn); all_classes[cc.get_id()] = cc; } string tosearch; while(cin.good()){ cout << GREEN("Welcome to the Wesnoth Units Database\n"); cout << GREEN("ctrl+D to exit\n"); cout << YELLOW("Enter a character class to search for: "); getline(cin, tosearch); if(tosearch == "") continue; if(all_classes.contains(tosearch)) cout << all_classes[tosearch]; else cout << "We can't find \"" << tosearch << "\", sorry\n"; } cout << "\n"; return 0; }