<commit_before>#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdlib> //C standard library <stdlib.h>, /* atoi */
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h> //C standard library <stdlib.h>, /* atoi */
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#ifdef _WIN32
#include <windows.h>
#define chdir _chdir

#else
#include <unistd.h>
#endif

//INLCUDING COMMANDS
//#include "commands/cat.h"

using namespace std;

int executeCommand(vector<string>&);
vector<string> getTokens(string, char);
char** vectorToCharPP (vector<string> tokenized);

int main(int argc, char const *argv[]){
    int status = 0;
    while(!status) {
        cout << "mi_sh> ";
        string line;
        getline(cin,line);
        vector<string> tokens = getTokens(line, ' ');
        status = executeCommand(tokens);
    };
    if(status != 1){
        cerr << "ERROR " << status << ": al ejecutar el comando" << endl;
    }
    return 0;
}

/*
ejecuta los comandos conocidos por el programa
retorna 0 cuando todo salio bien y continuar con el programa
retorna 1 para salir del programa sin errores
retorna cualquier otro valor con error
*/
int executeCommand(vector<string>& tokens){
    if(tokens.size() == 0){
        cerr << "No hay commando a ejecutar" << endl;
        return 0;
    }
    int childErr;
    if(tokens.size() > 0){
        int ppid, chpid;
        string commandPath = "commands/bin/" + tokens[0];
        char** argvData = vectorToCharPP (tokens);
        if((chpid=fork()) == 0){

            childErr = execvp(commandPath.c_str(), argvData);
            cout << "Comando " << argvData[0] <<": Fallido" << endl;

            return childErr;
        }else{
            wait(NULL);
            return 0;
        }
        return -1;
    }
    /*
    if(tokens[0] == "help"){
        if(tokens.size() == 1){
            cout << "-----AYUDA-----\n"
            << "por ahora no es de mucha ayuda, pero\n"
            << "si ocupan la lista de comandos disponible\n"
            << "utiliza 'help list' para mostrar la lista de comandos disponibles\n" << endl;
            return 0;
        }
        if(tokens[1] == "list"){
                cout
            << "cat [archivo]" << endl
            << "help (list)" << endl
            << "exit [numero]" << endl;
        }else{
            cout << "No hay ayuda para comando listado" << endl;
        }
        return 0;
    }
    if(tokens[0] == "exit"){
        if(tokens.size() == 1){
            return 1;
        }
        return atoi(tokens[1].c_str());
    }
    if(tokens[0] == "cat"){
        if(tokens.size() == 1){
            cout << "Uso incorrecto de cat, porfavor especifique archivo\n"
            << "Ejemplo: cat archivo.txt, cat [direccion/del/archivo.cpp]";
            return 0;
        }
        /* //CAT de fernando
        int controlador = 1;
        //int i = 0;
        do{
	        //if(controlador == 0 || tokens[i] == ' '){
                	FILE *file;
                	char line[100];
                	file = fopen(tokens[controlador].c_str(),"r");
                	while(fscanf(file,"%[^\n]\n",line)!=EOF){
          	      		printf("%s\n", line);
                	}
                	fclose(file);
                 	//arg = strtok(NULL, DELIMS);
               //}
          //     i++;
               controlador++;
        }while(controlador!=tokens.size());
        */
        /*
        //CAT de Isaias
        char * filename = new char [tokens[1].length()+1];
        strcpy(filename,tokens[1].c_str());
        cout << filename << endl;
        cat fileToPrint (filename);
        fileToPrint.printFile();
        delete[] filename;*//*
        return 0;
    }
    if (tokens[0] == "rm"){
    	if(tokens.size() == 1){
    		cout<<"Uso incorrecto de rm, muy pocos argumentos"<<endl;
    		return 0;
    	}
    	else{
    		if(tokens[1]=="-R"){
    			if(tokens.size()==2){
                    cout<<"uso incorrecto de rm -R, muy pocos argumentos"<<endl;
                    return 0;
    			}
    			if (fork() == 0) {// proceso hijo
                    return execlp("rm-R",tokens[2].c_str(),tokens[2].c_str(), (char *)0);
                }
                return -1;
    		}else{
    			if(fork()==0){
    				return execlp("rm",tokens[1].c_str(),tokens[1].c_str(), (char *)0);
    			}
                return -1;
    		}
    	}
    }
    if(tokens[0]=="ls"){
		if(tokens.size()==2){
			if(tokens[1]=="-m"){
				if(fork() == 0){
					return execlp("ls-m", "./ls-m", (char *)0);
				}
				return -1;
			}
			if(tokens[1]=="-l"){
				if(fork() == 0){
					//execlp("./ls-l", "./ls-l", (char *)0);
					return execlp("ls-l", "./ls-l", (char *)0);
				}
				return -1;
			}
			return -1;
		}else{
			if(fork() == 0){
				execlp("ls","./ls", (char *)0);
			}
			return 0;
		}
    }
	if(tokens[0]=="cd"){
		if(tokens.size()== 1){
			cout<<"Uso incorrecto de cd, muy pocos argumentos"<<endl;
			return 0;
		}else{
			chdir(tokens[1].c_str());
			return 0;
		}
		return -1;
	}
	if(tokens[0]=="rmdir"){
		if(tokens.size()==1){
			cout<<"Uso incorrecto de rmdir, muy pocos argumentos"<<endl;
			return 0;
		}else{
			if(fork() == 0){
				return execlp("rmdir","./rmdir",tokens[1].c_str(), (char *)0);
			}
			return -1;
		}
    }
    if(tokens[0]=="ps"){
		if(tokens.size()==2){
			if(tokens[1]=="-e"){
				if(fork() == 0){
					return execlp("ps-e","./ps-e", (char *)0);
				}
			}
			return -1;
		}
    }
    if(tokens[0]=="ln"){
		if(tokens.size()==1){
			cout<<"Error, hacen falta argumentos"<<endl;
			return 0;
		}else{
			if(tokens[1]=="-s"){
				if(fork() == 0){
					execlp("ln","./ln",tokens[2].c_str(), tokens[3].c_str(), (char *)0);
				}

			}
		}
    }
    if(tokens[0]=="uname"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
		}else{
			if(fork() == 0){
				execlp("uname","./uname",tokens[1].c_str(), (char *)0);
			}

		}
    }
    if(tokens[0]=="chmod"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
			return 0;
		}
		else{
	        int controlador = 0;
	        int i = 0;
	        int mode;
	        do{
				//if(arg[i]==' '){
				controlador++;
				if(controlador==1){
					mode = strtol(tokens[1].c_str(), 0, 8);
				}
	            if(controlador==2){
					if(chmod(tokens[2].c_str(), mode) != 0){
						perror("Command failed");
					}
				}
				//  arg = strtok(NULL, DELIMS);
				//}
				i++;
	        }while(controlador!=tokens.size());
	        if(controlador<2){
	            fprintf(stderr, "chmod missing argument .\n");
	        }
	        return 0;
		}
    }
    if(tokens[0]=="mkdir"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
			return 0;
		}
		else{
			if(fork() == 0){
                cout << "Ejecutando mkdir" << endl;
				execlp("commands/bin/mkdir", "mkdir", tokens[1].c_str(), (char *)0);
			}
			return 0;
		}
    }
    if(tokens[0] == "ln"){
       if(tokens.size() == 1){
            cout << "Falta comandos para el uso de ln, ln [opciones]\n"
                 << "opciones: -s"<<endl;
       }else{
         if(tokens[1] == "-s"){
            if(tokens.size() < 4){
                cout << "Falta el nombre del archivo existente o el nuevo archivo\n"
                     << "ln -s archivo.txt archivo2.txt"<<endl;
            }else{
                char * archivo = new char [tokens[2].length()+1];
                strcpy(archivo,tokens[2].c_str());

                char * linkarchivo = new char [tokens[3].length()+1];
                strcpy(linkarchivo,tokens[3].c_str());

                if(link(archivo, linkarchivo) < 0){
                    cout << "Error al linkear el archivo" << endl;
                }
            }
         }
      }
      return 0;
    }

    cout << tokens[0] << ": comando no encontrado" << endl;
    return 0;
    */
}

//retorna los tokens de la terminal
vector<string> getTokens(string toTokenize, char delimiter){
    vector<string> v;
    string::iterator stringIT = toTokenize.begin();
    for(string::iterator i = toTokenize.begin(); i != toTokenize.end(); i++){
        if(*i == delimiter){
            v.push_back(string(stringIT,i));
            stringIT=i+1;
        }
    }
    v.push_back(string(stringIT,toTokenize.end()));
    return v;
}
/*
retorna un char** al enviarle un vector<string>
vectorToCharPP = de vector a char puntero puntero
*/
char** vectorToCharPP (vector<string> tokenized){
    char** tokens;
    int tokenAmount = tokenized.size();
    tokens = new char*[tokenAmount+1];
    for(int i = 0; i < tokenAmount; i++){
        tokens[i] = new char[tokenized[i].length()];
        strcpy(tokens[i],tokenized[i].c_str());
    }
    tokens[tokenAmount] = NULL;
    return tokens;
}
<commit_msg>arreglando cd<commit_after>#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdlib> //C standard library <stdlib.h>, /* atoi */
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h> //C standard library <stdlib.h>, /* atoi */
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#ifdef _WIN32
#include <windows.h>
#define chdir _chdir

#else
#include <unistd.h>
#endif

//INLCUDING COMMANDS
//#include "commands/cat.h"

using namespace std;

int executeCommand(vector<string>&);
vector<string> getTokens(string, char);
char** vectorToCharPP (vector<string> tokenized);
string PATH, CURR_DIR;

int main(int argc, char const *argv[]){
    CURR_DIR = getenv("PWD");
    PATH = CURR_DIR+"/commands/bin/";
    int status = 0;
    while(!status) {
        cout << "mi_sh> ";
        string line;
        getline(cin,line);
        vector<string> tokens = getTokens(line, ' ');
        status = executeCommand(tokens);
    };
    if(status != 1){
        cerr << "ERROR " << status << ": al ejecutar el comando" << endl;
    }
    return 0;
}

