// Turns LLL tree into tree of code fragments programData opcodeify(Node node, programAux aux=Aux(), int height=0, std::map<std::string, int> dupvars= std::map<std::string, int>()) { std::string symb = "_"+mkUniqueToken(); Metadata m = node.metadata; // Numbers if (node.type == TOKEN) { return pd(aux, nodeToNumeric(node), 1); } else if (node.val == "ref" || node.val == "get" || node.val == "set") { std::string varname = node.args[0].val; if (!aux.vars.count(varname)) { aux.vars[varname] = unsignedToDecimal(aux.vars.size() * 32); } std::cout << aux.vars[varname] << " " << varname << " " << node.val << "\n"; if (varname == "'msg.data") aux.calldataUsed = true; // Set variable if (node.val == "set") { programData sub = opcodeify(node.args[1], aux, height, dupvars); if (!sub.outs) err("Value to set variable must have nonzero arity!", m); if (dupvars.count(node.args[0].val)) { int h = height - dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); Node nodelist[] = { sub.code, token("SWAP"+unsignedToDecimal(h), m), token("POP", m) }; return pd(sub.aux, multiToken(nodelist, 3, m), 0); } Node nodelist[] = { sub.code, token(sub.aux.vars[varname], m), token("MSTORE", m), }; return pd(sub.aux, multiToken(nodelist, 3, m), 0); } // Get variable else if (node.val == "get") { if (dupvars.count(node.args[0].val)) { int h = height - dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); return pd(aux, token("DUP"+unsignedToDecimal(h)), 1); } Node nodelist[] = { token(aux.vars[varname], m), token("MLOAD", m) }; std::cout << "<--- " << aux.vars[varname] << " " << varname << "\n"; return pd(aux, multiToken(nodelist, 2, m), 1); } // Refer variable else { if (dupvars.count(node.args[0].val)) err("Cannot ref stack variable!", m); return pd(aux, token(aux.vars[varname], m), 1); } } // Code blocks if (node.val == "lll" && node.args.size() == 2) { if (node.args[1].val != "0") aux.allocUsed = true; std::vector<Node> o; o.push_back(finalize(opcodeify(node.args[0]))); programData sub = opcodeify(node.args[1], aux, height, dupvars); Node code = astnode("____CODE", o, m); Node nodelist[] = { token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$endcode"+symb, m), token("JUMP", m), token("~begincode"+symb, m), code, token("~endcode"+symb, m) }; return pd(sub.aux, multiToken(nodelist, 10, m), 1); } // Stack variables if (node.val == "with") { std::map<std::string, int> dupvars2 = dupvars; dupvars2[node.args[0].val] = height; programData initial = opcodeify(node.args[1], aux, height, dupvars); if (!initial.outs) err("Initial variable value must have nonzero arity!", m); programData sub = opcodeify(node.args[2], initial.aux, height + 1, dupvars2); Node nodelist[] = { initial.code, sub.code }; programData o = pd(sub.aux, multiToken(nodelist, 2, m), sub.outs); if (sub.outs) o.code.args.push_back(token("SWAP1", m)); o.code.args.push_back(token("POP", m)); return o; } // Seq of multiple statements if (node.val == "seq") { std::vector<Node> children; int lastOut = 0; for (unsigned i = 0; i < node.args.size(); i++) { programData sub = opcodeify(node.args[i], aux, height, dupvars); aux = sub.aux; if (sub.outs == 1) { if (i < node.args.size() - 1) sub.code = popwrap(sub.code); else lastOut = 1; } children.push_back(sub.code); } return pd(aux, astnode("_", children, m), lastOut); } // 2-part conditional (if gets rewritten to unless in rewrites) else if (node.val == "unless" && node.args.size() == 2) { programData cond = opcodeify(node.args[0], aux, height, dupvars); programData action = opcodeify(node.args[1], cond.aux, height, dupvars); aux = action.aux; if (!cond.outs) err("Condition of if/unless statement has arity 0", m); if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { cond.code, token("$endif"+symb, m), token("JUMPI", m), action.code, token("~endif"+symb, m) }; return pd(aux, multiToken(nodelist, 5, m), 0); } // 3-part conditional else if (node.val == "if" && node.args.size() == 3) { programData ifd = opcodeify(node.args[0], aux, height, dupvars); programData thend = opcodeify(node.args[1], ifd.aux, height, dupvars); programData elsed = opcodeify(node.args[2], thend.aux, height, dupvars); aux = elsed.aux; if (!ifd.outs) err("Condition of if/unless statement has arity 0", m); // Handle cases where one conditional outputs something // and the other does not int outs = (thend.outs && elsed.outs) ? 1 : 0; if (thend.outs > outs) thend.code = popwrap(thend.code); if (elsed.outs > outs) elsed.code = popwrap(elsed.code); Node nodelist[] = { ifd.code, token("NOT", m), token("$else"+symb, m), token("JUMPI", m), thend.code, token("$endif"+symb, m), token("JUMP", m), token("~else"+symb, m), elsed.code, token("~endif"+symb, m) }; return pd(aux, multiToken(nodelist, 10, m), outs); } // While (rewritten to this in rewrites) else if (node.val == "until") { programData cond = opcodeify(node.args[0], aux, height, dupvars); programData action = opcodeify(node.args[1], cond.aux, height, dupvars); aux = action.aux; if (!cond.outs) err("Condition of while/until loop has arity 0", m); if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { token("~beg"+symb, m), cond.code, token("$end"+symb, m), token("JUMPI", m), action.code, token("$beg"+symb, m), token("JUMP", m), token("~end"+symb, m) }; return pd(aux, multiToken(nodelist, 8, m)); } // Memory allocations else if (node.val == "alloc") { programData bytez = opcodeify(node.args[0], aux, height, dupvars); aux = bytez.aux; if (!bytez.outs) err("Alloc input has arity 0", m); aux.allocUsed = true; Node nodelist[] = { bytez.code, token("MSIZE", m), token("SWAP1", m), token("MSIZE", m), token("ADD", m), token("0", m), token("SWAP1", m), token("MSTORE", m) }; return pd(aux, multiToken(nodelist, 8, m), 1); } // Array literals else if (node.val == "array_lit") { aux.allocUsed = true; std::vector<Node> nodes; if (!node.args.size()) { nodes.push_back(token("MSIZE", m)); return pd(aux, astnode("_", nodes, m)); } nodes.push_back(token("MSIZE", m)); nodes.push_back(token("0", m)); nodes.push_back(token("MSIZE", m)); nodes.push_back(token(unsignedToDecimal(node.args.size() * 32 - 1), m)); nodes.push_back(token("ADD", m)); nodes.push_back(token("MSTORE8", m)); for (unsigned i = 0; i < node.args.size(); i++) { Metadata m2 = node.args[i].metadata; nodes.push_back(token("DUP1", m2)); programData sub = opcodeify(node.args[i], aux, height + 2, dupvars); if (!sub.outs) err("Array_lit item " + unsignedToDecimal(i) + " has zero arity", m2); aux = sub.aux; nodes.push_back(sub.code); nodes.push_back(token("SWAP1", m2)); if (i > 0) { nodes.push_back(token(unsignedToDecimal(i * 32), m2)); nodes.push_back(token("ADD", m2)); } nodes.push_back(token("MSTORE", m2)); } return pd(aux, astnode("_", nodes, m), 1); } // All other functions/operators else { std::vector<Node> subs2; int depth = opinputs(upperCase(node.val)); if (node.val != "debug") { if (depth == -1) err("Not a function or opcode: "+node.val, m); if ((int)node.args.size() != depth) err("Invalid arity for "+node.val, m); } for (int i = node.args.size() - 1; i >= 0; i--) { programData sub = opcodeify(node.args[i], aux, height - i - 1 + node.args.size(), dupvars); aux = sub.aux; if (!sub.outs) err("Input "+unsignedToDecimal(i)+" has arity 0", sub.code.metadata); subs2.push_back(sub.code); } if (node.val == "debug") { subs2.push_back(token("DUP"+unsignedToDecimal(node.args.size()), m)); for (int i = 0; i <= (int)node.args.size(); i++) subs2.push_back(token("POP", m)); } else subs2.push_back(token(upperCase(node.val), m)); int outdepth = node.val == "debug" ? 0 : opoutputs(upperCase(node.val)); return pd(aux, astnode("_", subs2, m), outdepth); } }
void parseParameters(int argc,char *argv[],int *ptr,char sptr[MAX_PLIST][MAX_STRLEN], int *np,char name[MAX_PSR][MAX_NAMELEN],int *iname, int *haveName,char *filterStr,char *customStr,int *nohead,int *tbForm,int *noNumber, char *dbFile,char *mergeCat,paramtype *defParam,int *ephem,char *boundary, int *allmerge,int *webflag,char *plotx,char *ploty,int *plotx_log,int *ploty_log, int *bib_info,int *listRef,int *listallRef,int *listparticularRef,char *listIndRef, int *checkCat,int *fsize,int *nocand,int *nointerim) { register unsigned int i,j; char *strptr; char bound1[1000]; char bound2[1000]; pcat_expert = 0; strcpy(bound1,""); strcpy(bound2,""); *iname = 0; /* Number of pulsar names given on the command line */ /* Convert to upper case */ for (i=1;i<argc;i++) { if (strcasecmp(argv[i-1],"-db_file")!=0 && strcasecmp(argv[i-1],"-psr")!=0 && strcasecmp(argv[i-1],"-merge")!=0 && strcasecmp(argv[i-1],"-group")!=0 && strcasecmp(argv[i-1],"-web")!=0) /* Don't put filenames in upper case */ upperCase(argv[i]); } for (i=1;i<argc;i++) { if (strcmp(argv[i],"-S")==0) /* Define sort parameter */ pcat_sort=getParam(argv[++i],NULL); else if (strcmp(argv[i],"-H")==0) /* Help */ help(); else if (strcmp(argv[i],"-V")==0) /* Version of catalogue */ version(dbFile); else if (strcmp(argv[i],"-LISTREF")==0) /* List reference */ *listRef=1; else if (strcmp(argv[i],"-NOCAND")==0) /* No candidates */ *nocand=1; else if (strcmp(argv[i],"-NOINTERIM")==0) /* No interim */ *nointerim=1; else if (strcmp(argv[i],"-BBL")==0) /* List reference */ *listRef=2; else if (strcmp(argv[i],"-ALLBIBS")==0) /* List reference */ *listRef=3; else if (strcmp(argv[i],"-ALLREF")==0) /* List all references */ *listallRef=1; else if (strcmp(argv[i],"-BIB")==0) /* Provide bibliographic reference */ { *listparticularRef=1; strcpy(listIndRef,argv[++i]); } else if (strcmp(argv[i],"-BOUNDARY")==0) /* Boundary string */ strcpy(boundary,argv[++i]); else if (strcmp(argv[i],"-BOUND_COORD")==0) /* Old boundary method */ strcpy(bound1,argv[++i]); else if (strcmp(argv[i],"-BOUND_RADIUS")==0) /* Old boundary method */ strcpy(bound2,argv[++i]); else if (strcmp(argv[i],"-CHECK")==0) /* Check catalogue */ *checkCat=1; else if (strcmp(argv[i],"-ALL")==0) /* Merge with PSRCAT_RUNDIR environment variable */ *allmerge=1; else if (strcmp(argv[i],"-E")==0) /* TEMPO ephemeris */ *ephem = 1; else if (strcmp(argv[i],"-E2")==0) /* Full ephemeris */ *ephem = 2; else if (strcmp(argv[i],"-E3")==0) /* Select ephemeris */ *ephem = 3; else if (strcmp(argv[i],"-E4")==0) /* Select ephemeris */ *ephem = 4; else if (strcmp(argv[i],"-FSIZE")==0) /* Select ephemeris */ sscanf(argv[++i],"%d",fsize); else if (strcmp(argv[i],"-EXPERT")==0) /* expert mode */ pcat_expert = 1; else if (strcmp(argv[i],"-DESCEND")==0) /* Sort in descending order */ pcat_descend=1; else if (strcmp(argv[i],"-DB_FILE")==0) /* Catalogue file */ strcpy(dbFile,argv[++i]); else if (strcmp(argv[i],"-PLOTX")==0) /* expression for plotting on x-axis */ {strcpy(plotx,argv[++i]);*nohead=1;} else if (strcmp(argv[i],"-PLOTY")==0) /* ploty */ {strcpy(ploty,argv[++i]);*nohead=1;} else if (strcmp(argv[i],"-LOGX")==0) /* Take log10 of x-axis */ *plotx_log = 1; else if (strcmp(argv[i],"-LOGY")==0) /* Take log10 of y-axis */ *ploty_log = 1; else if (strcmp(argv[i],"-MERGE")==0) /* Merge catalogues */ strcat(mergeCat,argv[++i]); else if (strcmp(argv[i],"-BIBLIOGRAPHY")==0) *bib_info=1; else if (strcmp(argv[i],"-NONUMBER")==0) /* No numbering */ *noNumber=1; else if (strcmp(argv[i],"-O")==0) /* Tabular format */ { i++; if (strcmp(argv[i],"LONG")==0) *tbForm=0; if (strcmp(argv[i],"PUBLISH")==0) *tbForm=1; if (strcmp(argv[i],"SHORT")==0) *tbForm=2; if (strcmp(argv[i],"SHORT_NO_ERROR")==0) *tbForm=2; if (strcmp(argv[i],"SHORT_ERROR")==0) *tbForm=3; if (strcmp(argv[i],"LONG_ERROR")==0) *tbForm=4; if (strcmp(argv[i],"NONE")==0) *tbForm=5; } else if (strcmp(argv[i],"-C1")==0) /* Custom parameter 1 */ strcat(pcat_custom1,argv[++i]); else if (strcmp(argv[i],"-C2")==0) /* Custom parameter 2 */ strcat(pcat_custom2,argv[++i]); else if (strcmp(argv[i],"-C3")==0) /* Custom parameter 3 */ strcat(pcat_custom3,argv[++i]); else if (strcmp(argv[i],"-C4")==0) /* Custom parameter 4 */ strcat(pcat_custom4,argv[++i]); else if (strcmp(argv[i],"-NULL")==0) /* Null value string */ strcpy(NO_VAL,argv[++i]); else if (strcmp(argv[i],"-WEB")==0) /* Web flag */ { char web_address[MAX_STRLEN*3]; *webflag=1; /* Add to counter */ strcpy(web_address,"echo \""); strcat(web_address,argv[i+1]); i++; strcat(web_address,"\" >>"); strcat(web_address,COUNTER_FILE); system(web_address); } else if (strcmp(argv[i],"-P")==0) /* Describe parameters */ { if (i+1==argc) display_parameters("*",defParam); /* List all parameters */ else display_parameters(argv[i+1],defParam); /* Get selected parameter list */ } else if (strcmp(argv[i],"-C")==0) /* Define parameters */ { customStr = argv[i]; *np = 0; for (j=0;j<MAX_PLIST;j++) { if (j==0) strptr = strtok(argv[i+1]," \t\n"); else strptr = strtok(NULL," \t\n"); if (strptr==NULL) break; if (strcmp(strptr,"JNAME")==0) {strcpy(sptr[*np],"PSRJ"); strcpy(strptr,"PSRJ");} else if (strcmp(strptr,"BNAME")==0) {strcpy(sptr[*np],"PSRB"); strcpy(strptr,"PSRB");} else strcpy(sptr[*np],strptr); ptr[(*np)++] = getParam(strptr,NULL); if (ptr[(*np)-1]==-1) { printf("Parameter >%s< not known. Use psrcat -p to get a list of parameters\n",strptr); exit(1); } } i++; } else if (strcmp(argv[i],"-L")==0) /* Logical expression for filtering pulsars */ strcat(filterStr,argv[++i]); else if (strcmp(argv[i],"-NOHEAD")==0) *nohead=1; else if (strcmp(argv[i],"-VERBOSE")==0) verbose=1; else if (strcmp(argv[i],"-X")==0) /* Simplify some settings */ { *nohead=1; *noNumber=1; *tbForm=4; } else if (strcmp(argv[i],"-PSR")==0) /* Read pulsar names from a file */ { FILE *fin; char temp[1000]; i++; if (!(fin = fopen(argv[i],"r"))) { printf("Unable to open pulsar file %s\n",argv[i]); exit(1); } while (!feof(fin)) { if (fscanf(fin,"%s",temp)==1) { haveName[*iname]=0; if (temp[0] == '0' || temp[0]=='1' || temp[0] =='2') sprintf(name[(*iname)++],"?%s",temp); else sprintf(name[(*iname)++],"%s",temp); } } fclose(fin); } else if (argv[i][0] == '0' || argv[i][0] == '1' || argv[i][0] == '2') /* Pulsar name */ {haveName[*iname] = 0; sprintf(name[(*iname)++],"?%s",argv[i]);} else if (argv[i][0] == 'B' || argv[i][0] == 'J') /* Pulsar name */ {haveName[*iname] = 0; sprintf(name[(*iname)++],"%s",argv[i]);} else { printf("Unknown parameter >%s<. Use -h to get list of parameters.\n",argv[i]); exit(1); } } if (strlen(bound1)>0 && strlen(bound2)>0) { strcpy(boundary,bound1); strcat(boundary," "); strcat(boundary,bound2); } }
// Turns LLL tree into tree of code fragments programData opcodeify(Node node, programAux aux=Aux(), programVerticalAux vaux=verticalAux()) { std::string symb = "_"+mkUniqueToken(); Metadata m = node.metadata; // Numbers if (node.type == TOKEN) { return pd(aux, nodeToNumeric(node), 1); } else if (node.val == "ref" || node.val == "get" || node.val == "set") { std::string varname = node.args[0].val; // Determine reference to variable if (!aux.vars.count(node.args[0].val)) { aux.vars[node.args[0].val] = utd(aux.nextVarMem); aux.nextVarMem += 32; } Node varNode = tkn(aux.vars[varname], m); //std::cerr << varname << " " << printSimple(varNode) << "\n"; // Set variable if (node.val == "set") { programData sub = opcodeify(node.args[1], aux, vaux); if (!sub.outs) err("Value to set variable must have nonzero arity!", m); // What if we are setting a stack variable? if (vaux.dupvars.count(node.args[0].val)) { int h = vaux.height - vaux.dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); Node nodelist[] = { sub.code, token("SWAP"+unsignedToDecimal(h), m), token("POP", m) }; return pd(sub.aux, multiToken(nodelist, 3, m), 0); } // Setting a memory variable else { Node nodelist[] = { sub.code, varNode, token("MSTORE", m), }; return pd(sub.aux, multiToken(nodelist, 3, m), 0); } } // Get variable else if (node.val == "get") { // Getting a stack variable if (vaux.dupvars.count(node.args[0].val)) { int h = vaux.height - vaux.dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); return pd(aux, token("DUP"+unsignedToDecimal(h)), 1); } // Getting a memory variable else { Node nodelist[] = { varNode, token("MLOAD", m) }; return pd(aux, multiToken(nodelist, 2, m), 1); } } // Refer variable else if (node.val == "ref") { if (vaux.dupvars.count(node.args[0].val)) err("Cannot ref stack variable!", m); return pd(aux, varNode, 1); } } // Comments do nothing else if (node.val == "comment") { return pd(aux, astnode("_", m), 0); } // Custom operation sequence // eg. (ops bytez id msize swap1 msize add 0 swap1 mstore) == alloc if (node.val == "ops") { std::vector<Node> subs2; int depth = 0; for (unsigned i = 0; i < node.args.size(); i++) { std::string op = upperCase(node.args[i].val); if (node.args[i].type == ASTNODE || opinputs(op) == -1) { programVerticalAux vaux2 = vaux; vaux2.height = vaux.height - i - 1 + node.args.size(); programData sub = opcodeify(node.args[i], aux, vaux2); aux = sub.aux; depth += sub.outs; subs2.push_back(sub.code); } else { subs2.push_back(token(op, m)); depth += opoutputs(op) - opinputs(op); } } if (depth < 0 || depth > 1) err("Stack depth mismatch", m); return pd(aux, astnode("_", subs2, m), 0); } // Code blocks if (node.val == "lll" && node.args.size() == 2) { if (node.args[1].val != "0") aux.allocUsed = true; std::vector<Node> o; o.push_back(finalize(opcodeify(node.args[0]))); programData sub = opcodeify(node.args[1], aux, vaux); Node code = astnode("____CODE", o, m); Node nodelist[] = { token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$endcode"+symb, m), token("JUMP", m), token("~begincode"+symb, m), code, token("~endcode"+symb, m), token("JUMPDEST", m) }; return pd(sub.aux, multiToken(nodelist, 11, m), 1); } // Stack variables if (node.val == "with") { programData initial = opcodeify(node.args[1], aux, vaux); programVerticalAux vaux2 = vaux; vaux2.dupvars[node.args[0].val] = vaux.height; vaux2.height += 1; if (!initial.outs) err("Initial variable value must have nonzero arity!", m); programData sub = opcodeify(node.args[2], initial.aux, vaux2); Node nodelist[] = { initial.code, sub.code }; programData o = pd(sub.aux, multiToken(nodelist, 2, m), sub.outs); if (sub.outs) o.code.args.push_back(token("SWAP1", m)); o.code.args.push_back(token("POP", m)); return o; } // Seq of multiple statements if (node.val == "seq") { std::vector<Node> children; int lastOut = 0; for (unsigned i = 0; i < node.args.size(); i++) { programData sub = opcodeify(node.args[i], aux, vaux); aux = sub.aux; if (sub.outs == 1) { if (i < node.args.size() - 1) sub.code = popwrap(sub.code); else lastOut = 1; } children.push_back(sub.code); } return pd(aux, astnode("_", children, m), lastOut); } // 2-part conditional (if gets rewritten to unless in rewrites) else if (node.val == "unless" && node.args.size() == 2) { programData cond = opcodeify(node.args[0], aux, vaux); programData action = opcodeify(node.args[1], cond.aux, vaux); aux = action.aux; if (!cond.outs) err("Condition of if/unless statement has arity 0", m); if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { cond.code, token("$endif"+symb, m), token("JUMPI", m), action.code, token("~endif"+symb, m), token("JUMPDEST", m) }; return pd(aux, multiToken(nodelist, 6, m), 0); } // 3-part conditional else if (node.val == "if" && node.args.size() == 3) { programData ifd = opcodeify(node.args[0], aux, vaux); programData thend = opcodeify(node.args[1], ifd.aux, vaux); programData elsed = opcodeify(node.args[2], thend.aux, vaux); aux = elsed.aux; if (!ifd.outs) err("Condition of if/unless statement has arity 0", m); // Handle cases where one conditional outputs something // and the other does not int outs = (thend.outs && elsed.outs) ? 1 : 0; if (thend.outs > outs) thend.code = popwrap(thend.code); if (elsed.outs > outs) elsed.code = popwrap(elsed.code); Node nodelist[] = { ifd.code, token("ISZERO", m), token("$else"+symb, m), token("JUMPI", m), thend.code, token("$endif"+symb, m), token("JUMP", m), token("~else"+symb, m), token("JUMPDEST", m), elsed.code, token("~endif"+symb, m), token("JUMPDEST", m) }; return pd(aux, multiToken(nodelist, 12, m), outs); } // While (rewritten to this in rewrites) else if (node.val == "until") { programData cond = opcodeify(node.args[0], aux, vaux); programData action = opcodeify(node.args[1], cond.aux, vaux); aux = action.aux; if (!cond.outs) err("Condition of while/until loop has arity 0", m); if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { token("~beg"+symb, m), token("JUMPDEST", m), cond.code, token("$end"+symb, m), token("JUMPI", m), action.code, token("$beg"+symb, m), token("JUMP", m), token("~end"+symb, m), token("JUMPDEST", m), }; return pd(aux, multiToken(nodelist, 10, m)); } // Memory allocations else if (node.val == "alloc") { programData bytez = opcodeify(node.args[0], aux, vaux); aux = bytez.aux; if (!bytez.outs) err("Alloc input has arity 0", m); aux.allocUsed = true; Node nodelist[] = { bytez.code, token("MSIZE", m), token("SWAP1", m), token("MSIZE", m), token("ADD", m), token("0", m), token("SWAP1", m), token("MSTORE", m) }; return pd(aux, multiToken(nodelist, 8, m), 1); } // All other functions/operators else { std::vector<Node> subs2; int depth = opinputs(upperCase(node.val)); if (depth == -1) err("Not a function or opcode: "+node.val, m); if ((int)node.args.size() != depth) err("Invalid arity for "+node.val, m); for (int i = node.args.size() - 1; i >= 0; i--) { programVerticalAux vaux2 = vaux; vaux2.height = vaux.height - i - 1 + node.args.size(); programData sub = opcodeify(node.args[i], aux, vaux2); aux = sub.aux; if (!sub.outs) err("Input "+unsignedToDecimal(i)+" has arity 0", sub.code.metadata); subs2.push_back(sub.code); } subs2.push_back(token(upperCase(node.val), m)); int outdepth = opoutputs(upperCase(node.val)); return pd(aux, astnode("_", subs2, m), outdepth); } }
int main (int argc, char** argv) { UnitTest t (264); // void wrapText (std::vector <std::string>& lines, const std::string& text, const int width, bool hyphenate) std::string text = "This is a test of the line wrapping code."; std::vector <std::string> lines; wrapText (lines, text, 10, true); t.is (lines.size (), (size_t) 5, "wrapText 'This is a test of the line wrapping code.' -> total 5 lines"); t.is (lines[0], "This is a", "wrapText line 0 -> 'This is a'"); t.is (lines[1], "test of", "wrapText line 1 -> 'test of'"); t.is (lines[2], "the line", "wrapText line 2 -> 'the line'"); t.is (lines[3], "wrapping", "wrapText line 3 -> 'wrapping'"); t.is (lines[4], "code.", "wrapText line 4 -> 'code.'"); text = "This ☺ is a test of utf8 line extraction."; lines.clear (); wrapText (lines, text, 7, true); t.is (lines.size (), (size_t) 7, "wrapText 'This ☺ is a test of utf8 line extraction.' -> total 7 lines"); t.is (lines[0], "This ☺", "wrapText line 0 -> 'This ☺'"); t.is (lines[1], "is a", "wrapText line 1 -> 'is a'"); t.is (lines[2], "test of", "wrapText line 2 -> 'test of'"); t.is (lines[3], "utf8", "wrapText line 3 -> 'utf8'"); t.is (lines[4], "line", "wrapText line 4 -> 'line'"); t.is (lines[5], "extrac-", "wrapText line 5 -> 'extrac-'"); t.is (lines[6], "tion.", "wrapText line 6 -> 'tion.'"); text = "one two three\n four"; lines.clear (); wrapText (lines, text, 13, true); t.is (lines.size (), (size_t) 2, "wrapText 'one two three\\n four' -> 2 lines"); t.is (lines[0], "one two three", "wrapText line 0 -> 'one two three'"); t.is (lines[1], " four", "wrapText line 1 -> ' four'"); // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset) text = "This ☺ is a test of utf8 line extraction."; unsigned int offset = 0; std::string line; extractLine (line, text, 7, true, offset); t.is (line, "This ☺", "extractLine 7 'This ☺ is a test of utf8 line extraction.' -> 'This ☺'"); // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset) text = "line 1\nlengthy second line that exceeds width"; offset = 0; extractLine (line, text, 10, true, offset); t.is (line, "line 1", "extractLine 10 'line 1\\nlengthy second line that exceeds width' -> 'line 1'"); extractLine (line, text, 10, true, offset); t.is (line, "lengthy", "extractLine 10 'lengthy second line that exceeds width' -> 'lengthy'"); extractLine (line, text, 10, true, offset); t.is (line, "second", "extractLine 10 'second line that exceeds width' -> 'second'"); extractLine (line, text, 10, true, offset); t.is (line, "line that", "extractLine 10 'line that exceeds width' -> 'line that'"); extractLine (line, text, 10, true, offset); t.is (line, "exceeds", "extractLine 10 'exceeds width' -> 'exceeds'"); extractLine (line, text, 10, true, offset); t.is (line, "width", "extractLine 10 'width' -> 'width'"); t.notok (extractLine (line, text, 10, true, offset), "extractLine 10 '' -> ''"); // void split (std::vector<std::string>& results, const std::string& input, const char delimiter) std::vector <std::string> items; std::string unsplit = ""; split (items, unsplit, '-'); t.is (items.size (), (size_t) 0, "split '' '-' -> 0 items"); unsplit = "a"; split (items, unsplit, '-'); t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item"); t.is (items[0], "a", "split 'a' '-' -> 'a'"); split (items, unsplit, '-'); t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item"); t.is (items[0], "a", "split 'a' '-' -> 'a'"); unsplit = "-"; split (items, unsplit, '-'); t.is (items.size (), (size_t) 2, "split '-' '-' -> '' ''"); t.is (items[0], "", "split '-' '-' -> [0] ''"); t.is (items[1], "", "split '-' '-' -> [1] ''"); split_minimal (items, unsplit, '-'); t.is (items.size (), (size_t) 0, "split '-' '-' ->"); unsplit = "-a-bc-def"; split (items, unsplit, '-'); t.is (items.size (), (size_t) 4, "split '-a-bc-def' '-' -> '' 'a' 'bc' 'def'"); t.is (items[0], "", "split '-a-bc-def' '-' -> [0] ''"); t.is (items[1], "a", "split '-a-bc-def' '-' -> [1] 'a'"); t.is (items[2], "bc", "split '-a-bc-def' '-' -> [2] 'bc'"); t.is (items[3], "def", "split '-a-bc-def' '-' -> [3] 'def'"); split_minimal (items, unsplit, '-'); t.is (items.size (), (size_t) 3, "split '-a-bc-def' '-' -> 'a' 'bc' 'def'"); t.is (items[0], "a", "split '-a-bc-def' '-' -> [1] 'a'"); t.is (items[1], "bc", "split '-a-bc-def' '-' -> [2] 'bc'"); t.is (items[2], "def", "split '-a-bc-def' '-' -> [3] 'def'"); // void split (std::vector<std::string>& results, const std::string& input, const std::string& delimiter) unsplit = ""; split (items, unsplit, "--"); t.is (items.size (), (size_t) 0, "split '' '--' -> 0 items"); unsplit = "a"; split (items, unsplit, "--"); t.is (items.size (), (size_t) 1, "split 'a' '--' -> 1 item"); t.is (items[0], "a", "split 'a' '-' -> 'a'"); unsplit = "--"; split (items, unsplit, "--"); t.is (items.size (), (size_t) 2, "split '-' '--' -> '' ''"); t.is (items[0], "", "split '-' '-' -> [0] ''"); t.is (items[1], "", "split '-' '-' -> [1] ''"); unsplit = "--a--bc--def"; split (items, unsplit, "--"); t.is (items.size (), (size_t) 4, "split '-a-bc-def' '--' -> '' 'a' 'bc' 'def'"); t.is (items[0], "", "split '-a-bc-def' '--' -> [0] ''"); t.is (items[1], "a", "split '-a-bc-def' '--' -> [1] 'a'"); t.is (items[2], "bc", "split '-a-bc-def' '--' -> [2] 'bc'"); t.is (items[3], "def", "split '-a-bc-def' '--' -> [3] 'def'"); unsplit = "one\ntwo\nthree"; split (items, unsplit, "\n"); t.is (items.size (), (size_t) 3, "split 'one\\ntwo\\nthree' -> 'one', 'two', 'three'"); t.is (items[0], "one", "split 'one\\ntwo\\nthree' -> [0] 'one'"); t.is (items[1], "two", "split 'one\\ntwo\\nthree' -> [1] 'two'"); t.is (items[2], "three", "split 'one\\ntwo\\nthree' -> [2] 'three'"); // void splitq (std::vector<std::string>&, const std::string&, const char); unsplit = "one 'two' '' 'three four' \"five six seven\" eight'nine ten'"; splitq (items, unsplit, ' '); t.is (items.size () , (size_t) 6, "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten'"); t.is (items[0], "one", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [0] 'one'"); t.is (items[1], "two", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [1] 'two'"); t.is (items[2], "", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [2] ''"); t.is (items[3], "three four", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [3] 'three four'"); t.is (items[4], "five six seven", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [4] 'five six seven'"); t.is (items[5], "eight'nine ten'", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [4] 'eight\\'nine ten\\''"); // void join (std::string& result, const std::string& separator, const std::vector<std::string>& items) std::vector <std::string> unjoined; std::string joined; join (joined, "", unjoined); t.is (joined.length (), (size_t) 0, "join -> length 0"); t.is (joined, "", "join -> ''"); unjoined.push_back (""); unjoined.push_back ("a"); unjoined.push_back ("bc"); unjoined.push_back ("def"); join (joined, "", unjoined); t.is (joined.length (), (size_t) 6, "join '' 'a' 'bc' 'def' -> length 6"); t.is (joined, "abcdef", "join '' 'a' 'bc' 'def' -> 'abcdef'"); join (joined, "-", unjoined); t.is (joined.length (), (size_t) 9, "join '' - 'a' - 'bc' - 'def' -> length 9"); t.is (joined, "-a-bc-def", "join '' - 'a' - 'bc' - 'def' -> '-a-bc-def'"); // void join (std::string& result, const std::string& separator, const std::vector<int>& items) std::vector <int> unjoined2; join (joined, "", unjoined2); t.is (joined.length (), (size_t) 0, "join -> length 0"); t.is (joined, "", "join -> ''"); unjoined2.push_back (0); unjoined2.push_back (1); unjoined2.push_back (2); join (joined, "", unjoined2); t.is (joined.length (), (size_t) 3, "join 0 1 2 -> length 3"); t.is (joined, "012", "join 0 1 2 -> '012'"); join (joined, "-", unjoined2); t.is (joined.length (), (size_t) 5, "join 0 1 2 -> length 5"); t.is (joined, "0-1-2", "join 0 1 2 -> '0-1-2'"); // std::string trimLeft (const std::string& in, const std::string& t /*= " "*/) t.is (trimLeft (""), "", "trimLeft '' -> ''"); t.is (trimLeft (" "), "", "trimLeft ' ' -> ''"); t.is (trimLeft ("", " \t"), "", "trimLeft '' -> ''"); t.is (trimLeft ("xxx"), "xxx", "trimLeft 'xxx' -> 'xxx'"); t.is (trimLeft ("xxx", " \t"), "xxx", "trimLeft 'xxx' -> 'xxx'"); t.is (trimLeft (" \t xxx \t "), "\t xxx \t ", "trimLeft ' \\t xxx \\t ' -> '\\t xxx \\t '"); t.is (trimLeft (" \t xxx \t ", " \t"), "xxx \t ", "trimLeft ' \\t xxx \\t ' -> 'xxx \\t '"); // std::string trimRight (const std::string& in, const std::string& t /*= " "*/) t.is (trimRight (""), "", "trimRight '' -> ''"); t.is (trimRight (" "), "", "trimRight ' ' -> ''"); t.is (trimRight ("", " \t"), "", "trimRight '' -> ''"); t.is (trimRight ("xxx"), "xxx", "trimRight 'xxx' -> 'xxx'"); t.is (trimRight ("xxx", " \t"), "xxx", "trimRight 'xxx' -> 'xxx'"); t.is (trimRight (" \t xxx \t "), " \t xxx \t", "trimRight ' \\t xxx \\t ' -> ' \\t xxx \\t'"); t.is (trimRight (" \t xxx \t ", " \t"), " \t xxx", "trimRight ' \\t xxx \\t ' -> ' \\t xxx'"); // std::string trim (const std::string& in, const std::string& t /*= " "*/) t.is (trim (""), "", "trim '' -> ''"); t.is (trim (" "), "", "trim ' ' -> ''"); t.is (trim ("", " \t"), "", "trim '' -> ''"); t.is (trim ("xxx"), "xxx", "trim 'xxx' -> 'xxx'"); t.is (trim ("xxx", " \t"), "xxx", "trim 'xxx' -> 'xxx'"); t.is (trim (" \t xxx \t "), "\t xxx \t", "trim ' \\t xxx \\t ' -> '\\t xxx \\t'"); t.is (trim (" \t xxx \t ", " \t"), "xxx", "trim ' \\t xxx \\t ' -> 'xxx'"); // std::string unquoteText (const std::string& text) t.is (unquoteText (""), "", "unquoteText '' -> ''"); t.is (unquoteText ("x"), "x", "unquoteText 'x' -> 'x'"); t.is (unquoteText ("'x"), "'x", "unquoteText ''x' -> ''x'"); t.is (unquoteText ("x'"), "x'", "unquoteText 'x'' -> 'x''"); t.is (unquoteText ("\"x"), "\"x", "unquoteText '\"x' -> '\"x'"); t.is (unquoteText ("x\""), "x\"", "unquoteText 'x\"' -> 'x\"'"); t.is (unquoteText ("''"), "", "unquoteText '''' -> ''"); t.is (unquoteText ("'''"), "'", "unquoteText ''''' -> '''"); t.is (unquoteText ("\"\""), "", "unquoteText '\"\"' -> ''"); t.is (unquoteText ("\"\"\""), "\"", "unquoteText '\"\"\"' -> '\"'"); t.is (unquoteText ("''''"), "''", "unquoteText '''''' -> ''''"); t.is (unquoteText ("\"\"\"\""), "\"\"", "unquoteText '\"\"\"\"' -> '\"\"'"); t.is (unquoteText ("'\"\"'"), "\"\"", "unquoteText '''\"\"' -> '\"\"'"); t.is (unquoteText ("\"''\""), "''", "unquoteText '\"''\"' -> ''''"); t.is (unquoteText ("'x'"), "x", "unquoteText ''x'' -> 'x'"); t.is (unquoteText ("\"x\""), "x", "unquoteText '\"x\"' -> 'x'"); // int longestWord (const std::string&) t.is (longestWord (" "), 0, "longestWord ( ) --> 0"); t.is (longestWord ("this is a test"), 4, "longestWord (this is a test) --> 4"); t.is (longestWord ("this is a better test"), 6, "longestWord (this is a better test) --> 6"); t.is (longestWord ("house Çirçös clown"), 6, "longestWord (Çirçös) --> 6"); // int longestLine (const std::string&) t.is (longestLine ("one two three four"), 18, "longestLine (one two three four) --> 18"); t.is (longestLine ("one\ntwo three four"), 14, "longestLine (one\\ntwo three four) --> 14"); t.is (longestLine ("one\ntwo\nthree\nfour"), 5, "longestLine (one\\ntwo\\nthree\\nfour) --> 5"); // std::string commify (const std::string& data) t.is (commify (""), "", "commify '' -> ''"); t.is (commify ("1"), "1", "commify '1' -> '1'"); t.is (commify ("12"), "12", "commify '12' -> '12'"); t.is (commify ("123"), "123", "commify '123' -> '123'"); t.is (commify ("1234"), "1,234", "commify '1234' -> '1,234'"); t.is (commify ("12345"), "12,345", "commify '12345' -> '12,345'"); t.is (commify ("123456"), "123,456", "commify '123456' -> '123,456'"); t.is (commify ("1234567"), "1,234,567", "commify '1234567' -> '1,234,567'"); t.is (commify ("12345678"), "12,345,678", "commify '12345678' -> '12,345,678'"); t.is (commify ("123456789"), "123,456,789", "commify '123456789' -> '123,456,789'"); t.is (commify ("1234567890"), "1,234,567,890", "commify '1234567890' -> '1,234,567,890'"); t.is (commify ("pre"), "pre", "commify 'pre' -> 'pre'"); t.is (commify ("pre1234"), "pre1,234", "commify 'pre1234' -> 'pre1,234'"); t.is (commify ("1234post"), "1,234post", "commify '1234post' -> '1,234post'"); t.is (commify ("pre1234post"), "pre1,234post", "commify 'pre1234post' -> 'pre1,234post'"); // std::string lowerCase (const std::string& input) t.is (lowerCase (""), "", "lowerCase '' -> ''"); t.is (lowerCase ("pre01_:POST"), "pre01_:post", "lowerCase 'pre01_:POST' -> 'pre01_:post'"); // std::string upperCase (const std::string& input) t.is (upperCase (""), "", "upperCase '' -> ''"); t.is (upperCase ("pre01_:POST"), "PRE01_:POST", "upperCase 'pre01_:POST' -> 'PRE01_:POST'"); // bool nontrivial (const std::string&); t.notok (nontrivial (""), "nontrivial '' -> false"); t.notok (nontrivial (" "), "nontrivial ' ' -> false"); t.notok (nontrivial ("\t\t"), "nontrivial '\\t\\t' -> false"); t.notok (nontrivial (" \t \t"), "nontrivial ' \\t \\t' -> false"); t.ok (nontrivial ("a"), "nontrivial 'a' -> true"); t.ok (nontrivial (" a"), "nontrivial ' a' -> true"); t.ok (nontrivial ("a "), "nontrivial 'a ' -> true"); t.ok (nontrivial (" \t\ta"), "nontrivial ' \\t\\ta' -> true"); t.ok (nontrivial ("a\t\t "), "nontrivial 'a\\t\\t ' -> true"); // bool digitsOnly (const std::string&); t.ok (digitsOnly (""), "digitsOnly '' -> true"); t.ok (digitsOnly ("0"), "digitsOnly '0' -> true"); t.ok (digitsOnly ("123"), "digitsOnly '123' -> true"); t.notok (digitsOnly ("12fa"), "digitsOnly '12fa' -> false"); // bool noSpaces (const std::string&); t.ok (noSpaces (""), "noSpaces '' -> true"); t.ok (noSpaces ("a"), "noSpaces 'a' -> true"); t.ok (noSpaces ("abc"), "noSpaces 'abc' -> true"); t.notok (noSpaces (" "), "noSpaces ' ' -> false"); t.notok (noSpaces ("ab cd"), "noSpaces 'ab cd' -> false"); // bool noVerticalSpace (const std::string&); t.ok (noVerticalSpace (""), "noVerticalSpace '' -> true"); t.ok (noVerticalSpace ("a"), "noVerticalSpace 'a' -> true"); t.ok (noVerticalSpace ("abc"), "noVerticalSpace 'abc' -> true"); t.notok (noVerticalSpace ("a\nb"), "noVerticalSpace 'a\\nb' -> false"); t.notok (noVerticalSpace ("a\rb"), "noVerticalSpace 'a\\rb' -> false"); t.notok (noVerticalSpace ("a\fb"), "noVerticalSpace 'a\\fb' -> false"); text = "Hello, world."; // 0123456789012 // s e s e // bool isWordStart (const std::string&, std::string::size_type); t.notok (isWordStart ("", 0), "isWordStart (\"\", 0) -> false"); t.ok (isWordStart ("foo", 0), "isWordStart (\"foo\", 0) -> true"); t.ok (isWordStart (text, 0), "isWordStart (\"Hello, world.\", 0) -> true"); t.notok (isWordStart (text, 1), "isWordStart (\"Hello, world.\", 1) -> false"); t.notok (isWordStart (text, 2), "isWordStart (\"Hello, world.\", 2) -> false"); t.notok (isWordStart (text, 3), "isWordStart (\"Hello, world.\", 3) -> false"); t.notok (isWordStart (text, 4), "isWordStart (\"Hello, world.\", 4) -> false"); t.notok (isWordStart (text, 5), "isWordStart (\"Hello, world.\", 5) -> false"); t.notok (isWordStart (text, 6), "isWordStart (\"Hello, world.\", 6) -> false"); t.ok (isWordStart (text, 7), "isWordStart (\"Hello, world.\", 7) -> true"); t.notok (isWordStart (text, 8), "isWordStart (\"Hello, world.\", 8) -> false"); t.notok (isWordStart (text, 9), "isWordStart (\"Hello, world.\", 9) -> false"); t.notok (isWordStart (text, 10), "isWordStart (\"Hello, world.\", 10) -> false"); t.notok (isWordStart (text, 11), "isWordStart (\"Hello, world.\", 11) -> false"); t.notok (isWordStart (text, 12), "isWordStart (\"Hello, world.\", 12) -> false"); // bool isWordEnd (const std::string&, std::string::size_type); t.notok (isWordEnd ("", 0), "isWordEnd (\"\", 0) -> false"); t.ok (isWordEnd ("foo", 2), "isWordEnd (\"foo\", 2) -> true"); t.notok (isWordEnd (text, 0), "isWordEnd (\"Hello, world.\", 0) -> false"); t.notok (isWordEnd (text, 1), "isWordEnd (\"Hello, world.\", 1) -> false"); t.notok (isWordEnd (text, 2), "isWordEnd (\"Hello, world.\", 2) -> false"); t.notok (isWordEnd (text, 3), "isWordEnd (\"Hello, world.\", 3) -> false"); t.ok (isWordEnd (text, 4), "isWordEnd (\"Hello, world.\", 4) -> true"); t.notok (isWordEnd (text, 5), "isWordEnd (\"Hello, world.\", 5) -> false"); t.notok (isWordEnd (text, 6), "isWordEnd (\"Hello, world.\", 6) -> false"); t.notok (isWordEnd (text, 7), "isWordEnd (\"Hello, world.\", 7) -> false"); t.notok (isWordEnd (text, 8), "isWordEnd (\"Hello, world.\", 8) -> false"); t.notok (isWordEnd (text, 9), "isWordEnd (\"Hello, world.\", 9) -> false"); t.notok (isWordEnd (text, 10), "isWordEnd (\"Hello, world.\", 10) -> false"); t.ok (isWordEnd (text, 11), "isWordEnd (\"Hello, world.\", 11) -> true"); t.notok (isWordEnd (text, 12), "isWordEnd (\"Hello, world.\", 12) -> false"); // bool compare (const std::string&, const std::string&, bool caseless = false); // Make sure degenerate cases are handled. t.ok (compare ("", ""), "'' == ''"); t.notok (compare ("foo", ""), "foo != ''"); t.notok (compare ("", "foo"), "'' != foo"); // Make sure the default is case-sensitive. t.ok (compare ("foo", "foo"), "foo == foo"); t.notok (compare ("foo", "FOO"), "foo != foo"); // Test case-sensitive. t.notok (compare ("foo", "xx", true), "foo != xx"); t.ok (compare ("foo", "foo", true), "foo == foo"); t.notok (compare ("foo", "FOO", true), "foo != FOO"); t.notok (compare ("FOO", "foo", true), "FOO != foo"); t.ok (compare ("FOO", "FOO", true), "FOO == FOO"); // Test case-insensitive. t.notok (compare ("foo", "xx", false), "foo != foo (caseless)"); t.ok (compare ("foo", "foo", false), "foo == foo (caseless)"); t.ok (compare ("foo", "FOO", false), "foo == FOO (caseless)"); t.ok (compare ("FOO", "foo", false), "FOO == foo (caseless)"); t.ok (compare ("FOO", "FOO", false), "FOO == FOO (caseless)"); // std::string::size_type find (const std::string&, const std::string&, bool caseless = false); // Make sure degenerate cases are handled. t.is ((int) find ("foo", ""), (int) 0, "foo !contains ''"); t.is ((int) find ("", "foo"), (int) std::string::npos, "'' !contains foo"); // Make sure the default is case-sensitive. t.is ((int) find ("foo", "fo"), 0, "foo contains fo"); t.is ((int) find ("foo", "FO"), (int) std::string::npos, "foo !contains fo"); // Test case-sensitive. t.is ((int) find ("foo", "xx", true), (int) std::string::npos, "foo !contains xx"); t.is ((int) find ("foo", "oo", true), 1, "foo contains oo"); t.is ((int) find ("foo", "fo", true), 0, "foo contains fo"); t.is ((int) find ("foo", "FO", true), (int) std::string::npos, "foo !contains fo"); t.is ((int) find ("FOO", "fo", true), (int) std::string::npos, "foo !contains fo"); t.is ((int) find ("FOO", "FO", true), 0, "foo contains fo"); // Test case-insensitive. t.is ((int) find ("foo", "xx", false), (int) std::string::npos, "foo !contains xx (caseless)"); t.is ((int) find ("foo", "oo", false), 1, "foo contains oo (caseless)"); t.is ((int) find ("foo", "fo", false), 0, "foo contains fo (caseless)"); t.is ((int) find ("foo", "FO", false), 0, "foo contains FO (caseless)"); t.is ((int) find ("FOO", "fo", false), 0, "FOO contains fo (caseless)"); t.is ((int) find ("FOO", "FO", false), 0, "FOO contains FO (caseless)"); // Test start offset. t.is ((int) find ("one two three", "e", 3, true), (int) 11, "offset obeyed"); t.is ((int) find ("one two three", "e", 11, true), (int) 11, "offset obeyed"); // int strippedLength (const std::string&); t.is (strippedLength (std::string ("")), 0, "strippedLength -> 0"); t.is (strippedLength (std::string ("abc")), 3, "strippedLength abc -> 3"); t.is (strippedLength (std::string ("one\033[5;38;255mtwo\033[0mthree")), 11, "strippedLength one^[[5;38;255mtwo^[[0mthree -> 11"); t.is (strippedLength (std::string ("\033[0m")), 0, "strippedLength ^[[0m -> 0"); t.is (strippedLength (std::string ("\033[1m\033[0m")), 0, "strippedLength ^[[1m^[[0m -> 0"); // std::string format (char); t.is (format ('A'), "A", "format ('A') -> A"); // std::string format (int); t.is (format (0), "0", "format (0) -> 0"); t.is (format (-1), "-1", "format (-1) -> -1"); // std::string formatHex (int); t.is (formatHex (0), "0", "formatHex (0) -> 0"); t.is (formatHex (10), "a", "formatHex (10) -> a"); t.is (formatHex (123), "7b", "formatHex (123) -> 7b"); // std::string format (float, int, int); t.is (format (1.23456789, 8, 1), " 1", "format (1.23456789, 8, 1) -> _______1"); t.is (format (1.23456789, 8, 2), " 1.2", "format (1.23456789, 8, 2) -> _____1.2"); t.is (format (1.23456789, 8, 3), " 1.23", "format (1.23456789, 8, 3) -> ____1.23"); t.is (format (1.23456789, 8, 4), " 1.235", "format (1.23456789, 8, 4) -> ___1.235"); t.is (format (1.23456789, 8, 5), " 1.2346", "format (1.23456789, 8, 5) -> __1.2346"); t.is (format (1.23456789, 8, 6), " 1.23457", "format (1.23456789, 8, 6) -> 1.23457"); t.is (format (1.23456789, 8, 7), "1.234568", "format (1.23456789, 8, 7) -> 1.234568"); t.is (format (1.23456789, 8, 8), "1.2345679", "format (1.23456789, 8, 8) -> 1.2345679"); t.is (format (2444238.56789, 12, 11), "2444238.5679", "format (2444238.56789, 12, 11) -> 2444238.5679"); // std::string format (double, int, int); // std::string leftJustify (const std::string&, const int); t.is (leftJustify (123, 3), "123", "leftJustify 123,3 -> '123'"); t.is (leftJustify (123, 4), "123 ", "leftJustify 123,4 -> '123 '"); t.is (leftJustify (123, 5), "123 ", "leftJustify 123,5 -> '123 '"); // std::string leftJustify (const std::string&, const int); t.is (leftJustify ("foo", 3), "foo", "leftJustify foo,3 -> 'foo'"); t.is (leftJustify ("foo", 4), "foo ", "leftJustify foo,4 -> 'foo '"); t.is (leftJustify ("foo", 5), "foo ", "leftJustify foo,5 -> 'foo '"); t.is (leftJustify ("föo", 5), "föo ", "leftJustify föo,5 -> 'föo '"); // std::string rightJustify (const std::string&, const int); t.is (rightJustify (123, 3), "123", "rightJustify 123,3 -> '123'"); t.is (rightJustify (123, 4), " 123", "rightJustify 123,4 -> ' 123'"); t.is (rightJustify (123, 5), " 123", "rightJustify 123,5 -> ' 123'"); // std::string rightJustify (const std::string&, const int); t.is (rightJustify ("foo", 3), "foo", "rightJustify foo,3 -> 'foo'"); t.is (rightJustify ("foo", 4), " foo", "rightJustify foo,4 -> ' foo'"); t.is (rightJustify ("foo", 5), " foo", "rightJustify foo,5 -> ' foo'"); t.is (rightJustify ("föo", 5), " föo", "rightJustify föo,5 -> ' föo'"); // int utf8_length (const std::string&); t.is ((int) utf8_length ("Çirçös"), 6, "utf8_length (Çirçös) == 6"); t.is ((int) utf8_length ("ツネナラム"), 5, "utf8_length (ツネナラム) == 5"); t.is ((int) utf8_length ("Zwölf Boxkämpfer"), 16, "utf8_length (Zwölf Boxkämpfer) == 16"); return 0; }
virtual void customSetup(void) { QMenu *edit = toMainWidget()->getEditMenu(); edit->addSeparator(); IncMenu = edit->addMenu( qApp->translate("toEditExtensionTool", "Incremental Search")); IncrementalSearch = IncMenu->addAction(qApp->translate("toEditExtensionTool", "Forward"), &toEditExtensionsSingle::Instance(), SLOT(searchForward())); IncrementalSearch->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_S); ReverseSearch = IncMenu->addAction(qApp->translate("toEditExtensionTool", "Backward"), &toEditExtensionsSingle::Instance(), SLOT(searchBackward())); ReverseSearch->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_R); // ------------------------------ indentation menu IndentMenu = edit->addMenu( qApp->translate("toEditExtensionTool", "Auto Indent")); IndentBlock = IndentMenu->addAction(qApp->translate( "toEditExtensionTool", "Selection"), &toEditExtensionsSingle::Instance(), SLOT(autoIndentBlock())); IndentBlock->setShortcut(Qt::CTRL + + Qt::ALT + Qt::Key_I); IndentBuffer = IndentMenu->addAction(qApp->translate( "toEditExtensionTool", "Editor"), &toEditExtensionsSingle::Instance(), SLOT(autoIndentBuffer())); IndentBuffer->setShortcut(Qt::CTRL + Qt::ALT + Qt::SHIFT + Qt::Key_I); IndentMenu->addSeparator(); ObsBlock = IndentMenu->addAction(qApp->translate( "toEditExtensionTool", "Obfuscate Selection"), &toEditExtensionsSingle::Instance(), SLOT(obfuscateBlock())); ObsBuffer = IndentMenu->addAction(qApp->translate("toEditExtensionTool", "Obfuscate Editor"), &toEditExtensionsSingle::Instance(), SLOT(obfuscateBuffer())); // ------------------------------ case menu CaseMenu = edit->addMenu( qApp->translate("toEditExtensionTool", "Modify Case")); UpperCase = CaseMenu->addAction(qApp->translate("toEditExtensionTool", "Upper"), &toEditExtensionsSingle::Instance(), SLOT(upperCase())); UpperCase->setShortcut(Qt::CTRL + Qt::Key_U); LowerCase = CaseMenu->addAction(qApp->translate("toEditExtensionTool", "Lower"), &toEditExtensionsSingle::Instance(), SLOT(lowerCase())); LowerCase->setShortcut(Qt::CTRL + Qt::Key_L); // bookmark menu BookmarkMenu = edit->addMenu(qApp->translate("toEditExtensionTool", "Bookmarks")); BookmarkSwitchAct = BookmarkMenu->addAction("Add/Remove Bookmark", &toEditExtensionsSingle::Instance(), SLOT(bookmarkSwitch())); BookmarkSwitchAct->setShortcut(Qt::CTRL + Qt::Key_B); BookmarkPrevAct = BookmarkMenu->addAction("Go to previous Bookmark", &toEditExtensionsSingle::Instance(), SLOT(bookmarkPrev())); BookmarkPrevAct->setShortcut(Qt::ALT + Qt::Key_PageUp); BookmarkNextAct = BookmarkMenu->addAction("Go to next Bookmark", &toEditExtensionsSingle::Instance(), SLOT(bookmarkNext())); BookmarkNextAct->setShortcut(Qt::ALT + Qt::Key_PageDown); // EOL menu EolMenu = edit->addMenu(qApp->translate("toEditExtensionTool", "Convert End of Lines to")); EolUnixAct = EolMenu->addAction("UNIX", &toEditExtensionsSingle::Instance(), SLOT(convertEol())); EolMacAct = EolMenu->addAction("Mac OS X", &toEditExtensionsSingle::Instance(), SLOT(convertEol())); EolWindowsAct = EolMenu->addAction("MS Windows", &toEditExtensionsSingle::Instance(), SLOT(convertEol())); // ------------------------------ etc Indent = edit->addAction( QIcon(QPixmap(const_cast<const char**>(indent_xpm))), qApp->translate("toEditExtensionTool", "Indent Block"), &toEditExtensionsSingle::Instance(), SLOT(indentBlock())); #ifndef Q_WS_MAC Indent->setShortcut(Qt::ALT + Qt::Key_Right); #endif Deindent = edit->addAction( QIcon(QPixmap(const_cast<const char**>(deindent_xpm))), qApp->translate("toEditExtensionTool", "De-indent Block"), &toEditExtensionsSingle::Instance(), SLOT(deindentBlock())); #ifndef Q_WS_MAC Deindent->setShortcut(Qt::ALT + Qt::Key_Left); #endif Quote = edit->addAction(qApp->translate("toEditExtensionTool", "Quote Selection"), &toEditExtensionsSingle::Instance(), SLOT(quoteBlock())); UnQuote = edit->addAction(qApp->translate("toEditExtensionTool", "UnQuote Selection"), &toEditExtensionsSingle::Instance(), SLOT(unquoteBlock())); Comment = edit->addAction(qApp->translate("toEditExtensionTool", "Comment or Uncomment"), &toEditExtensionsSingle::Instance(), SLOT(handleComment()), Qt::CTRL + Qt::Key_D); GotoLine = edit->addAction(qApp->translate("toEditExtensionTool", "Goto Line"), &toEditExtensionsSingle::Instance(), SLOT(gotoLine())); GotoLine->setShortcut(Qt::CTRL + Qt::Key_G); AutoComplete = edit->addAction( qApp->translate("toEditExtensionTool", "Complete"), &toEditExtensionsSingle::Instance(), SLOT(autoComplete())); AutoComplete->setShortcut(Qt::CTRL + Qt::Key_Space); // add buttons to main window // disabled due the problems in the state of toolbars // toMainWidget()->addButtonApplication(Deindent); // toMainWidget()->addButtonApplication(Indent); toEditExtensionsSingle::Instance().receivedFocus(NULL); connect(toMainWidget(), SIGNAL(editEnabled(bool)), &toEditExtensionsSingle::Instance(), SLOT(editEnabled(bool))); }
// Turns LLL tree into tree of code fragments programData opcodeify(Node node, programAux aux=Aux()) { std::string symb = "_"+mkUniqueToken(); Metadata m = node.metadata; // Numbers if (node.type == TOKEN) { return pd(aux, nodeToNumeric(node)); } else if (node.val == "ref" || node.val == "get" || node.val == "set") { std::string varname = node.args[0].val; if (!aux.vars.count(varname)) { aux.vars[varname] = intToDecimal(aux.vars.size() * 32); } if (varname == "msg.data") aux.calldataUsed = true; // Set variable if (node.val == "set") { programData sub = opcodeify(node.args[1], aux); Node nodelist[] = { sub.code, token(aux.vars[varname], m), token("MSTORE", m), }; return pd(sub.aux, multiToken(nodelist, 3, m)); } // Get variable else if (node.val == "get") { Node nodelist[] = { token(aux.vars[varname], m), token("MLOAD", m) }; return pd(aux, multiToken(nodelist, 2, m)); } // Refer variable else return pd(aux, token(aux.vars[varname], m)); } // Code blocks if (node.val == "lll" && node.args.size() == 2) { if (node.args[1].val != "0") aux.allocUsed = true; std::vector<Node> o; o.push_back(finalize(opcodeify(node.args[0]))); programData sub = opcodeify(node.args[1], aux); Node code = astnode("____CODE", o, m); Node nodelist[] = { token("$begincode"+symb+".endcode"+symb, m), token("DUP", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$endcode"+symb, m), token("JUMP", m), token("~begincode"+symb, m), code, token("~endcode"+symb, m) }; return pd(sub.aux, multiToken(nodelist, 10, m)); } std::vector<Node> subs; for (unsigned i = 0; i < node.args.size(); i++) { programData sub = opcodeify(node.args[i], aux); aux = sub.aux; subs.push_back(sub.code); } // Debug if (node.val == "debug") { Node nodelist[] = { subs[0], token("DUP", m), token("POP", m), token("POP", m) }; return pd(aux, multiToken(nodelist, 4, m)); } // Seq of multiple statements if (node.val == "seq") { return pd(aux, astnode("_", subs, m)); } // 2-part conditional (if gets rewritten to unless in rewrites) else if (node.val == "unless" && node.args.size() == 2) { Node nodelist[] = { subs[0], token("$endif"+symb, m), token("JUMPI", m), subs[1], token("~endif"+symb, m) }; return pd(aux, multiToken(nodelist, 5, m)); } // 3-part conditional else if (node.val == "if" && node.args.size() == 3) { Node nodelist[] = { subs[0], token("NOT", m), token("$else"+symb, m), token("JUMPI", m), subs[1], token("$endif"+symb, m), token("JUMP", m), token("~else"+symb, m), subs[2], token("~endif"+symb, m) }; return pd(aux, multiToken(nodelist, 10, m)); } // While (rewritten to this in rewrites) else if (node.val == "until") { Node nodelist[] = { token("~beg"+symb, m), subs[0], token("$end"+symb, m), token("JUMPI", m), subs[1], token("$beg"+symb, m), token("JUMP", m), token("~end"+symb, m) }; return pd(aux, multiToken(nodelist, 8, m)); } // Memory allocations else if (node.val == "alloc") { aux.allocUsed = true; Node nodelist[] = { subs[0], token("MSIZE", m), token("SWAP", m), token("MSIZE", m), token("ADD", m), token("0", m), token("SWAP", m), token("MSTORE", m) }; return pd(aux, multiToken(nodelist, 8, m)); } // Array literals else if (node.val == "array_lit") { aux.allocUsed = true; std::vector<Node> nodes; if (!subs.size()) { nodes.push_back(token("MSIZE", m)); return pd(aux, astnode("_", nodes, m)); } nodes.push_back(token("MSIZE", m)); nodes.push_back(token("0", m)); nodes.push_back(token("MSIZE", m)); nodes.push_back(token(intToDecimal(subs.size() * 32 - 1), m)); nodes.push_back(token("ADD", m)); nodes.push_back(token("MSTORE8", m)); for (unsigned i = 0; i < subs.size(); i++) { nodes.push_back(token("DUP", m)); nodes.push_back(subs[i]); nodes.push_back(token("SWAP", m)); if (i > 0) { nodes.push_back(token(intToDecimal(i * 32), m)); nodes.push_back(token("ADD", m)); } nodes.push_back(token("MSTORE", m)); } return pd(aux, astnode("_", nodes, m)); } // All other functions/operators else { std::vector<Node> subs2; while (subs.size()) { subs2.push_back(subs.back()); subs.pop_back(); } subs2.push_back(token(upperCase(node.val), m)); return pd(aux, astnode("_", subs2, m)); } }
bool FastaReader::readFile(QString fileName) { string file = fileName.toStdString(); //Make sure that we were requested to open a file if(file.empty()) { return false; } ui->print(file); setupProgressBar(); //Parse the name of the chromosome from the file name and send it to glwidget to be stored storeChrName(file); //Clear out anything that may be left in the sequence string and set initial pad character sequence.clear(); sequence = ""; sequence.reserve(5); sequence = string(">"); //Clear out anything that may be in the ifstream then open the new file wordfile.clear(); wordfile.open(file.c_str(), ifstream::in | ifstream::binary); //See if we opened the file successfully if(wordfile.fail()) { ErrorBox msg("Could not read the file. Either Skittle doesn't have file permissions or the file does not exist."); return false; } //Get how many characters are in the file wordfile.seekg(0, ios::beg); int begin = wordfile.tellg(); wordfile.seekg(0, ios::end); int end = wordfile.tellg(); bytesInFile = end - begin; //Discovered Reserve is different than malloc by creating a memory iterator //The iterator takes old size, then virtually allocates a new vector to new size while at the same time copying start/end memory to this new location //Then it destroys the old vector and walks through physical storage looking for a contiguous slot open, then dumps into the start and end location of new slot sequence.reserve(bytesInFile); //Start progress bar at 0 int progress = bytesInFile / 20; progressBar->setValue(progress); QApplication::processEvents(); //Return to the beginning of the file wordfile.seekg(0, ios::beg); //Skip the first line of the file as this is the chromosome name/info wordfile.ignore(500, '\n'); //Read in the rest of the file char current; int i = 0; cancelled = false; do { //If the cancel button was pushed, go ahead and exit fasta reader if(cancelled){ return false; } //Read the next character wordfile >> current; //If it is a letter, uppercase it current = upperCase(current); //if(current == 65 || current == 67 || current == 71 || current == 84 || current == 78) //A C G T N if(current != '\n' && current != '\r') { sequence.push_back(current); } if(i != 0 && i % progress == 0) { progressBar->setValue(progressBar->value() + 5); QApplication::processEvents(); } i++; } while(!wordfile.eof() && !wordfile.fail() && !cancelled); //Close up everything progressBar->reset(); progressBar->close(); if(progressBar) { delete progressBar; progressBar = NULL; } wordfile.close(); ui->print("Done loading file!"); emit newFileRead(seq()); return true; }
DwUseQuery::DwUseQuery(DwUseOptions* options) { this->options = options; // create a database connection try { this->conn = new DbConnect( options->Username(), options->Password(), options->Database() ); } catch( SQLException ex ) { throw DwUseException( "Error connecting to the database with " + options->Username() +"/" + options->Password() + "@" + options->Database() +": \n" + ex.getMessage() ); } // create variable translator for column this->variableTranslator = new VariableTranslator(this->conn, this->options->Table()); // collect final list of variables // if there are none in the options, read all from the database // else read only the ones in the list string probeSql = "select "; // create a DwColumn for each column that we need (maybe leave out the technical cols) vector<string> cols = this->options->Variables(); if( cols.size() == 0 ) { probeSql += "* "; // we'll check what kind of columns we see. I don't know the schema, or whether table is a view or synonym } else { for(size_t i = 0; i < cols.size(); i++) { if( i > 0 ) probeSql += ", "; probeSql += cols[i]; } } probeSql += " from " + this->options->Table() + " where 1=2 "; // run the probe query and collect columns vector<DbColumnMetaData> colMeta; vector<string> colNames; try { colMeta = this->conn->Describe(probeSql); } catch( SQLException ex ) { string msg = ex.getMessage(); throw DwUseException( "Error reading column definitions with \n" + probeSql +": \n" + msg ); } // we'll need to know what to translate set<string> transVars = this->options->LabelVariables(); set<string> transVals = this->options->LabelValues(); bool isTransAllVars = this->options->IsLabelVariables() && transVars.size() == 0; bool isTransAllVals = this->options->IsLabelValues() && transVals.size() == 0; // create meta data holders for(size_t i=0; i<colMeta.size(); i++) { // get the column name so we can decide if it needs tranlation or not string colName = colMeta[i].name; // not qouted // translate or not? DwColumn* dwCol = new DwColumn( colMeta[i], i+1, // position in ResultSet this->options->VariableCasing(), (isTransAllVars || transVars.find(upperCase(colName)) != transVars.end()) ? this->variableTranslator : NULL, (isTransAllVals || transVals.find(upperCase(colName)) != transVals.end()) ? new ValueTranslator(this->conn, this->options->Table(), colName) : NULL ); this->columns.push_back( dwCol ); colNames.push_back( upperCase(colName) ); // to test translations } // check that all the variables selected for labeling are valid column names CheckLabels( transVars, colNames, "label_variable" ); CheckLabels( transVals, colNames, "label_values" ); };