/*
ejecuta los comandos conocidos por el programa
retorna 0 cuando todo salio bien y continuar con el programa
retorna 1 para salir del programa sin errores
retorna cualquier otro valor con error
*/
int executeCommand(vector<string>& tokens){
    if(tokens.size() == 0){
        cerr << "No hay commando a ejecutar" << endl;
        return 0;
    }
    int childErr;
    if(tokens.size() > 0){
        int ppid, chpid;
        	string commandPath = PATH + tokens[0];
        char** argvData = vectorToCharPP (tokens);
	if(tokens[0] == "cd"){
	        if(tokens.size()== 2){
               		chdir(tokens[1].c_str());
        	}
		return 0;

	}else{
        	if((chpid=fork()) == 0){
            		childErr = execvp(commandPath.c_str(), argvData);
            		cout << "Comando " << argvData[0] <<": Fallido" << endl;

            		return childErr;
        	}else{
            		wait(NULL);
            		return 0;
        	}
        	return -1;
	}
    }
    /*
    if(tokens[0] == "help"){
        if(tokens.size() == 1){
            cout << "-----AYUDA-----\n"
            << "por ahora no es de mucha ayuda, pero\n"
            << "si ocupan la lista de comandos disponible\n"
            << "utiliza 'help list' para mostrar la lista de comandos disponibles\n" << endl;
            return 0;
        }
        if(tokens[1] == "list"){
                cout
            << "cat [archivo]" << endl
            << "help (list)" << endl
            << "exit [numero]" << endl;
        }else{
            cout << "No hay ayuda para comando listado" << endl;
        }
        return 0;
    }
    if(tokens[0] == "exit"){
        if(tokens.size() == 1){
            return 1;
        }
        return atoi(tokens[1].c_str());
    }
    if(tokens[0] == "cat"){
        if(tokens.size() == 1){
            cout << "Uso incorrecto de cat, porfavor especifique archivo\n"
            << "Ejemplo: cat archivo.txt, cat [direccion/del/archivo.cpp]";
            return 0;
        }
        /* //CAT de fernando
        int controlador = 1;
        //int i = 0;
        do{
	        //if(controlador == 0 || tokens[i] == ' '){
                	FILE *file;
                	char line[100];
                	file = fopen(tokens[controlador].c_str(),"r");
                	while(fscanf(file,"%[^\n]\n",line)!=EOF){
          	      		printf("%s\n", line);
                	}
                	fclose(file);
                 	//arg = strtok(NULL, DELIMS);
               //}
          //     i++;
               controlador++;
        }while(controlador!=tokens.size());
        */
        /*
        //CAT de Isaias
        char * filename = new char [tokens[1].length()+1];
        strcpy(filename,tokens[1].c_str());
        cout << filename << endl;
        cat fileToPrint (filename);
        fileToPrint.printFile();
        delete[] filename;*//*
        return 0;
    }
    if (tokens[0] == "rm"){
    	if(tokens.size() == 1){
    		cout<<"Uso incorrecto de rm, muy pocos argumentos"<<endl;
    		return 0;
    	}
    	else{
    		if(tokens[1]=="-R"){
    			if(tokens.size()==2){
                    cout<<"uso incorrecto de rm -R, muy pocos argumentos"<<endl;
                    return 0;
    			}
    			if (fork() == 0) {// proceso hijo
                    return execlp("rm-R",tokens[2].c_str(),tokens[2].c_str(), (char *)0);
                }
                return -1;
    		}else{
    			if(fork()==0){
    				return execlp("rm",tokens[1].c_str(),tokens[1].c_str(), (char *)0);
    			}
                return -1;
    		}
    	}
    }
    if(tokens[0]=="ls"){
		if(tokens.size()==2){
			if(tokens[1]=="-m"){
				if(fork() == 0){
					return execlp("ls-m", "./ls-m", (char *)0);
				}
				return -1;
			}
			if(tokens[1]=="-l"){
				if(fork() == 0){
					//execlp("./ls-l", "./ls-l", (char *)0);
					return execlp("ls-l", "./ls-l", (char *)0);
				}
				return -1;
			}
			return -1;
		}else{
			if(fork() == 0){
				execlp("ls","./ls", (char *)0);
			}
			return 0;
		}
    }
	if(tokens[0]=="cd"){
		if(tokens.size()== 1){
			cout<<"Uso incorrecto de cd, muy pocos argumentos"<<endl;
			return 0;
		}else{
			chdir(tokens[1].c_str());
			return 0;
		}
		return -1;
	}
	if(tokens[0]=="rmdir"){
		if(tokens.size()==1){
			cout<<"Uso incorrecto de rmdir, muy pocos argumentos"<<endl;
			return 0;
		}else{
			if(fork() == 0){
				return execlp("rmdir","./rmdir",tokens[1].c_str(), (char *)0);
			}
			return -1;
		}
    }
    if(tokens[0]=="ps"){
		if(tokens.size()==2){
			if(tokens[1]=="-e"){
				if(fork() == 0){
					return execlp("ps-e","./ps-e", (char *)0);
				}
			}
			return -1;
		}
    }
    if(tokens[0]=="ln"){
		if(tokens.size()==1){
			cout<<"Error, hacen falta argumentos"<<endl;
			return 0;
		}else{
			if(tokens[1]=="-s"){
				if(fork() == 0){
					execlp("ln","./ln",tokens[2].c_str(), tokens[3].c_str(), (char *)0);
				}

			}
		}
    }
    if(tokens[0]=="uname"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
		}else{
			if(fork() == 0){
				execlp("uname","./uname",tokens[1].c_str(), (char *)0);
			}

		}
    }
    if(tokens[0]=="chmod"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
			return 0;
		}
		else{
	        int controlador = 0;
	        int i = 0;
	        int mode;
	        do{
				//if(arg[i]==' '){
				controlador++;
				if(controlador==1){
					mode = strtol(tokens[1].c_str(), 0, 8);
				}
	            if(controlador==2){
					if(chmod(tokens[2].c_str(), mode) != 0){
						perror("Command failed");
					}
				}
				//  arg = strtok(NULL, DELIMS);
				//}
				i++;
	        }while(controlador!=tokens.size());
	        if(controlador<2){
	            fprintf(stderr, "chmod missing argument .\n");
	        }
	        return 0;
		}
    }
    if(tokens[0]=="mkdir"){
		if(tokens.size()==1){
			cout<<"Error, faltan argumentos"<<endl;
			return 0;
		}
		else{
			if(fork() == 0){
                cout << "Ejecutando mkdir" << endl;
				execlp("commands/bin/mkdir", "mkdir", tokens[1].c_str(), (char *)0);
			}
			return 0;
		}
    }
    if(tokens[0] == "ln"){
       if(tokens.size() == 1){
            cout << "Falta comandos para el uso de ln, ln [opciones]\n"
                 << "opciones: -s"<<endl;
       }else{
         if(tokens[1] == "-s"){
            if(tokens.size() < 4){
                cout << "Falta el nombre del archivo existente o el nuevo archivo\n"
                     << "ln -s archivo.txt archivo2.txt"<<endl;
            }else{
                char * archivo = new char [tokens[2].length()+1];
                strcpy(archivo,tokens[2].c_str());

                char * linkarchivo = new char [tokens[3].length()+1];
                strcpy(linkarchivo,tokens[3].c_str());

                if(link(archivo, linkarchivo) < 0){
                    cout << "Error al linkear el archivo" << endl;
                }
            }
         }
      }
      return 0;
    }

    cout << tokens[0] << ": comando no encontrado" << endl;
    return 0;
    */
}

//retorna los tokens de la terminal
vector<string> getTokens(string toTokenize, char delimiter){
    vector<string> v;
    string::iterator stringIT = toTokenize.begin();
    for(string::iterator i = toTokenize.begin(); i != toTokenize.end(); i++){
        if(*i == delimiter){
            v.push_back(string(stringIT,i));
            stringIT=i+1;
        }
    }
    v.push_back(string(stringIT,toTokenize.end()));
    return v;
}
/*
retorna un char** al enviarle un vector<string>
vectorToCharPP = de vector a char puntero puntero
*/
char** vectorToCharPP (vector<string> tokenized){
    char** tokens;
    int tokenAmount = tokenized.size();
    tokens = new char*[tokenAmount+1];
    for(int i = 0; i < tokenAmount; i++){
        tokens[i] = new char[tokenized[i].length()];
        strcpy(tokens[i],tokenized[i].c_str());
    }
    tokens[tokenAmount] = NULL;
    return tokens;
}
<|endoftext|>


<commit_before>/* The MIT Licensem

   Copyright (c) 2013 Adrian Tan <atks@umich.edu>

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "align.h"
#include "annotate_1000g.h"
#include "annotate_dbsnp_rsid.h"
#include "annotate_indels.h"
#include "annotate_mendelian.h"
#include "annotate_regions.h"
#include "annotate_variants.h"
#include "annotate_vntrs.h"
#include "cat.h"
#include "compute_features.h"
#include "compute_concordance.h"
#include "compute_rl_dist.h"
#include "config.h"
#include "consolidate.h"
#include "consolidate_multiallelics.h"
#include "consolidate_vntrs.h"
#include "construct_probes.h"
#include "decompose_blocksub.h"
#include "decompose.h"
#include "decompose2.h"
#include "discover.h"
#include "estimate.h"
#include "extract_vntrs.h"
#include "filter_overlap.h"
#include "fuzzy_partition.h"
#include "genotype.h"
#include "hfilter.h"
#include "index.h"
#include "info2tab.h"
#include "info2tab_x.h"
#include "milk_filter.h"
#include "merge_candidate_variants.h"
#include "merge.h"
#include "multi_partition.h"
#include "normalize.h"
#include "partition.h"
#include "paste.h"
#include "paste_genotypes.h"
#include "paste_and_compute_features_sequential.h"
#include "peek.h"
#include "profile_afs.h"
#include "profile_chm1.h"
#include "profile_chrom.h"
#include "profile_fic_hwe.h"
#include "profile_hwe.h"
#include "profile_indels.h"
#include "profile_len.h"
#include "profile_mendelian.h"
#include "profile_na12878.h"
#include "profile_snps.h"
#include "profile_vntrs.h"
#include "rminfo.h"
#include "seq.h"
#include "set_ref.h"
#include "sort.h"
#include "subset.h"
#include "svm_predict.h"
#include "svm_train.h"
#include "test.h"
#include "union_variants.h"
#include "uniq.h"
#include "validate.h"
#include "version.h"
#include "view.h"
#include "vntrize.h"

void print_time(double t)
{
    if (t<60)
    {
        fprintf(stderr, "Time elapsed: %.2fs\n\n", t);
    }
    else if (t<60*60) //less than an hour
    {
        fprintf(stderr, "Time elapsed: %dm %ds\n\n", ((int32_t)(t/60)), ((int32_t)fmod(t, 60)));
    }
    else if (t<60*60*24) //less than a day
    {
        double m = fmod(t, 60*60); //remaining minutes
        fprintf(stderr, "Time elapsed: %dh %dm %ds\n\n", ((int32_t)(t/(60*60))), ((int32_t)(m/60)), ((int32_t)fmod(m, 60)));
    }
    else if (t<60*60*24*365) //less than a year
    {
        double h = fmod(t, 60*60*24); //remaining hours
        double m = fmod(h, 60*60); //remaining minutes
        fprintf(stderr, "Time elapsed: %dd %dh %dm %ds\n\n", ((int32_t)(t/(60*60*24))), ((int32_t)(h/(60*60))), ((int32_t)(m/60)), ((int32_t)fmod(m, 60)));
    }
};

void help()
{
    std::clog << "Help page on http://statgen.sph.umich.edu/wiki/Vt\n";
    std::clog << "\n";
    std::clog << "Useful tools:\n";
    std::clog << "view                      view vcf/vcf.gz/bcf files\n";
    std::clog << "index                     index vcf.gz/bcf files\n";
    std::clog << "normalize                 normalize variants\n";
    std::clog << "decompose                 decompose variants\n";
    std::clog << "uniq                      drop duplicate variants\n";
    std::clog << "cat                       concatenate VCF files\n";
    std::clog << "paste                     paste VCF files\n";
    std::clog << "sort                      sort VCF files\n";
    std::clog << "subset                    subset VCF file to variants polymorphic in a sample\n";
    std::clog << "\n";
    std::clog << "peek                      summary of variants in the vcf file\n";
    std::clog << "partition                 partition variants\n";
    std::clog << "multi_partition           partition variants from multiple VCF files\n";
    std::clog << "annotate_variants         annotate variants\n";
    std::clog << "annotate_db_rsid          annotate variants with dbSNP rsid\n";
    std::clog << "annotate_1000g            annotate variants with 1000 Genomes variants\n";
    std::clog << "annotate_regions          annotate regions\n";
    std::clog << "compute_concordance       compute genotype concordance between 2 call sets\n";
    std::clog << "compute_features          compute genotype likelihood based statistics\n";
    std::clog << "\n";
    std::clog << "discover                  discover variants\n";
    std::clog << "genotype                  genotype variants\n";
    std::clog << "\n";
}

int main(int argc, char ** argv)
{
    clock_t t0;
    t0 = clock();
    bool print = true;

    if (argc==1)
    {
        help();
        exit(0);
    }

    std::string cmd(argv[1]);

    //primitive programs that do not require help pages and summary statistics by default
    if (argc==2 && (cmd=="--version" || cmd=="-v"))
    {
        std::clog << "vt v" << VERSION << "\n";
        std::clog << "The MIT license\n";
        std::clog << "Copyright (c) 2013 Adrian Tan <atks@umich.edu>\n";
        exit(0);
    }
    else if (argc>1 && cmd=="view")
    {
        print = view(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="index")
    {
        print = index(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="merge")
    {
        print = merge(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste")
    {
        print = paste(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_and_compute_features_sequential")
    {
        paste_and_compute_features_sequential(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="cat")
    {
        print = cat(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="subset")
    {
        subset(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose")
    {
        decompose(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose2")
    {
        decompose2(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose_blocksub")
    {
        decompose_blocksub(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="extract_vntrs")
    {
        extract_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_vntrs")
    {
        annotate_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_genotypes")
    {
        paste_genotypes(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate_multiallelics")
    {
        consolidate_multiallelics(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_mendelian")
    {
        annotate_mendelian(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="normalize")
    {
        print = normalize(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="vntrize")
    {
        print = vntrize(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="validate")
    {
        print = validate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="rminfo")
    {
        print = rminfo(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="sort")
    {
        print = sort(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="config")
    {
        config(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="uniq")
    {
        uniq(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="set_ref")
    {
        set_ref(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="filter_overlap")
    {
        filter_overlap(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="peek")
    {
        peek(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="partition")
    {
        partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="fuzzy_partition")
    {
        fuzzy_partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="info2tab")
    {
        info2tab(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="info2tab+")
    {
        info2tab_x(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="svm_train")
    {
        svm_train(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="svm_predict")
    {
        svm_predict(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="multi_partition")
    {
        multi_partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_variants")
    {
        annotate_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_regions")
    {
        annotate_regions(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_dbsnp_rsid")
    {
        annotate_dbsnp_rsid(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="discover")
    {
        discover(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="merge_candidate_variants")
    {
        merge_candidate_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="union_variants")
    {
        union_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="genotype")
    {
        genotype(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="construct_probes")
    {
        construct_probes(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_rl_dist")
    {
        compute_rl_dist(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_vntrs")
    {
        profile_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_indels")
    {
        profile_indels(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_snps")
    {
        profile_snps(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="seq")
    {
        print = seq(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_mendelian")
    {
        profile_mendelian(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_na12878")
    {
        profile_na12878(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_chm1")
    {
        profile_chm1(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_chrom")
    {
        profile_chrom(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_and_compute_features_sequential")
    {
        paste_and_compute_features_sequential(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="milk_filter")
    {
        milk_filter(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="align")
    {
        align(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_features")
    {
        compute_features(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_concordance")
    {
        compute_concordance(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="estimate")
    {
        estimate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_afs")
    {
        profile_afs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_hwe")
    {
        profile_hwe(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_len")
    {
        profile_len(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_indels")
    {
        annotate_indels(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_1000g")
    {
        annotate_1000g(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate")
    {
        consolidate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate_vntrs")
    {
        consolidate_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="filter")
    {
        hfilter(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="test")
    {
        test(argc-1, ++argv);
    }
    else
    {
        std::clog << "Command not found: " << argv[1] << "\n\n";
        help();
        exit(1);
    }

    if (print)
    {
        clock_t t1;
        t1 = clock();
        print_time((float)(t1-t0)/CLOCKS_PER_SEC);
    }

    return 0;
}
<commit_msg>hidden changes<commit_after>/* The MIT Licensem

   Copyright (c) 2013 Adrian Tan <atks@umich.edu>

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "align.h"
#include "annotate_1000g.h"
#include "annotate_dbsnp_rsid.h"
#include "annotate_indels.h"
#include "annotate_mendelian.h"
#include "annotate_regions.h"
#include "annotate_variants.h"
#include "annotate_vntrs.h"
#include "cat.h"
#include "compute_features.h"
#include "compute_concordance.h"
#include "compute_rl_dist.h"
#include "config.h"
#include "consolidate.h"
#include "consolidate_multiallelics.h"
#include "consolidate_vntrs.h"
#include "construct_probes.h"
#include "decompose_blocksub.h"
#include "decompose.h"
#include "decompose2.h"
#include "discover.h"
#include "estimate.h"
#include "extract_vntrs.h"
#include "filter_overlap.h"
#include "fuzzy_partition.h"
#include "genotype.h"
#include "hfilter.h"
#include "index.h"
#include "info2tab.h"
#include "milk_filter.h"
#include "merge_candidate_variants.h"
#include "merge.h"
#include "multi_partition.h"
#include "normalize.h"
#include "partition.h"
#include "paste.h"
#include "paste_genotypes.h"
#include "paste_and_compute_features_sequential.h"
#include "peek.h"
#include "profile_afs.h"
#include "profile_chm1.h"
#include "profile_chrom.h"
#include "profile_fic_hwe.h"
#include "profile_hwe.h"
#include "profile_indels.h"
#include "profile_len.h"
#include "profile_mendelian.h"
#include "profile_na12878.h"
#include "profile_snps.h"
#include "profile_vntrs.h"
#include "rminfo.h"
#include "seq.h"
#include "set_ref.h"
#include "sort.h"
#include "subset.h"
#include "svm_predict.h"
#include "svm_train.h"
#include "test.h"
#include "union_variants.h"
#include "uniq.h"
#include "validate.h"
#include "version.h"
#include "view.h"
#include "vntrize.h"

void print_time(double t)
{
    if (t<60)
    {
        fprintf(stderr, "Time elapsed: %.2fs\n\n", t);
    }
    else if (t<60*60) //less than an hour
    {
        fprintf(stderr, "Time elapsed: %dm %ds\n\n", ((int32_t)(t/60)), ((int32_t)fmod(t, 60)));
    }
    else if (t<60*60*24) //less than a day
    {
        double m = fmod(t, 60*60); //remaining minutes
        fprintf(stderr, "Time elapsed: %dh %dm %ds\n\n", ((int32_t)(t/(60*60))), ((int32_t)(m/60)), ((int32_t)fmod(m, 60)));
    }
    else if (t<60*60*24*365) //less than a year
    {
        double h = fmod(t, 60*60*24); //remaining hours
        double m = fmod(h, 60*60); //remaining minutes
        fprintf(stderr, "Time elapsed: %dd %dh %dm %ds\n\n", ((int32_t)(t/(60*60*24))), ((int32_t)(h/(60*60))), ((int32_t)(m/60)), ((int32_t)fmod(m, 60)));
    }
};

void help()
{
    std::clog << "Help page on http://statgen.sph.umich.edu/wiki/Vt\n";
    std::clog << "\n";
    std::clog << "Useful tools:\n";
    std::clog << "view                      view vcf/vcf.gz/bcf files\n";
    std::clog << "index                     index vcf.gz/bcf files\n";
    std::clog << "normalize                 normalize variants\n";
    std::clog << "decompose                 decompose variants\n";
    std::clog << "uniq                      drop duplicate variants\n";
    std::clog << "cat                       concatenate VCF files\n";
    std::clog << "paste                     paste VCF files\n";
    std::clog << "sort                      sort VCF files\n";
    std::clog << "subset                    subset VCF file to variants polymorphic in a sample\n";
    std::clog << "\n";
    std::clog << "peek                      summary of variants in the vcf file\n";
    std::clog << "partition                 partition variants\n";
    std::clog << "multi_partition           partition variants from multiple VCF files\n";
    std::clog << "annotate_variants         annotate variants\n";
    std::clog << "annotate_db_rsid          annotate variants with dbSNP rsid\n";
    std::clog << "annotate_1000g            annotate variants with 1000 Genomes variants\n";
    std::clog << "annotate_regions          annotate regions\n";
    std::clog << "compute_concordance       compute genotype concordance between 2 call sets\n";
    std::clog << "compute_features          compute genotype likelihood based statistics\n";
    std::clog << "\n";
    std::clog << "discover                  discover variants\n";
    std::clog << "genotype                  genotype variants\n";
    std::clog << "\n";
}

int main(int argc, char ** argv)
{
    clock_t t0;
    t0 = clock();
    bool print = true;

    if (argc==1)
    {
        help();
        exit(0);
    }

    std::string cmd(argv[1]);

    //primitive programs that do not require help pages and summary statistics by default
    if (argc==2 && (cmd=="--version" || cmd=="-v"))
    {
        std::clog << "vt v" << VERSION << "\n";
        std::clog << "The MIT license\n";
        std::clog << "Copyright (c) 2013 Adrian Tan <atks@umich.edu>\n";
        exit(0);
    }
    else if (argc>1 && cmd=="view")
    {
        print = view(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="index")
    {
        print = index(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="merge")
    {
        print = merge(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste")
    {
        print = paste(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_and_compute_features_sequential")
    {
        paste_and_compute_features_sequential(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="cat")
    {
        print = cat(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="subset")
    {
        subset(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose")
    {
        decompose(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose2")
    {
        decompose2(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="decompose_blocksub")
    {
        decompose_blocksub(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="extract_vntrs")
    {
        extract_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_vntrs")
    {
        annotate_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_genotypes")
    {
        paste_genotypes(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate_multiallelics")
    {
        consolidate_multiallelics(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_mendelian")
    {
        annotate_mendelian(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="normalize")
    {
        print = normalize(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="vntrize")
    {
        print = vntrize(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="validate")
    {
        print = validate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="rminfo")
    {
        print = rminfo(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="sort")
    {
        print = sort(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="config")
    {
        config(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="uniq")
    {
        uniq(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="set_ref")
    {
        set_ref(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="filter_overlap")
    {
        filter_overlap(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="peek")
    {
        peek(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="partition")
    {
        partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="fuzzy_partition")
    {
        fuzzy_partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="info2tab")
    {
        info2tab(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="info2tab+")
    {
        info2tab_x(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="svm_train")
    {
        svm_train(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="svm_predict")
    {
        svm_predict(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="multi_partition")
    {
        multi_partition(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_variants")
    {
        annotate_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_regions")
    {
        annotate_regions(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_dbsnp_rsid")
    {
        annotate_dbsnp_rsid(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="discover")
    {
        discover(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="merge_candidate_variants")
    {
        merge_candidate_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="union_variants")
    {
        union_variants(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="genotype")
    {
        genotype(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="construct_probes")
    {
        construct_probes(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_rl_dist")
    {
        compute_rl_dist(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_vntrs")
    {
        profile_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_indels")
    {
        profile_indels(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_snps")
    {
        profile_snps(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="seq")
    {
        print = seq(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_mendelian")
    {
        profile_mendelian(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_na12878")
    {
        profile_na12878(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_chm1")
    {
        profile_chm1(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_chrom")
    {
        profile_chrom(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="paste_and_compute_features_sequential")
    {
        paste_and_compute_features_sequential(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="milk_filter")
    {
        milk_filter(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="align")
    {
        align(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_features")
    {
        compute_features(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="compute_concordance")
    {
        compute_concordance(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="estimate")
    {
        estimate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_afs")
    {
        profile_afs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_hwe")
    {
        profile_hwe(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="profile_len")
    {
        profile_len(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_indels")
    {
        annotate_indels(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="annotate_1000g")
    {
        annotate_1000g(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate")
    {
        consolidate(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="consolidate_vntrs")
    {
        consolidate_vntrs(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="filter")
    {
        hfilter(argc-1, ++argv);
    }
    else if (argc>1 && cmd=="test")
    {
        test(argc-1, ++argv);
    }
    else
    {
        std::clog << "Command not found: " << argv[1] << "\n\n";
        help();
        exit(1);
    }

    if (print)
    {
        clock_t t1;
        t1 = clock();
        print_time((float)(t1-t0)/CLOCKS_PER_SEC);
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * fast_mmi_master.cc
 */
#include "fast_mmi_master.h"
#include <iostream>

namespace qvmmi {
	FastMMIMaster::FastMMIMaster(const Matrix& mat) :
		iter_(mat) {}

	void FastMMIMaster::run() {
		/*
		 * Keep track of how many tasks were originally submitted. It oculd happen
		 * that fewer tasks are generated and sent than there are cores, so don't
		 * want to be waiting for tasks to return which were never submitted.
		 */
		int submitted = 0;
		/* Send initial matrices to workers. */
		for(int i = 1; i < num_proc_ && iter_.has_next(); ++i) {
			Matrix matrix = iter_.next();
			send_matrix(matrix, i);
			map_[i] = matrix;
			submitted++;
		}

		while(iter_.has_next()) {
			int result = receive_result();
			int worker = status_.Get_source();
			handle_result(result, worker);
			Matrix matrix = iter_.next();
			send_matrix(matrix, worker);
			map_[worker] = matrix;
		}
		/* Wait for remaining tasks. */
		for(int i = 1; i < submitted; ++i) {
			int result = receive_result();
			int worker = status_.Get_source();
			handle_result(result, worker);
		}
		send_shutdown();
	}

	void FastMMIMaster::handle_result(int result, int worker) {
		if(result == 1) {
			/* Matrix is mmi. */
			Matrix mat = map_[worker];
			std::cout << mat << std::endl;
		}
	}

}

<commit_msg>Changes the submitted counter to include the very last task which was previously being skipped. This was changed in SlowCheckMaster earlier, but not in FastMMIMaster.<commit_after>/*
 * fast_mmi_master.cc
 */
#include "fast_mmi_master.h"
#include <iostream>

namespace qvmmi {
	FastMMIMaster::FastMMIMaster(const Matrix& mat) :
		iter_(mat) {}

	void FastMMIMaster::run() {
		/*
		 * Keep track of how many tasks were originally submitted. It oculd happen
		 * that fewer tasks are generated and sent than there are cores, so don't
		 * want to be waiting for tasks to return which were never submitted.
		 */
		int submitted = 1;
		/* Send initial matrices to workers. */
		for(int i = 1; i < num_proc_ && iter_.has_next(); ++i) {
			Matrix matrix = iter_.next();
			send_matrix(matrix, i);
			map_[i] = matrix;
			submitted++;
		}

		while(iter_.has_next()) {
			int result = receive_result();
			int worker = status_.Get_source();
			handle_result(result, worker);
			Matrix matrix = iter_.next();
			send_matrix(matrix, worker);
			map_[worker] = matrix;
		}
		/* Wait for remaining tasks. */
		for(int i = 1; i < submitted; ++i) {
			int result = receive_result();
			int worker = status_.Get_source();
			handle_result(result, worker);
		}
		send_shutdown();
	}

	void FastMMIMaster::handle_result(int result, int worker) {
		if(result == 1) {
			/* Matrix is mmi. */
			Matrix mat = map_[worker];
			std::cout << mat << std::endl;
		}
	}

}

<|endoftext|>


<commit_before>#include <vexcl/devlist.hpp>
#include <vexcl/spmat.hpp>
#include <vexcl/vector.hpp>

#include <blaze/math/CompressedMatrix.h>
#include <blaze/math/DynamicVector.h>
#include <blaze/math/DenseSubvector.h>

#include <blaze/util/serialization/Archive.h>
#include <blaze/math/serialization/MatrixSerializer.h>
#include <blaze/math/serialization/VectorSerializer.h>

#include <vector>
#include <sstream>
#include <string>
#include <iostream>

void ConvertSpMat(std::vector<size_t>& row, std::vector<size_t>& col, std::vector<double>& val, blaze::CompressedMatrix<double>& mat) {
	uint non_zeros = mat.nonZeros();
	row.clear();
	col.clear();
	val.clear();
	uint count = 0;
	for (int i = 0; i < mat.rows(); ++i) {
		row.push_back(count);
		for (blaze::CompressedMatrix<double>::Iterator it = mat.begin(i); it != mat.end(i); ++it) {
			col.push_back(it->index());
			val.push_back(it->value());
			count++;
		}
	}
	row.push_back(count);
}

std::string slurp(std::string fname){
	std::ifstream file(fname.c_str());
	std::string buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
	return buffer;
}

void readSPMAT(std::string & data, blaze::CompressedMatrix<double> & mat){
	std::stringstream ss(data);

	uint rows, cols, nonzeros;
	ss>>rows>>cols>>nonzeros;
	//printf("INFO: rows: %d, columns: %d, non zeros: %d\n",rows, cols, nonzeros);
	mat.resize(rows,cols);
	mat.reserve(nonzeros);
	uint row_nonzeros;
	uint colval;
	double v;

	for(int i=0; i<rows; i++){
		if(i%1000000==0){printf("%d, ",i);}

		ss>>row_nonzeros;

		for(int j=0; j<row_nonzeros; j++){
			ss>>colval>>v;
			mat.append(i,colval,v);
		}
		mat.finalize(i);
	}
	printf("\n");
}
void readVector(std::string & data, std::vector<double> & vec){
	std::stringstream ss(data);

	uint size;
	ss>>size;
	vec.resize(size);

	//printf("INFO: size: %d\n",size);
	double v;
	for(int i=0; i<size; i++){
		ss>>v;
		vec[i] = v;
	}
}
int main(int argc, char* argv[]){
	printf("start execution \n");
	vex::Context ctx(vex::Filter::Env && vex::Filter::DoublePrecision);
	std::cout<<ctx<<std::endl;
	printf("create context \n");

	blaze::CompressedMatrix<double> D_T, M_invD;
	std::vector<double> g,b;
	printf("read D^T \n");
	{
		std::string data = slurp("D_T.mat");
		readSPMAT(data, D_T);
	}

	{
		std::string data = slurp("M_invD.mat");
		readSPMAT(data, M_invD);
	}
	{
		std::string data = slurp("gamma.vec");
		readVector(data, g);
	}

	{
		std::string data = slurp("b.vec");
		readVector(data, b);
	}

	printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T.rows(), D_T.columns(), D_T.nonZeros());
	printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD.rows(), M_invD.columns(), M_invD.nonZeros());
	printf("gamma: size: %d\n", g.size());
	printf("b: size: %d\n", b.size());

	std::vector<size_t> row;
	std::vector<size_t> col;
	std::vector<double> val;

	ConvertSpMat(row, col, val, D_T);
	vex::SpMat<double> _D_T(ctx, D_T.rows(), D_T.columns(), row.data(), col.data(), val.data());

	ConvertSpMat(row, col, val, M_invD);
	vex::SpMat<double> _M_invD(ctx, M_invD.rows(), M_invD.columns(), row.data(), col.data(), val.data());

	blaze::DynamicVector<double> gamma(g.size()),rhs(g.size());

	for(int i=0; i<g.size(); i++){
		gamma[i] = g[i];
		rhs[i] = b[i];
	}
	blaze::DynamicVector<double> tmp_cpu(g.size());
	blaze::DynamicVector<double> res_cpu(g.size());
	double start_cpu = omp_get_wtime();

	double RUNS = 1;
	if(argc>1){
		RUNS=atoi(argv[1]);
	}
	for(size_t i = 0; i < RUNS; i++){
		tmp_cpu = M_invD*gamma;
		res_cpu += D_T*tmp_cpu;
	}
	double end_cpu = omp_get_wtime();

	vex::profiler<> prof;

	vex::vector<double> gamma_gpu(ctx,g.size());
	vex::vector<double> b_gpu(ctx,b.size());
	vex::copy(g,gamma_gpu);
	vex::copy(b,b_gpu);
	vex::vector<double> tmp_gpu(ctx,g.size());
	vex::vector<double> res_gpu(ctx,g.size());

	tmp_gpu += _M_invD*gamma_gpu;
	tmp_gpu = 0;
	res_gpu += _D_T*tmp_gpu;
	res_gpu = 0;
	prof.tic_cpu("GPU");
	double start_gpu = omp_get_wtime();
	for(size_t i = 0; i < RUNS; i++){
		tmp_gpu  = _M_invD*gamma_gpu;
		res_gpu  += _D_T*tmp_gpu;
	}
	ctx.finish();
	double end_gpu = omp_get_wtime();
	double tot_time = prof.toc("GPU");
	printf("CPU took %f sec. time.\n", (end_cpu-start_cpu)/RUNS);
	printf("GPU took %f sec. time, %f sec time.\n", (end_gpu-start_gpu)/RUNS, tot_time/RUNS);
	printf("Speedup: %f\n", (end_cpu-start_cpu) /(end_gpu-start_gpu));

	//std::vector<double> res_host(g.size());

	//vex::copy(res_gpu,res_host);

	//printf("copy\n");
	// for(int i=0; i<g.size(); i++){
	// 	if(res_host[i]!=res_cpu[i]){
	// 		printf("%f\n",res_host[i]-res_cpu[i]);
	// 	}
	// }

	return 0;
}<commit_msg>Update gflops and transfer<commit_after>#include <vexcl/devlist.hpp>
#include <vexcl/spmat.hpp>
#include <vexcl/vector.hpp>

#include <blaze/math/CompressedMatrix.h>
#include <blaze/math/DynamicVector.h>
#include <blaze/math/DenseSubvector.h>

#include <blaze/util/serialization/Archive.h>
#include <blaze/math/serialization/MatrixSerializer.h>
#include <blaze/math/serialization/VectorSerializer.h>

#include <vector>
#include <sstream>
#include <string>
#include <iostream>

void ConvertSpMat(std::vector<size_t>& row, std::vector<size_t>& col, std::vector<double>& val, blaze::CompressedMatrix<double>& mat) {
	uint non_zeros = mat.nonZeros();
	row.clear();
	col.clear();
	val.clear();
	uint count = 0;
	for (int i = 0; i < mat.rows(); ++i) {
		row.push_back(count);
		for (blaze::CompressedMatrix<double>::Iterator it = mat.begin(i); it != mat.end(i); ++it) {
			col.push_back(it->index());
			val.push_back(it->value());
			count++;
		}
	}
	row.push_back(count);
}

std::string slurp(std::string fname){
	std::ifstream file(fname.c_str());
	std::string buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
	return buffer;
}

void readSPMAT(std::string & data, blaze::CompressedMatrix<double> & mat){
	std::stringstream ss(data);

	uint rows, cols, nonzeros;
	ss>>rows>>cols>>nonzeros;
	//printf("INFO: rows: %d, columns: %d, non zeros: %d\n",rows, cols, nonzeros);
	mat.resize(rows,cols);
	mat.reserve(nonzeros);
	uint row_nonzeros;
	uint colval;
	double v;

	for(int i=0; i<rows; i++){
		if(i%1000000==0){printf("%d, ",i);}

		ss>>row_nonzeros;

		for(int j=0; j<row_nonzeros; j++){
			ss>>colval>>v;
			mat.append(i,colval,v);
		}
		mat.finalize(i);
	}
	printf("\n");
}
void readVector(std::string & data, std::vector<double> & vec){
	std::stringstream ss(data);

	uint size;
	ss>>size;
	vec.resize(size);

	//printf("INFO: size: %d\n",size);
	double v;
	for(int i=0; i<size; i++){
		ss>>v;
		vec[i] = v;
	}
}
int main(int argc, char* argv[]){
	vex::profiler<> prof;
	vex::Context ctx(vex::Filter::Env && vex::Filter::DoublePrecision);
	std::cout<<ctx<<std::endl;
	printf("create context \n");

	blaze::CompressedMatrix<double> D_T, M_invD;
	std::vector<double> g,b;
	printf("read D^T \n");
	{
		std::string data = slurp("D_T.mat");
		readSPMAT(data, D_T);
	}

	{
		std::string data = slurp("M_invD.mat");
		readSPMAT(data, M_invD);
	}
	{
		std::string data = slurp("gamma.vec");
		readVector(data, g);
	}

	{
		std::string data = slurp("b.vec");
		readVector(data, b);
	}

	printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T.rows(), D_T.columns(), D_T.nonZeros());
	printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD.rows(), M_invD.columns(), M_invD.nonZeros());
	printf("gamma: size: %d\n", g.size());
	printf("b: size: %d\n", b.size());

	std::vector<size_t> row;
	std::vector<size_t> col;
	std::vector<double> val;

	ConvertSpMat(row, col, val, D_T);
	vex::SpMat<double> _D_T(ctx, D_T.rows(), D_T.columns(), row.data(), col.data(), val.data());

	ConvertSpMat(row, col, val, M_invD);
	vex::SpMat<double> _M_invD(ctx, M_invD.rows(), M_invD.columns(), row.data(), col.data(), val.data());

	blaze::DynamicVector<double> gamma(g.size()),rhs(g.size());

	for(int i=0; i<g.size(); i++){
		gamma[i] = g[i];
		rhs[i] = b[i];
	}
	blaze::DynamicVector<double> tmp_cpu(g.size());
	blaze::DynamicVector<double> res_cpu(g.size());

	prof.tic_cpu("CPU");

	double RUNS = 1;
	if(argc>1){
		RUNS=atoi(argv[1]);
	}
	for(size_t i = 0; i < RUNS; i++){
		tmp_cpu = M_invD*gamma;
		res_cpu += D_T*tmp_cpu;
	}
double cpu_time = prof.toc("CPU");

	vex::vector<double> gamma_gpu(ctx,g.size());
	vex::vector<double> b_gpu(ctx,b.size());
	vex::copy(g,gamma_gpu);
	vex::copy(b,b_gpu);
	vex::vector<double> tmp_gpu(ctx,g.size());
	vex::vector<double> res_gpu(ctx,g.size());

	tmp_gpu += _M_invD*gamma_gpu;
	tmp_gpu = 0;
	res_gpu += _D_T*tmp_gpu;
	res_gpu = 0;
	prof.tic_cpu("GPU");
	double start_gpu = omp_get_wtime();
	for(size_t i = 0; i < RUNS; i++){
		tmp_gpu  = _M_invD*gamma_gpu;
		res_gpu  += _D_T*tmp_gpu;
	}
	ctx.finish();
	double end_gpu = omp_get_wtime();
	double gpu_time = prof.toc("GPU");
	//Two Spmv each with 2*nnz operations
	uint operations = 2 * 2 * D_T.nonZeros();
	uint moved = 2* (D_T.nonZeros() + 2* D_T.rows()) * sizeof(double);

	double cpu_single = cpu_time/RUNS;
	double gpu_single = gpu_time/RUNS;
	double GFLOP = 1000000000;
	printf("CPU %f sec. GPU %f sec.\n", cpu_single,gpu_single);
	printf("Speedup: %f\n", cpu_single /gpu_single);
	printf("Flops: CPU: %f GPU: %f\n", operations/cpu_single/GFLOP,operations/gpu_single/GFLOP);
	printf("Bandwidth: CPU: %f GPU: %f\n", moved/cpu_single/GFLOP, moved /gpu_single/GFLOP);

	//std::vector<double> res_host(g.size());

	//vex::copy(res_gpu,res_host);

	//printf("copy\n");
	// for(int i=0; i<g.size(); i++){
	// 	if(res_host[i]!=res_cpu[i]){
	// 		printf("%f\n",res_host[i]-res_cpu[i]);
	// 	}
	// }

	return 0;
}<|endoftext|>


<commit_before>07a6ac51-ad5d-11e7-9eeb-ac87a332f658<commit_msg>Put the thingie in the thingie<commit_after>082e44ca-ad5d-11e7-ba87-ac87a332f658<|endoftext|>


<commit_before>/* The MIT License (MIT)
 *
 * Copyright (c) 2015 Giovanni Ortolani, Taneli Mikkonen, Pingjiang Li, Tommi Puolamaa, Mitra Vahida
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE. */

#include <iostream>
#include <exception>

#include "initOgre.h"
#include "PSphere.h"
#include "Common.h"
#include "Test.h"
#include "testui2/mainwindow.h"
#include <QApplication>
#include "ResourceParameter.h"
#include <QDebug>

using namespace std;

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include <io.h>
#include <fcntl.h>
#include "windows.h"
#endif

int main(int argc, char *argv[])
{
	if(argc==1) //no arguments, run planet generator
	{
		unsigned int fontSize;
		//#pragma comment( linker, "/subsystem:windows" )
		QApplication a(argc, argv);
		MainWindow w;

		// Calculate fontsize. size 8 is for dpi 96
		fontSize = 8;
		qDebug() << "DPI is:" << w.logicalDpiX() << w.logicalDpiY();
		fontSize = roundf(((float)fontSize+0.25f) * (96.0f / w.logicalDpiY()));
		qDebug() << "Setting fontsize to:" << fontSize;

		QFont font("Arial", fontSize);
		a.setFont(font);

		w.show();
		a.exec();
	}else if(argc==2 && (std::strcmp(argv[1],"t")==0) )
	{
#ifdef linux

		cout<<"  linux OS!"<<endl;

#endif
#ifdef __WINDOWS_

		AllocConsole();
		HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
		int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
		FILE* hf_out = _fdopen(hCrt, "w");
		setvbuf(hf_out, NULL, _IONBF, 1);
		*stdout = *hf_out;

		HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
		hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
		FILE* hf_in = _fdopen(hCrt, "r");
		setvbuf(hf_in, NULL, _IONBF, 128);
		*stdin = *hf_in;
		cout<<"  Windows OS!  "<<endl;

#endif
#ifdef _WIN32
		AllocConsole();
		HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
		int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
		FILE* hf_out = _fdopen(hCrt, "w");
		setvbuf(hf_out, NULL, _IONBF, 1);
		*stdout = *hf_out;

		HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
		hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
		FILE* hf_in = _fdopen(hCrt, "r");
		setvbuf(hf_in, NULL, _IONBF, 128);
		*stdin = *hf_in;
		cout<<"  WIN32 OS!  "<<endl;
#endif

		cout << "Testing Mode" << endl;
		testAll();
		cout << "Test Ended. Press Enter to exit." << endl;
		cin.get();
	}

	return 0;
}
<commit_msg>Fixed roundf function (not supported in msvc)<commit_after>/* The MIT License (MIT)
 *
 * Copyright (c) 2015 Giovanni Ortolani, Taneli Mikkonen, Pingjiang Li, Tommi Puolamaa, Mitra Vahida
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE. */

#include <iostream>
#include <exception>

#include "initOgre.h"
#include "PSphere.h"
#include "Common.h"
#include "Test.h"
#include "testui2/mainwindow.h"
#include <QApplication>
#include "ResourceParameter.h"
#include <QDebug>

using namespace std;

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include <io.h>
#include <fcntl.h>
#include "windows.h"
#endif

int main(int argc, char *argv[])
{
	if(argc==1) //no arguments, run planet generator
	{
		unsigned int fontSize;
		//#pragma comment( linker, "/subsystem:windows" )
		QApplication a(argc, argv);
		MainWindow w;

		// Calculate fontsize. size 8 is for dpi 96
		fontSize = 8;
		qDebug() << "DPI is:" << w.logicalDpiX() << w.logicalDpiY();
		fontSize = (unsigned int)((((float)fontSize+0.25f) * (96.0f / w.logicalDpiY()))+0.5f);
		qDebug() << "Setting fontsize to:" << fontSize;

		QFont font("Arial", fontSize);
		a.setFont(font);

		w.show();
		a.exec();
	}else if(argc==2 && (std::strcmp(argv[1],"t")==0) )
	{
#ifdef linux

		cout<<"  linux OS!"<<endl;

#endif
#ifdef __WINDOWS_

		AllocConsole();
		HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
		int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
		FILE* hf_out = _fdopen(hCrt, "w");
		setvbuf(hf_out, NULL, _IONBF, 1);
		*stdout = *hf_out;

		HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
		hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
		FILE* hf_in = _fdopen(hCrt, "r");
		setvbuf(hf_in, NULL, _IONBF, 128);
		*stdin = *hf_in;
		cout<<"  Windows OS!  "<<endl;

#endif
#ifdef _WIN32
		AllocConsole();
		HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
		int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
		FILE* hf_out = _fdopen(hCrt, "w");
		setvbuf(hf_out, NULL, _IONBF, 1);
		*stdout = *hf_out;

		HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
		hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
		FILE* hf_in = _fdopen(hCrt, "r");
		setvbuf(hf_in, NULL, _IONBF, 128);
		*stdin = *hf_in;
		cout<<"  WIN32 OS!  "<<endl;
#endif

		cout << "Testing Mode" << endl;
		testAll();
		cout << "Test Ended. Press Enter to exit." << endl;
		cin.get();
	}

	return 0;
}
<|endoftext|>


<commit_before>/**
 * SUBLEQ Assembly: main.cpp
 *
 *  Created on: Apr 9, 2014
 *      Author:       Pimenta
 *      Collaborator: Alexandre Dantas
 *
 * This program reads a SUBLEQ Assembly file and outputs
 * a well-formed object file.
 * It's supposed to be fed to the Linker.
 */

#include <cstdint>
#include <cstdio>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <sstream>

using namespace std;

typedef uint32_t uword_t;

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

static fstream f;

/// Global buffer that will hold the current line
/// when reading the file.
static string buf;

/// Set of all exported symbols.
/// They're used together with other object files
/// on the linker.
static set<string> exported;

/// All current symbols of this file.
/// Maps from a label to it's address in memory.
static map<string, uword_t> symbols;

/// Contains all symbols not found on this file.
///
/// It has labels supposed to be found on other
/// Assembly files.
/// They'll get resolved with the external symbols.
static map<string, set<uword_t>> references;

/// Relative addresses found on this file.
///
/// When you "call" a symbol on this file, it's address
/// is relative to the start of this file.
///
/// When the Linker joins several object files, it will
/// use the values on this set to relocate them all.
///
static set<uword_t> relatives;

/// Current size of the memory.
/// While parsing: points the current memory address
///                being read.
/// At the end:    has the entire size of the memory
///                read.
static uword_t mem_size = 0;

/// Raw memory.
/// It contains the assembled memory that will get
/// written at the end of the object file.
static uword_t* mem = new uword_t[MEM_WORDS];

static int currentLine = 1, lastTokenLine = 1, currentTokenLine = 1;

/// Reads a token (separated by whitespaces) from the file,
/// char by char, putting on `buf`
inline static void readToken() {
  buf = "";
  lastTokenLine = currentTokenLine;

  for (char c = f.get(); f.good(); c = f.get()) {
    // comment found
    if (c == '/') {

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine;
        return;
      }

      // ignoring entire comment
      for (c = f.get(); c != '\r' && c != '\n' && f.good(); c = f.get());

      // checking for CR or CRLF line endings
      if (c == '\r') {
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }

      currentLine++;
      continue;
    }

    // line break found
    if (c == '\r' || c == '\n') {

      // checking for CR or CRLF line endings
      if (c == '\r') {
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine++;
        return;
      }

      currentLine++;
      continue;
    }

    // white space found
    if (c == ' ' || c == '\t') {

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine;
        return;
      }
      continue;
    }

    // this character was none of the above
    // simply appending it
    buf += c;
  }

  currentTokenLine = currentLine;
}

/// Returns text on `buf` as data.
///
/// Converts textual data to words.
/// For example, converts "0x1" to 1.
inline static uword_t parseData() {
  uword_t data = 0;
  if (buf[0] == '0' && buf[1] == 'x') { // for hex notation
    sscanf(buf.c_str(), "%i", &data);
  }
  else { // for decimal notation
    stringstream ss;
    ss << buf;
    ss >> data;
  }
  return data;
}

/// Parses a single field contained on `buf`.
///
/// So for `SUBLEQ A B C` we call this function three times,
/// once for each field A, B and C.
///
/// Returns the address being "called" by the field.
///
/// For example, if we have:
///
///     .data
///         one: 1
///     .text
///       loop:
///         one one loop
///
/// For `one` on `loop:` it returns 0, since it's the
/// address of the thing being "called" by the instruction.
///
inline static uword_t parseField() {
  uword_t field = 0;
  // hex notation means absolute address
  if (buf[0] == '0' && buf[1] == 'x') {
    sscanf(buf.c_str(), "%i", &field);
  }
  // symbol means an address that needs to be relocated later
  else {
    relatives.emplace(mem_size);

    // looking for array offset
    if (buf.find("+") != buf.npos) {
      string offset = buf.substr(buf.find("+") + 1, buf.size());
      buf = buf.substr(0, buf.find("+"));
      stringstream ss;
      ss << offset;
      ss >> field;
    }

    auto sym = symbols.find(buf);
    // symbol not found. leave a reference
    if (sym == symbols.end()) {
      references[buf].emplace(mem_size);
    }
    // symbol found. the field is the address of the symbol
    else {
      field = sym->second;
    }
  }
  return field;
}

int main(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  readToken(); // reading ".export"

  // reading export section
  for (readToken(); buf != ".data"; readToken()) {
    exported.insert(buf);
  }

  // reading data section
  for (readToken(); buf != ".text";) {
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    readToken();
    if (buf == ".array") { // uninitialized array
      readToken();
      mem_size += parseData();
      readToken(); // next symbol
    }
    else if (buf == ".iarray") { // initialized array
      for (readToken(); currentTokenLine == lastTokenLine; readToken()) {
        mem[mem_size++] = parseData();
      }
    }
    else if (buf == ".ptr") { // pointer
      readToken();
      mem[mem_size] = parseField();
      mem_size++;
      readToken(); // next symbol
    }
    else { // initialized word
      mem[mem_size++] = parseData();
      readToken(); // next symbol
    }
  }

  // reading text section
  int field = 0;
  for (readToken(); buf.size();) {
    // field 2 omitted
    if (field == 2 && currentTokenLine != lastTokenLine) {
      relatives.emplace(mem_size);
      mem[mem_size] = mem_size + 1;
      mem_size++;
      field = (field + 1)%3;
    }
    // symbol found
    else if (buf[buf.size() - 1] == ':') {
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;
      if (buf == "start:")
        exported.emplace("start");
      readToken();
    }
    // field 0, 1, or field 2 specified
    else {
      mem[mem_size] = parseField();
      mem_size++;
      field = (field + 1)%3;
      readToken();
    }
  }

  f.close();

  // resolve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // resolve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      mem[*it] += sym->second;
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uword_t tmp;

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uword_t));

      // write references to current symbol
      for (auto ref : sym.second) {
        tmp = ref;
        f.write((const char*)&tmp, sizeof(uword_t));
      }
    }

    // write number of relative addresses
    tmp = relatives.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write relative addresses
    for (auto addr : relatives) {
      tmp = addr;
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(uword_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<commit_msg>More stylistic changes<commit_after>/**
 * SUBLEQ Assembly: main.cpp
 *
 *  Created on: Apr 9, 2014
 *      Author:       Pimenta
 *      Collaborator: Alexandre Dantas
 *
 * This program reads a SUBLEQ Assembly file and outputs
 * a well-formed object file.
 * It's supposed to be fed to the Linker.
 */

#include <cstdint>
#include <cstdio>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <sstream>

using namespace std;

typedef uint32_t uword_t;

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

static fstream f;

/// Global buffer that always contains the current
/// token being read by `readToken`
static string buf;

/// Set of all exported symbols.
/// They're used together with other object files
/// on the linker.
static set<string> exported;

/// All current symbols of this file.
/// Maps from a label to it's address in memory.
static map<string, uword_t> symbols;

/// Contains all symbols not found on this file.
///
/// It has labels supposed to be found on other
/// Assembly files.
/// They'll get resolved with the external symbols.
static map<string, set<uword_t>> references;

/// Relative addresses found on this file.
///
/// When you "call" a symbol on this file, it's address
/// is relative to the start of this file.
///
/// When the Linker joins several object files, it will
/// use the values on this set to relocate them all.
///
static set<uword_t> relatives;

/// Current size of the memory.
/// While parsing: points the current memory address
///                being read.
/// At the end:    has the entire size of the memory
///                read.
static uword_t mem_size = 0;

/// Raw memory.
/// It contains the assembled memory that will get
/// written at the end of the object file.
static uword_t* mem = new uword_t[MEM_WORDS];

static int currentLine = 1, lastTokenLine = 1, currentTokenLine = 1;

/// Reads a token (separated by whitespaces) from the file,
/// char by char, putting on `buf`
inline static void readToken() {
  buf = "";
  lastTokenLine = currentTokenLine;

  // Will read all chars until:
  //
  // - Finding a whitespace (or tab)
  // - Finding a comment
  // - Finding an end-of-line
  // - File somehow ends
  //
  while (true)
  {
    char c = f.get();

    if (!f.good())
	    break;

    // comment found
    if (c == '/') {

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine;
        return;
      }

      // ignoring entire comment
      do {
        c = f.get();
      } while (c != '\r' && c != '\n' && f.good());

      // checking for CR or CRLF line endings
      if (c == '\r') {
        c = f.get();

        if (f.good() && c != '\n')
          f.unget();
      }

      currentLine++;
      continue;
    }

    // line break found
    if (c == '\r' || c == '\n') {

      // checking for CR or CRLF line endings
      if (c == '\r') {
        c = f.get();

        if (f.good() && c != '\n')
          f.unget();
      }

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine++;
        return;
      }

      currentLine++;
      continue;
    }

    // white space found
    if (c == ' ' || c == '\t') {

      // token was read
      if (buf.size()) {
        currentTokenLine = currentLine;
        return;
      }
      continue;
    }

    // this character was none of the above
    // simply appending it
    buf += c;
  }

  currentTokenLine = currentLine;
}

/// Returns text on `buf` as data.
///
/// Converts textual data to words.
/// For example, converts "0x1" to 1.
inline static uword_t parseData() {
  uword_t data = 0;
  if (buf[0] == '0' && buf[1] == 'x') { // for hex notation
    sscanf(buf.c_str(), "%i", &data);
  }
  else { // for decimal notation
    stringstream ss;
    ss << buf;
    ss >> data;
  }
  return data;
}

/// Parses a single field contained on `buf`.
///
/// So for `SUBLEQ A B C` we call this function three times,
/// once for each field A, B and C.
///
/// Returns the address being "called" by the field.
///
/// For example, if we have:
///
///     .data
///         one: 1
///     .text
///       loop:
///         one one loop
///
/// For `one` on `loop:` it returns 0, since it's the
/// address of the thing being "called" by the instruction.
///
inline static uword_t parseField() {
  uword_t field = 0;
  // hex notation means absolute address
  if (buf[0] == '0' && buf[1] == 'x') {
    sscanf(buf.c_str(), "%i", &field);
  }
  // symbol means an address that needs to be relocated later
  else {
    relatives.emplace(mem_size);

    // looking for array offset
    if (buf.find("+") != buf.npos) {
      string offset = buf.substr(buf.find("+") + 1, buf.size());
      buf = buf.substr(0, buf.find("+"));
      stringstream ss;
      ss << offset;
      ss >> field;
    }

    auto sym = symbols.find(buf);
    // symbol not found. leave a reference
    if (sym == symbols.end()) {
      references[buf].emplace(mem_size);
    }
    // symbol found. the field is the address of the symbol
    else {
      field = sym->second;
    }
  }
  return field;
}

int main(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  readToken(); // reading ".export"

  // reading export section
  for (readToken(); buf != ".data"; readToken()) {
    exported.insert(buf);
  }

  // reading data section
  for (readToken(); buf != ".text";) {
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    readToken();
    if (buf == ".array") { // uninitialized array
      readToken();
      mem_size += parseData();
      readToken(); // next symbol
    }
    else if (buf == ".iarray") { // initialized array
      for (readToken(); currentTokenLine == lastTokenLine; readToken()) {
        mem[mem_size++] = parseData();
      }
    }
    else if (buf == ".ptr") { // pointer
      readToken();
      mem[mem_size] = parseField();
      mem_size++;
      readToken(); // next symbol
    }
    else { // initialized word
      mem[mem_size++] = parseData();
      readToken(); // next symbol
    }
  }

  // reading text section
  int field = 0;
  for (readToken(); buf.size();) {
    // field 2 omitted
    if (field == 2 && currentTokenLine != lastTokenLine) {
      relatives.emplace(mem_size);
      mem[mem_size] = mem_size + 1;
      mem_size++;
      field = (field + 1)%3;
    }
    // symbol found
    else if (buf[buf.size() - 1] == ':') {
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;
      if (buf == "start:")
        exported.emplace("start");
      readToken();
    }
    // field 0, 1, or field 2 specified
    else {
      mem[mem_size] = parseField();
      mem_size++;
      field = (field + 1)%3;
      readToken();
    }
  }

  f.close();

  // resolve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // resolve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      mem[*it] += sym->second;
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uword_t tmp;

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uword_t));

      // write references to current symbol
      for (auto ref : sym.second) {
        tmp = ref;
        f.write((const char*)&tmp, sizeof(uword_t));
      }
    }

    // write number of relative addresses
    tmp = relatives.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write relative addresses
    for (auto addr : relatives) {
      tmp = addr;
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(uword_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <array>
#include <exception>
#include <fstream>
#include <iostream>
#include <unordered_map>

#include "ArgumentParser.hpp"
#include "Brainfuck.hpp"
#include "version.h"

#if __cplusplus >= 201103L
#  define NOEXCEPT  noexcept
#else
#  define NOEXCEPT  throw()
#endif

static void
showVersion() NOEXCEPT;

static std::string
removeDirectoryPart(const std::string& filepath) NOEXCEPT;

static std::string
removeSuffix(const std::string& filename) NOEXCEPT;

int
main(int argc, const char* argv[])
{
  std::unordered_map<std::string, Brainfuck::Target> targetMap{
    {"c", Brainfuck::Target::kC},
    {"xbyakc", Brainfuck::Target::kXbyakC},
    {"winx86", Brainfuck::Target::kWinX86},
    {"winx64", Brainfuck::Target::kWinX64},
    {"elfx86", Brainfuck::Target::kElfX86},
    {"elfx64", Brainfuck::Target::kElfX64},
    {"elfarmeabi", Brainfuck::Target::kElfArmeabi}
  };

  try {
    ArgumentParser ap(argv[0]);
    ap.add('h', "help", "Show help and exit this program");
    ap.add('m', "minify", "Remove all non-brainfuck characters from source code");
    ap.add('t', "target", ArgumentParser::OptionType::kRequiredArgument,
        "Specify target language" + ap.getNewlineDescription()
        + "- c:      Transpile to C source" + ap.getNewlineDescription()
        + "- xbyakc: Dump xbyak code as C source" + ap.getNewlineDescription()
        + "- winx86: Compile to x86 EXE binary" + ap.getNewlineDescription()
        + "- winx64: Compile to x64 EXE binary" + ap.getNewlineDescription()
        + "- elfx86: Compile to x86 ELF binary" + ap.getNewlineDescription()
        + "- elfx64: Compile to x64 ELF binary" + ap.getNewlineDescription()
        + "- elfarmeabi: Compile to ARM EABI ELF binary",
        "TARGET", "");
    ap.add('v', "version", "Show version");
    ap.add('O', "optimize", ArgumentParser::OptionType::kRequiredArgument,
        "Specify optimization level" + ap.getNewlineDescription()
        + "Default value: 1" + ap.getNewlineDescription()
        + "- 0: Execute directly" + ap.getNewlineDescription()
        + "- 1: Compile to IR code and execute" + ap.getNewlineDescription()
        + "- 2: Compile to native code and execute", "LEVEL", 1);
    ap.add("dump-ir", "Dump IR code");
    ap.add("enable-synchronize-with-stdio", "Disable synchronization between std::cout/std::cin and <cstdio>");
    ap.add("heap-size", ArgumentParser::OptionType::kRequiredArgument,
        "Specify heap memory size" + ap.getNewlineDescription()
        + "Default value: 65536", "HEAP_SIZE", 65536);
    ap.parse(argc, argv);

    if (ap.get<bool>("help")) {
      ap.showUsage();
      return EXIT_SUCCESS;
    }
    if (ap.get<bool>("version")) {
      showVersion();
      return EXIT_SUCCESS;
    }
    if (!ap.get<bool>("enable-synchronize-with-stdio")) {
      std::cin.tie(nullptr);
      std::ios::sync_with_stdio(false);
    }
    std::size_t heapSize = ap.get<std::size_t>("heap-size");
    int optLevel = ap.get<int>("optimize");

    std::vector<std::string> args = ap.getArguments();
    if (args.size() == 0) {
      std::cerr << "Please specify one or more brainfuck source code" << std::endl;
      return EXIT_FAILURE;
    }

    Brainfuck bf;
    if (ap.get<bool>("minify")) {
      for (const auto& filename : args) {
        bf.load(filename);
        bf.trim();
        std::cout << bf.getSource() << std::endl;
        return EXIT_SUCCESS;
      }
    }
    if (ap.get<bool>("dump-ir")) {
      for (const auto& filename : args) {
        bf.load(filename);
        bf.trim();
        bf.compile();
        bf.dumpIR();
      }
      return EXIT_SUCCESS;
    }
    const std::string& target = ap.get("target");
    if (target != "") {
      if (targetMap.find(target) == targetMap.end()) {
        std::cerr << "Option -t, --target: Invalid value: \"" << target << "\" is specified" << std::endl;
        return EXIT_FAILURE;
      }
      bf.load(args[0]);
      bf.trim();
      bf.compile(Brainfuck::CompileType::kJit);
      Brainfuck::Target targetType = targetMap[target];
      std::string basename = removeSuffix(removeDirectoryPart(args[0]));
      switch (targetType) {
        case Brainfuck::Target::kC:
        case Brainfuck::Target::kXbyakC:
          bf.emit(std::cout, targetType);
          break;
        case Brainfuck::Target::kWinX86:
        case Brainfuck::Target::kWinX64:
          {
            std::ofstream ofs(basename + ".exe", std::ios::binary);
            if (!ofs.is_open()) {
              std::cerr << "Failed to open: " << "a.out" << std::endl;
              return EXIT_FAILURE;
            }
            bf.emit(ofs, targetType);
          }
          break;
        case Brainfuck::Target::kElfX86:
        case Brainfuck::Target::kElfX64:
        case Brainfuck::Target::kElfArmeabi:
          {
            std::ofstream ofs(basename + ".out", std::ios::binary);
            if (!ofs.is_open()) {
              std::cerr << "Failed to open: " << "a.out" << std::endl;
              return EXIT_FAILURE;
            }
            bf.emit(ofs, targetType);
          }
          break;
        default:
          assert(false);
      }
      return EXIT_SUCCESS;
    }

    for (const auto& filename : args) {
      if (filename == "-") {
        bf.load(std::cin);
      } else {
        bf.load(filename);
      }
      bf.trim();
      if (optLevel == 1) {
        bf.compile(Brainfuck::CompileType::kIR);
      } else if (optLevel > 1){
        bf.compile(Brainfuck::CompileType::kJit);
      }
      bf.execute(heapSize);
    }
  } catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return EXIT_SUCCESS;
}

static void
showVersion() NOEXCEPT
{
  const char* username = std::getenv("USER");
  std::cout << "<<< CppBrainfuck >>>\n\n";
  if (username != NULL) {
    std::cout << "Compiled by: " << username << "\n";
  }
  std::cout << "Compiled date: " << __DATE__ << " " << __TIME__ << "\n"
               "Version: " << kVersion
            << std::endl;
}

static std::string
removeDirectoryPart(const std::string& filepath) NOEXCEPT
{
  std::string::size_type pos = filepath.find_last_of('/');
  return pos == std::string::npos ? filepath : filepath.substr(pos + 1);
}

static std::string
removeSuffix(const std::string& filename) NOEXCEPT
{
  std::string::size_type pos = filename.find_last_of('.');
  return pos == std::string::npos ? (filename + ".") : filename.substr(0, pos);
}
<commit_msg>Implement two option: -e, --eval and -o, --output<commit_after>#include <cstdlib>
#include <array>
#include <exception>
#include <fstream>
#include <iostream>
#include <unordered_map>

#include "ArgumentParser.hpp"
#include "Brainfuck.hpp"
#include "version.h"

#if __cplusplus >= 201103L
namespace std {
  template <class T>
  struct hash {
    static_assert(is_enum<T>::value, "This hash only works for enumeration types");
    size_t operator()(T x) const noexcept {
      using type = typename underlying_type<T>::type;
      return hash<type>{}(static_cast<type>(x));
    }
  };
}
#endif  // __cplusplus >= 201103L

#if __cplusplus >= 201103L
#  define NOEXCEPT  noexcept
#else
#  define NOEXCEPT  throw()
#endif

static void
showVersion() NOEXCEPT;

static std::string
getDefaultOutputName(const std::string& inputFile, Brainfuck::Target targetType) NOEXCEPT;

static std::string
removeDirectoryPart(const std::string& filepath) NOEXCEPT;

static std::string
removeSuffix(const std::string& filename) NOEXCEPT;

int
main(int argc, const char* argv[])
{
  std::unordered_map<std::string, Brainfuck::Target> targetMap{
    {"c", Brainfuck::Target::kC},
    {"xbyakc", Brainfuck::Target::kXbyakC},
    {"winx86", Brainfuck::Target::kWinX86},
    {"winx64", Brainfuck::Target::kWinX64},
    {"elfx86", Brainfuck::Target::kElfX86},
    {"elfx64", Brainfuck::Target::kElfX64},
    {"elfarmeabi", Brainfuck::Target::kElfArmeabi}
  };

  try {
    ArgumentParser ap(argv[0]);
    ap.add('e', "eval",  ArgumentParser::OptionType::kRequiredArgument,
        "Execute specified brainfuck source", "SRC", "");
    ap.add('h', "help", "Show help and exit this program");
    ap.add('m', "minify", "Remove all non-brainfuck characters from source code");
    ap.add('o', "output",  ArgumentParser::OptionType::kRequiredArgument,
        "Specify output filename", "FILE", "");
    ap.add('t', "target", ArgumentParser::OptionType::kRequiredArgument,
        "Specify target language" + ap.getNewlineDescription()
        + "- c:      Transpile to C source" + ap.getNewlineDescription()
        + "- xbyakc: Dump xbyak code as C source" + ap.getNewlineDescription()
        + "- winx86: Compile to x86 EXE binary" + ap.getNewlineDescription()
        + "- winx64: Compile to x64 EXE binary" + ap.getNewlineDescription()
        + "- elfx86: Compile to x86 ELF binary" + ap.getNewlineDescription()
        + "- elfx64: Compile to x64 ELF binary" + ap.getNewlineDescription()
        + "- elfarmeabi: Compile to ARM EABI ELF binary",
        "TARGET", "");
    ap.add('v', "version", "Show version");
    ap.add('O', "optimize", ArgumentParser::OptionType::kRequiredArgument,
        "Specify optimization level" + ap.getNewlineDescription()
        + "Default value: 1" + ap.getNewlineDescription()
        + "- 0: Execute directly" + ap.getNewlineDescription()
        + "- 1: Compile to IR code and execute" + ap.getNewlineDescription()
        + "- 2: Compile to native code and execute", "LEVEL", 1);
    ap.add("dump-ir", "Dump IR code");
    ap.add("enable-synchronize-with-stdio", "Disable synchronization between std::cout/std::cin and <cstdio>");
    ap.add("heap-size", ArgumentParser::OptionType::kRequiredArgument,
        "Specify heap memory size" + ap.getNewlineDescription()
        + "Default value: 65536", "HEAP_SIZE", 65536);
    ap.parse(argc, argv);

    if (ap.get<bool>("help")) {
      ap.showUsage();
      return EXIT_SUCCESS;
    }
    if (ap.get<bool>("version")) {
      showVersion();
      return EXIT_SUCCESS;
    }
    if (!ap.get<bool>("enable-synchronize-with-stdio")) {
      std::cin.tie(nullptr);
      std::ios::sync_with_stdio(false);
    }
    std::size_t heapSize = ap.get<std::size_t>("heap-size");
    int optLevel = ap.get<int>("optimize");

    const std::vector<std::string>& args = ap.getArguments();
    const std::string& source = ap.get("eval");
    std::string inputFile = "a.b";

    Brainfuck bf;
    if (source != "") {
      bf.loadSource(source);
    } else if (args.size() > 0) {
      if (args[0] == "-") {
        bf.load(std::cin);
      } else {
        bf.load(args[0]);
        inputFile = args[0];
      }
    } else {
      std::cerr << "Please specify one brainfuck source code" << std::endl;
      return EXIT_FAILURE;
    }
    bf.trim();

    if (ap.get<bool>("minify")) {
      std::cout << bf.getSource() << std::endl;
      return EXIT_SUCCESS;
    }
    if (ap.get<bool>("dump-ir")) {
      bf.compile();
      bf.dumpIR();
      return EXIT_SUCCESS;
    }
    const std::string& target = ap.get("target");
    if (target != "") {
      if (targetMap.find(target) == targetMap.end()) {
        std::cerr << "Option -t, --target: Invalid value: \"" << target << "\" is specified" << std::endl;
        return EXIT_FAILURE;
      }
      bf.compile(Brainfuck::CompileType::kJit);
      Brainfuck::Target targetType = targetMap[target];
      std::string outputFile = ap.get("output");
      if (outputFile == "") {
        outputFile = getDefaultOutputName(inputFile, targetType);
      }
      switch (targetType) {
        case Brainfuck::Target::kC:
        case Brainfuck::Target::kXbyakC:
          bf.emit(std::cout, targetType);
          break;
        case Brainfuck::Target::kWinX86:
        case Brainfuck::Target::kWinX64:
        case Brainfuck::Target::kElfX86:
        case Brainfuck::Target::kElfX64:
        case Brainfuck::Target::kElfArmeabi:
          {
            std::ofstream ofs(outputFile, std::ios::binary);
            if (!ofs.is_open()) {
              std::cerr << "Failed to open: " << outputFile << std::endl;
              return EXIT_FAILURE;
            }
            bf.emit(ofs, targetType);
          }
          break;
        default:
          assert(false);
      }
      return EXIT_SUCCESS;
    }

    if (optLevel == 1) {
      bf.compile(Brainfuck::CompileType::kIR);
    } else if (optLevel > 1) {
      bf.compile(Brainfuck::CompileType::kJit);
    }
    bf.execute(heapSize);
  } catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return EXIT_SUCCESS;
}

static void
showVersion() NOEXCEPT
{
  const char* username = std::getenv("USER");
  std::cout << "<<< CppBrainfuck >>>\n\n";
  if (username != NULL) {
    std::cout << "Compiled by: " << username << "\n";
  }
  std::cout << "Compiled date: " << __DATE__ << " " << __TIME__ << "\n"
               "Version: " << kVersion
            << std::endl;
}

static std::string
getDefaultOutputName(const std::string& inputFile, Brainfuck::Target targetType) NOEXCEPT
{
  std::unordered_map<Brainfuck::Target, std::string> suffixMap{
    {Brainfuck::Target::kC, ".c"},
    {Brainfuck::Target::kXbyakC, ".c"},
    {Brainfuck::Target::kWinX86, ".exe"},
    {Brainfuck::Target::kWinX64, ".exe"},
    {Brainfuck::Target::kElfX86, ".out"},
    {Brainfuck::Target::kElfX64, ".out"},
    {Brainfuck::Target::kElfArmeabi, ".out"}
  };
  return removeSuffix(removeDirectoryPart(inputFile)) + suffixMap[targetType];
}

static std::string
removeDirectoryPart(const std::string& filepath) NOEXCEPT
{
  std::string::size_type pos = filepath.find_last_of('/');
  return pos == std::string::npos ? filepath : filepath.substr(pos + 1);
}

static std::string
removeSuffix(const std::string& filename) NOEXCEPT
{
  std::string::size_type pos = filename.find_last_of('.');
  return pos == std::string::npos ? (filename + ".") : filename.substr(0, pos);
}
<|endoftext|>


<commit_before>10714d66-ad5c-11e7-a6c8-ac87a332f658<commit_msg>this is my first commit?<commit_after>10fe173d-ad5c-11e7-8ded-ac87a332f658<|endoftext|>


<commit_before>12ba7cd1-2748-11e6-ba3e-e0f84713e7b8<commit_msg>#BUG723 uncommitted code found on my computer Monday morning<commit_after>12c7fc0c-2748-11e6-9aed-e0f84713e7b8<|endoftext|>