/** \brief Set the argument offsets for a function, then kick off compiling * of the function * * \param prevarg - Last argument * \param currfn - Current function */ void setlocvar(SYMBOL *prevarg,SYMBOL *currfn) { int lgh,where; int *iptr; SYMBOL *copyarg; int argnumber; char buffer2[120]; unsigned char tester; lgh = 0; /* Initialise it */ if ( prevarg != NULL && currfn->prototyped == 0 ) { StoreFunctionSignature(prevarg); } argnumber=currfn->prototyped; /* * If we have filled up our number of arguments, then pretend * we don't have any..nasty, nasty */ if (argnumber==(MAXARGS-1)) argnumber=0; else if (argnumber) argnumber=1; /* * Dump some info about defining the function etc */ if (verbose){ toconsole(); outstr("Defining function: "); outstr(currfn->name); nl(); tofile(); } nl();prefix();outname(currfn->name,dopref(currfn));col();nl(); /* print function name */ infunc=1; /* In a function for sure! */ copyarg=prevarg; if ( ( (currfn->flags&SHARED) && makeshare ) || sharedfile ) { /* Shared library definition, offset the stack */ where= 2 +shareoffset; } else where = 2 ; /* If we use frame pointer we preserve previous framepointer on entry * to each function */ #ifdef USEFRAME if (useframe) where+=2; #endif while ( prevarg ) { lgh = 2 ; /* Default length */ /* This is strange, previously double check for ->type */ if ( prevarg->type == LONG && prevarg->ident != POINTER ) lgh=4; if ( prevarg->type == DOUBLE && prevarg->ident != POINTER ) lgh=6; /* Far pointers */ if ( (prevarg->flags&FARPTR)==FARPTR && prevarg->ident == POINTER) lgh=4; prevarg->size=lgh; #ifdef CODSWALLOP /* All pointers are pushed onto the stack for functions as 4 bytes, if * needed, near pointers are padded out to compensate for this by dummy * loading with zero, this allows us to have one set of routines to * cope with this and hence solve a lot of duplication */ if (prevarg->ident == POINTER && lpointer) lgh=4; prevarg->size=lgh; #endif /* * Check the definition against prototypes here... */ if (argnumber) { tester=CalcArgValue(prevarg->type,prevarg->ident,prevarg->flags); if (currfn->args[argnumber] != tester ) { if (currfn->args[argnumber] != PELLIPSES ) { if (currfn->args[argnumber] == 0 ) { warning(W_2MADECL); } else { if ( (currfn->args[argnumber]&PMASKSIGN) == (tester&PMASKSIGN) ) { warning(W_SIGNARG); } else { error(E_ARGMIS1,currfn->name,currfn->prototyped-argnumber+1, ExpandArgValue(tester,buffer2,prevarg->tag_idx) ); error(E_ARGMIS2,ExpandArgValue(currfn->args[argnumber],buffer2, currfn->tagarg[argnumber])); } } } } argnumber++; } iptr = &prevarg->offset.i ; prevarg = prevarg->offset.p ; /* follow ptr to prev. arg */ *iptr = where ; /* insert offset */ where += lgh ; /* calculate next offset */ } #ifdef USEFRAME pushframe(); #endif currfn->handled=YES; if (currfn->prototyped==1 && (currfn->flags®CALL) ) { /* * Fast call routine.. */ if (lgh==2) zpush(); else if (lgh==4) lpush(); else if (lgh==6) dpush(); /* erk, if not matched, dodgy type! */ copyarg->offset.i=-lgh; where=2; } stackargs=where; lstdecl=0; /* Set number of local statics to zero */ if ( statement() != STRETURN ) { if (lstdecl) postlabel(lstlab); lstdecl=0; /* do a statement, but if it's a return, skip */ /* cleaning up the stack */ leave(NO,NO) ; } CleanGoto(); /* Asz80 needs a label at the end to sort out local symbols */ if (asxx) { nl();prefix(); outstr("smce_"); outname(currfn->name,NO); col();nl(); } #ifdef INBUILT_OPTIMIZER generate(); #endif infunc = 0 ; /* not in fn. any more */ }
int PET::write( int options ) { int sl, fr; ofstream outfile; char outbuff[100]; string patid( getPatientID() ); string outname( getPatientID() ); string patname( _prefix ); cout << "PET::write(): " << _numFrame << " frames of " << _numSlice << " slices." << endl; if ( options & OPT_VOLU ) { // Using one output file. // string outname( _prefix + "." ); // string outname( + "." ); outname.append( "." ); outname.append( (options & OPT_ANAL) ? "img" : "raw"); outfile.open( outname.c_str(), ios::binary ); if ( !outfile.is_open() ) error( "Cannot open output file", outname ); // Write the Analyze header if required. if ( options & OPT_ANAL ) analyze->writePET( this, outname, options, 0 ); } // Run through each frame and write to disk. std::transform(patname.begin(), patname.end(), patname.begin(), (int(*)(int)) toupper); for ( fr = 0; fr < _numFrame; fr++ ) { if ( !( options & OPT_VOLU )) { // New output file per frame if not writing to one file. // Changed this 4/2/07 ahc. Can't remember why I was using patid // rather than abbreviated name for Analyze files. // sprintf( outbuff, "%s_%02d.%s", // patid.c_str(), fr, (options & OPT_ANAL) ? "img" : "raw" ); sprintf( outbuff, "%s_%02d.%s", patname.c_str(), fr, (options & OPT_ANAL) ? "img" : "raw" ); outfile.open( outbuff, ios::binary ); if ( !outfile.is_open() ) error( "Cannot open output file", outbuff ); // Write the Analyze header if required. if ( options & OPT_ANAL ) analyze->writePET( this, outbuff, options, fr ); } // Call virtual fn. for specific PET slices. for ( int sl = 0; sl < _numSlice; sl++ ) { writeSliceData( fr, sl, outfile, options ); } if ( !( options & OPT_VOLU )) outfile.close(); cout << ((fr + 1) % 10) << flush; } cout << endl; if ( outfile.is_open() ) outfile.close(); return 0; }
bool GBuildMakefileGenerator::writeMakefile(QTextStream &text) { QStringList tmp; QString filename(Option::output.fileName()); QString pathtoremove(qmake_getpwd()); QString relpath(pathtoremove); QString strtarget(project->first("TARGET")); bool isnativebin = nativebins.contains(strtarget); relpath.replace(Option::output_dir, ""); /* correct output for non-prl, non-recursive case */ QString outname(qmake_getpwd()); outname += QDir::separator(); outname += strtarget; outname += projectSuffix(); Option::output.close(); Option::output.setFileName(outname); MakefileGenerator::openOutput(Option::output, QString()); if (strtarget != fileInfo(project->projectFile()).baseName().section('.', -2, -2)) { QString gpjname(strtarget); QString outputName(qmake_getpwd()); outputName += QDir::separator(); outputName += fileInfo(project->projectFile()).baseName(); outputName += projectSuffix(); QFile f(outputName); f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); QTextStream t(&f); t << "#!gbuild\n"; t << "[Project]\n"; t << gpjname << projectSuffix() << "\n"; if ((project->first("TEMPLATE") == "lib") && project->isActiveConfig("shared")) t << gpjname << "_shared" << projectSuffix() << "\n"; t.flush(); gpjname += projectSuffix(); Option::output.close(); Option::output.setFileName(gpjname); MakefileGenerator::openOutput(Option::output, QString()); } if ((project->first("TEMPLATE") == "app") && (!isnativebin)) { QTextStream t(&Option::output); QString intname(strtarget); intname += ".int"; /* this is for bulding an INTEGRITY application. * generate the .int integrate file and the .gpj INTEGRITY Application * project file, then go on with regular files */ t << "#!gbuild" << "\n"; t << "[INTEGRITY Application]" << "\n"; t << "\t:binDirRelative=.\n"; t << "\t-o " << strtarget << "\n"; t << intname << "\n"; t << strtarget << "_app" << projectSuffix() << "\n"; t.flush(); /* generate integrate file */ QFile f(intname); f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); QTextStream ti(&f); ti << "# This is a file automatically generated by qmake" << "\n"; ti << "# Modifications will be lost next time you run qmake" << "\n"; ti << "Kernel" << "\n"; ti << "\tFilename\tDynamicDownload" << "\n"; ti << "EndKernel" << "\n" << "\n"; ti << "AddressSpace" << "\n"; ti << "\tName\t" << strtarget << "\n"; ti << "\tFilename\t" << strtarget << "_app" << "\n"; ti << "\tMemoryPoolSize\t0x100000" << "\n"; ti << "\tLanguage\tC++" << "\n"; /* FIXME : heap size is huge to be big enough for every example * it should probably be tailored for each example, btu there is no * good way to guess that */ ti << "\tHeapSize\t0x00D00000" << "\n"; ti << "\tTask\tInitial" << "\n"; ti << "\t\tStackSize\t0x30000" << "\n"; ti << "\t\tStartIt\tTrue" << "\n"; ti << "\tEndTask" << "\n"; ti << "EndAddressSpace" << "\n"; ti.flush(); /* change current project file to <projectname>_app.gpj and continue * generation */ outname.insert(outname.lastIndexOf("."), "_app"); Option::output.close(); Option::output.setFileName(outname); MakefileGenerator::openOutput(Option::output, QString()); } else if ((project->first("TEMPLATE") == "lib") && project->isActiveConfig("dll")) { QString gpjname(strtarget); gpjname += "_shared"; gpjname += projectSuffix(); QFile f(gpjname); f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); QTextStream t(&f); t << "#!gbuild\n" "[Program]\n" "\t-A libINTEGRITY.so\n" "\t-A libc.so\n" "\t-A libscxx.so\n" "\t-A libQtCore.so\n" "\t-e __ghsbegin_text\n" "\t-startfile=-\n" "\t:syslibraries=-\n" "\t-Onolink\n"; t << "\t-o lib" << strtarget << ".so\n"; t << "\t-l" << strtarget << "\n"; t << "\t-extractall=-l" << strtarget << "\n"; t << "\t:outputDir=work/" << filename.section(QDir::separator(), 0, -1).remove(".gpj") << "\n"; t << strtarget << "_shared.ld\n"; t << "$(__OS_DIR)/intlib/sharedobjbssinit.c\n"; t.flush(); QFile fl(strtarget + "_shared.ld"); fl.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); QTextStream tl(&fl); tl << "CONSTANTS {\n" " __INTEGRITY_MinPageAlign = 16K\n" " __INTEGRITY_MaxPageAlign = 16K\n" " __INTEGRITY_LibCBaseAddress = \n"; tl << dllbase << "\n"; tl << "}\n" "-sec\n" "{\n" " .picbase __INTEGRITY_LibCBaseAddress :\n" " .text :\n" " .syscall :\n" " .intercall :\n" " .interfunc :\n" " .secinfo :\n" " .rodata align(16) :\n" " .fixaddr :\n" " .fixtype :\n" " .rombeg :\n" " .textchecksum :\n" " // The above sections may be large. Leave a bigger gap for large pages.\n" " .pidbase align(__INTEGRITY_MaxPageAlign) :\n" " .sdabase :\n" " .data :\n" " .toc :\n" " .opd :\n" " .datachecksum :\n" " .sbss : \n" " .bss align(__INTEGRITY_MinPageAlign) :\n" " .argsection(__INTEGRITY_MaxPageAlign) :\n" " .heap : \n" "}\n"; tl.flush(); dllbase += DLLOFFSET; } warn_msg(WarnParser, Option::output.fileName().toAscii()); QTextStream t(&Option::output); QString primaryTarget; if (!project->values("QMAKE_CXX").isEmpty()) primaryTarget = project->values("QMAKE_CXX").at(0); pathtoremove += QDir::separator(); filename.remove(qmake_getpwd()); //HEADER t << "#!gbuild" << "\n"; /* find the architecture out of the compiler name */ if (filename.endsWith("projects.gpj")) { primaryTarget.remove(0, 5); t << "macro QT_BUILD_DIR=%expand_path(.)\n"; t << "macro __OS_DIR=" << project->values("INTEGRITY_DIR").first() << "\n"; t << "primaryTarget=" << primaryTarget << "_integrity.tgt" << "\n"; t << "customization=util/integrity/qt.bod\n"; } /* project type */ if (project->first("TEMPLATE") == "app") { t << "[Program]" << "\n"; if (isnativebin) { t << "\t:binDir=bin\n"; t << "\t-o " << strtarget << "\n"; } else { t << "\t:binDirRelative=.\n"; t << "\t-o " << strtarget << "_app\n"; } } else if (project->first("TEMPLATE") == "lib") { t << "[Library]" << "\n"; t << "\t:binDir=lib" << "\n"; t << "\t-o lib" << strtarget << ".a" << "\n"; } else if (project->first("TEMPLATE") == "subdirs") t << "[Project]" << "\n"; else t << project->first("TEMPLATE") << "\n"; /* compilations options */ t << "\t:sourceDir=." << "\n"; t << "\t:outputDir=work" << relpath << "\n"; t << "\t-I${%expand_path(.)}/work" << relpath << "\n"; t << "\t--cxx_include_directory ${%expand_path(.)}/work" << relpath << "\n"; if (filename.endsWith("projects.gpj")) { t << "\t:sourceDir=work\n"; t << "\t-Iwork\n"; t << "\t-Llib\n"; t << "\t"; QStringList &l = project->values("QMAKE_CXXFLAGS"); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if ((*it).startsWith("-")) t << "\n" << "\t" << (*it); else t << " " << (*it); } t << "\n"; } t << "\n"; if (project->first("TEMPLATE") != "project") t << varGlue("DEFINES", "\t-D", "\n\t-D", "\n"); t << "\t-I.\n\t-I" << specdir() << "\n"; t << varGlue("INCLUDEPATH", "\t-I", "\n\t-I", "\n"); t << "\t--cxx_include_directory .\n\t--cxx_include_directory " << specdir() << "\n"; t << varGlue("INCLUDEPATH", "\t--cxx_include_directory ", "\n\t--cxx_include_directory ", "\n"); if (project->first("TEMPLATE") == "app") { /* include linker flags if it's an application */ QString src[] = { "QMAKE_LFLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", "LIBS", QString() }; for (int i = 0; !src[i].isNull(); i++) { /* skip target libraries for native tools */ if (isnativebin && (i == 0)) continue; t << "\t"; QStringList &l = project->values(src[i]); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if ((*it).startsWith("-")) t << "\n" << "\t" << (*it); else t << " " << (*it); } t << "\n"; } } /* first subdirectories/subprojects */ { QStringList &l = project->values("SUBDIRS"); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString gpjname((*it)); /* avoid native tools */ if (nativebins.contains(gpjname.section("_", -1))) continue; if (!project->first((*it) + ".subdir").isEmpty()) gpjname = project->first((*it) + ".subdir"); /* some SUBDIRS are not actually subdirs, instead .pro files */ if (gpjname.endsWith(".pro")) gpjname.chop(4); else gpjname += QDir::separator() + gpjname.section(QDir::separator(), -1); gpjname += projectSuffix(); /* make relative */ if (!project->values("QT_SOURCE_TREE").isEmpty()) { gpjname.replace(project->values("QT_SOURCE_TREE").first() + QDir::separator(), ""); } t << gpjname << "\n"; } } { QStringList &l = project->values("RESOURCES"); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString tmpstr((*it).replace(pathtoremove, "")); t << tmpstr << "\t[Qt Resource]\n"; tmpstr = tmpstr.section(".", -2, -1).section(QDir::separator(), -1); tmpstr.remove(".qrc"); t << "\t-name " << tmpstr << "\n"; tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "qrc_"); tmpstr.append(".cpp"); t << "\t-o work/" << relpath << QDir::separator() << tmpstr << "\n"; } } { QStringList &l = project->values("FORMS"); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString tmpstr((*it).replace(pathtoremove, "")); t << tmpstr << "\t[Qt Dialog]\n"; tmpstr = tmpstr.section(".", 0, 0).section(QDir::separator(), -1); tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "ui_"); tmpstr.remove(".ui"); tmpstr.append(".h"); t << "\t-o work/" << relpath << QDir::separator() << tmpstr << "\n"; } } /* source files for this project */ QString src[] = { "HEADERS", "SOURCES", QString() }; for (int i = 0; !src[i].isNull(); i++) { QStringList &l = project->values(src[i]); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if ((*it).isEmpty()) continue; /* native tools aren't preprocessed */ if (!isnativebin) t << writeOne((*it), pathtoremove); else t << (*it).remove(pathtoremove) << "\n"; } } t << "\n"; { QStringList &l = project->values("GENERATED_SOURCES"); for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { t << "work/" << relpath << QDir::separator() << (*it).section(QDir::separator(), -1) << "\n"; } } return true; }
/* * write information about function definition * * this is also done for static functions so we are able to check if * they are called with proper argument types */ void outfdef(sym_t *fsym, pos_t *posp, int rval, int osdef, sym_t *args) { int narg; sym_t *arg; /* reset the buffer */ outclr(); /* * line number of .c source, 'd' for declaration, Id of current * source (.c or .h), and line in current source * * we are already at the end of the function. If we are in the * .c source, posp->p_line is correct, otherwise csrc_pos.p_line * (for functions defined in header files). */ if (posp->p_file == csrc_pos.p_file) { outint(posp->p_line); } else { outint(csrc_pos.p_line); } outchar('d'); outint(getfnid(posp->p_file)); outchar('.'); outint(posp->p_line); /* flags */ /* both SCANFLIKE and PRINTFLIKE imply VARARGS */ if (prflstrg != -1) { nvararg = prflstrg; } else if (scflstrg != -1) { nvararg = scflstrg; } if (nvararg != -1) { outchar('v'); outint(nvararg); } if (scflstrg != -1) { outchar('S'); outint(scflstrg); } if (prflstrg != -1) { outchar('P'); outint(prflstrg); } nvararg = prflstrg = scflstrg = -1; outchar('d'); if (rval) /* has return value */ outchar('r'); if (llibflg) /* * mark it as used so lint2 does not complain about * unused symbols in libraries */ outchar('u'); if (osdef) /* old style function definition */ outchar('o'); if (fsym->s_scl == STATIC) outchar('s'); /* name of function */ outname(fsym->s_name); /* renamed name of function, if necessary */ if (fsym->s_rename) { outchar('r'); outname(fsym->s_rename); } /* argument types and return value */ if (osdef) { narg = 0; for (arg = args; arg != NULL; arg = arg->s_nxt) narg++; outchar('f'); outint(narg); for (arg = args; arg != NULL; arg = arg->s_nxt) outtype(arg->s_type); outtype(fsym->s_type->t_subt); } else { outtype(fsym->s_type); } }
/* * write out all information necessary for lint2 to check function * calls * * rvused is set if the return value is used (asigned to a variable) * rvdisc is set if the return value is not used and not ignored * (casted to void) */ void outcall(tnode_t *tn, int rvused, int rvdisc) { tnode_t *args, *arg; int narg, n, i; int64_t q; tspec_t t; /* reset buffer */ outclr(); /* * line number of .c source, 'c' for function call, Id of current * source (.c or .h), and line in current source */ outint(csrc_pos.p_line); outchar('c'); outint(getfnid(curr_pos.p_file)); outchar('.'); outint(curr_pos.p_line); /* * flags; 'u' and 'i' must be last to make sure a letter * is between the numeric argument of a flag and the name of * the function */ narg = 0; args = tn->tn_right; for (arg = args; arg != NULL; arg = arg->tn_right) narg++; /* informations about arguments */ for (n = 1; n <= narg; n++) { /* the last argument is the top one in the tree */ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) continue; arg = arg->tn_left; if (arg->tn_op == CON) { if (isityp(t = arg->tn_type->t_tspec)) { /* * XXX it would probably be better to * explizitly test the sign */ if ((q = arg->tn_val->v_quad) == 0) { /* zero constant */ outchar('z'); } else if (msb(q, t, 0) == 0) { /* positive if casted to signed */ outchar('p'); } else { /* negative if casted to signed */ outchar('n'); } outint(n); } } else if (arg->tn_op == AMPER && arg->tn_left->tn_op == STRING && arg->tn_left->tn_strg->st_tspec == CHAR) { /* constant string, write all format specifiers */ outchar('s'); outint(n); outfstrg(arg->tn_left->tn_strg); } } /* return value discarded/used/ignored */ outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i')); /* name of the called function */ outname(tn->tn_left->tn_left->tn_sym->s_name); /* types of arguments */ outchar('f'); outint(narg); for (n = 1; n <= narg; n++) { /* the last argument is the top one in the tree */ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) continue; outtype(arg->tn_left->tn_type); } /* expected type of return value */ outtype(tn->tn_type); }
/* * write information about a global declared/defined symbol * with storage class extern * * informations about function definitions are written in outfdef(), * not here */ void outsym(sym_t *sym, scl_t sc, def_t def) { /* * Static function declarations must also be written to the output * file. Compatibility of function declarations (for both static * and extern functions) must be checked in lint2. Lint1 can't do * this, especially not, if functions are declared at block level * before their first declaration at level 0. */ if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC)) return; /* reset buffer */ outclr(); /* * line number of .c source, 'd' for declaration, Id of current * source (.c or .h), and line in current source. */ outint(csrc_pos.p_line); outchar('d'); outint(getfnid(sym->s_dpos.p_file)); outchar('.'); outint(sym->s_dpos.p_line); /* flags */ switch (def) { case DEF: /* defined */ outchar('d'); break; case TDEF: /* tentative defined */ outchar('t'); break; case DECL: /* declared */ outchar('e'); break; default: lerror("outsym() 2"); } if (llibflg && def != DECL) { /* * mark it as used so we get no warnings from lint2 about * unused symbols in libraries. */ outchar('u'); } if (sc == STATIC) outchar('s'); /* name of the symbol */ outname(sym->s_name); /* renamed name of symbol, if necessary */ if (sym->s_rename) { outchar('r'); outname(sym->s_rename); } /* type of the symbol */ outtype(sym->s_type); }
/* * Write type into the output buffer. */ static void outtype(type_t *tp) { int t, s, na; tspec_t ts; type_t **ap; while (tp != NULL) { if ((ts = tp->t_tspec) == INT && tp->t_isenum) ts = ENUM; switch (ts) { case CHAR: t = 'C'; s = '\0'; break; case SCHAR: t = 'C'; s = 's'; break; case UCHAR: t = 'C'; s = 'u'; break; case SHORT: t = 'S'; s = '\0'; break; case USHORT: t = 'S'; s = 'u'; break; case INT: t = 'I'; s = '\0'; break; case UINT: t = 'I'; s = 'u'; break; case LONG: t = 'L'; s = '\0'; break; case ULONG: t = 'L'; s = 'u'; break; case QUAD: t = 'Q'; s = '\0'; break; case UQUAD: t = 'Q'; s = 'u'; break; case FLOAT: t = 'D'; s = 's'; break; case DOUBLE: t = 'D'; s = '\0'; break; case LDOUBLE: t = 'D'; s = 'l'; break; case VOID: t = 'V'; s = '\0'; break; case PTR: t = 'P'; s = '\0'; break; case ARRAY: t = 'A'; s = '\0'; break; case ENUM: t = 'T'; s = 'e'; break; case STRUCT: t = 'T'; s = 's'; break; case UNION: t = 'T'; s = 'u'; break; case FUNC: if (tp->t_args != NULL && !tp->t_proto) { t = 'f'; } else { t = 'F'; } s = '\0'; break; default: errx(1, "internal error: outtype() 1"); } if (tp->t_const) outchar('c'); if (tp->t_volatile) outchar('v'); if (s != '\0') outchar(s); outchar(t); if (ts == ARRAY) { outint(tp->t_dim); } else if (ts == ENUM || ts == STRUCT || ts == UNION) { if (tp->t_istag) { outint(1); outname(tp->t_tag->h_name); } else if (tp->t_istynam) { outint(2); outname(tp->t_tynam->h_name); } else if (tp->t_isuniqpos) { outint(3); outint(tp->t_uniqpos.p_line); outchar('.'); outint(tp->t_uniqpos.p_file); outchar('.'); outint(tp->t_uniqpos.p_uniq); } else errx(1, "internal error: outtype() 2"); } else if (ts == FUNC && tp->t_args != NULL) { na = 0; for (ap = tp->t_args; *ap != NULL; ap++) na++; if (tp->t_vararg) na++; outint(na); for (ap = tp->t_args; *ap != NULL; ap++) outtype(*ap); if (tp->t_vararg) outchar('E'); } tp = tp->t_subt; } }
int rapMapMap(int argc, char* argv[]) { std::cerr << "RapMap Mapper\n"; std::string versionString = rapmap::version; TCLAP::CmdLine cmd( "RapMap Mapper", ' ', versionString); cmd.getProgramName() = "rapmap"; TCLAP::ValueArg<std::string> index("i", "index", "The location of the pseudoindex", true, "", "path"); TCLAP::ValueArg<std::string> read1("1", "leftMates", "The location of the left paired-end reads", false, "", "path"); TCLAP::ValueArg<std::string> read2("2", "rightMates", "The location of the right paired-end reads", false, "", "path"); TCLAP::ValueArg<std::string> unmatedReads("r", "unmatedReads", "The location of single-end reads", false, "", "path"); TCLAP::ValueArg<uint32_t> numThreads("t", "numThreads", "Number of threads to use", false, 1, "positive integer"); TCLAP::ValueArg<uint32_t> maxNumHits("m", "maxNumHits", "Reads mapping to more than this many loci are discarded", false, 200, "positive integer"); TCLAP::ValueArg<std::string> outname("o", "output", "The output file (default: stdout)", false, "", "path"); TCLAP::SwitchArg endCollectorSwitch("e", "endCollector", "Use the simpler (and faster) \"end\" collector as opposed to the more sophisticated \"skipping\" collector", false); TCLAP::SwitchArg noout("n", "noOutput", "Don't write out any alignments (for speed testing purposes)", false); cmd.add(index); cmd.add(noout); cmd.add(read1); cmd.add(read2); cmd.add(unmatedReads); cmd.add(outname); cmd.add(numThreads); cmd.add(maxNumHits); cmd.add(endCollectorSwitch); auto consoleSink = std::make_shared<spdlog::sinks::stderr_sink_mt>(); auto consoleLog = spdlog::create("stderrLog", {consoleSink}); try { cmd.parse(argc, argv); bool pairedEnd = (read1.isSet() or read2.isSet()); if (pairedEnd and (read1.isSet() != read2.isSet())) { consoleLog->error("You must set both the -1 and -2 arguments to align " "paired end reads!"); std::exit(1); } if (pairedEnd and unmatedReads.isSet()) { consoleLog->error("You cannot specify both paired-end and unmated " "reads in the input!"); std::exit(1); } if (!pairedEnd and !unmatedReads.isSet()) { consoleLog->error("You must specify input; either both paired-end " "or unmated reads!"); std::exit(1); } std::string indexPrefix(index.getValue()); if (indexPrefix.back() != '/') { indexPrefix += "/"; } if (!rapmap::fs::DirExists(indexPrefix.c_str())) { consoleLog->error("It looks like the index you provided [{}] " "doesn't exist", indexPrefix); std::exit(1); } IndexHeader h; std::ifstream indexStream(indexPrefix + "header.json"); { cereal::JSONInputArchive ar(indexStream); ar(h); } indexStream.close(); if (h.indexType() != IndexType::PSEUDO) { consoleLog->error("The index {} does not appear to be of the " "appropriate type (pseudo)", indexPrefix); std::exit(1); } RapMapIndex rmi; rmi.load(indexPrefix); std::cerr << "\n\n\n\n"; // from: http://stackoverflow.com/questions/366955/obtain-a-stdostream-either-from-stdcout-or-stdofstreamfile // set either a file or cout as the output stream std::streambuf* outBuf; std::ofstream outFile; bool haveOutputFile{false}; if (outname.getValue() == "") { outBuf = std::cout.rdbuf(); } else { outFile.open(outname.getValue()); outBuf = outFile.rdbuf(); haveOutputFile = true; } // Now set the output stream to the buffer, which is // either std::cout, or a file. std::ostream outStream(outBuf); // Must be a power of 2 size_t queueSize{268435456}; spdlog::set_async_mode(queueSize); auto outputSink = std::make_shared<spdlog::sinks::ostream_sink_mt>(outStream); auto outLog = std::make_shared<spdlog::logger>("outLog", outputSink); outLog->set_pattern("%v"); uint32_t nthread = numThreads.getValue(); std::unique_ptr<paired_parser> pairParserPtr{nullptr}; std::unique_ptr<single_parser> singleParserPtr{nullptr}; if (!noout.getValue()) { rapmap::utils::writeSAMHeader(rmi, outLog); } SpinLockT iomutex; { ScopedTimer timer; HitCounters hctrs; consoleLog->info("mapping reads . . . \n\n\n"); if (pairedEnd) { std::vector<std::thread> threads; std::vector<std::string> read1Vec = rapmap::utils::tokenize(read1.getValue(), ','); std::vector<std::string> read2Vec = rapmap::utils::tokenize(read2.getValue(), ','); if (read1Vec.size() != read2Vec.size()) { consoleLog->error("The number of provided files for " "-1 and -2 must be the same!"); std::exit(1); } size_t numFiles = read1Vec.size() + read2Vec.size(); char** pairFileList = new char*[numFiles]; for (size_t i = 0; i < read1Vec.size(); ++i) { pairFileList[2*i] = const_cast<char*>(read1Vec[i].c_str()); pairFileList[2*i+1] = const_cast<char*>(read2Vec[i].c_str()); } size_t maxReadGroup{1000}; // Number of reads in each "job" size_t concurrentFile{2}; // Number of files to read simultaneously pairParserPtr.reset(new paired_parser(4 * nthread, maxReadGroup, concurrentFile, pairFileList, pairFileList+numFiles)); /** Create the threads depending on the collector type **/ if (endCollectorSwitch.getValue()) { EndCollector endCollector(&rmi); for (size_t i = 0; i < nthread; ++i) { threads.emplace_back(processReadsPair<EndCollector, SpinLockT>, pairParserPtr.get(), std::ref(rmi), std::ref(endCollector), &iomutex, outLog, std::ref(hctrs), maxNumHits.getValue(), noout.getValue()); } } else { SkippingCollector skippingCollector(&rmi); for (size_t i = 0; i < nthread; ++i) { threads.emplace_back(processReadsPair<SkippingCollector, SpinLockT>, pairParserPtr.get(), std::ref(rmi), std::ref(skippingCollector), &iomutex, outLog, std::ref(hctrs), maxNumHits.getValue(), noout.getValue()); } } for (auto& t : threads) { t.join(); } delete [] pairFileList; } else { std::vector<std::thread> threads; std::vector<std::string> unmatedReadVec = rapmap::utils::tokenize(unmatedReads.getValue(), ','); size_t maxReadGroup{1000}; // Number of reads in each "job" size_t concurrentFile{1}; stream_manager streams( unmatedReadVec.begin(), unmatedReadVec.end(), concurrentFile); singleParserPtr.reset(new single_parser(4 * nthread, maxReadGroup, concurrentFile, streams)); /** Create the threads depending on the collector type **/ if (endCollectorSwitch.getValue()) { EndCollector endCollector(&rmi); for (size_t i = 0; i < nthread; ++i) { threads.emplace_back(processReadsSingle<EndCollector, SpinLockT>, singleParserPtr.get(), std::ref(rmi), std::ref(endCollector), &iomutex, outLog, std::ref(hctrs), maxNumHits.getValue(), noout.getValue()); } } else { SkippingCollector skippingCollector(&rmi); for (size_t i = 0; i < nthread; ++i) { threads.emplace_back(processReadsSingle<SkippingCollector, SpinLockT>, singleParserPtr.get(), std::ref(rmi), std::ref(skippingCollector), &iomutex, outLog, std::ref(hctrs), maxNumHits.getValue(), noout.getValue()); } } for (auto& t : threads) { t.join(); } } consoleLog->info("Done mapping reads."); consoleLog->info("In total saw {} reads.", hctrs.numReads); consoleLog->info("Final # hits per read = {}", hctrs.totHits / static_cast<float>(hctrs.numReads)); consoleLog->info("Discarded {} reads because they had > {} alignments", hctrs.tooManyHits, maxNumHits.getValue()); consoleLog->info("flushing output"); outLog->flush(); } if (haveOutputFile) { outFile.close(); } return 0; } catch (TCLAP::ArgException& e) { consoleLog->error("Exception [{}] when parsing argument {}", e.error(), e.argId()); return 1; } }
/* * evaluate one initialiser * * if dump is TRUE, dump literal immediately * save character string in litq to dump later * this is used for structures and arrays of pointers to char, so that the * struct or array is built immediately and the char strings are dumped later */ void init(int size, int ident, int *dim, int more, int dump, int is_struct) { int32_t value; int sz; /* number of chars in queue */ /* * djm 14/3/99 We have to rewrite this bit (ugh!) so that we store * our literal in a temporary queue, then if needed, we then dump * it out.. */ if ((sz = qstr(&value)) != -1 ) { sz++; #if 0 if (ident == VARIABLE || (size != 1 && more != CCHAR)) error(E_ASSIGN); #endif #ifdef INIT_TEST outstr("ident="); outdec(ident); outstr("size="); outdec(size); outstr("more="); outdec(more); outstr("dim="); outdec(*dim); outstr("sz="); outdec(sz); nl(); #endif if (ident == ARRAY && more == 0) { /* * Dump the literals where they are, padding out as appropriate */ if (*dim != -1 && sz > *dim) { /* * Ooops, initialised to long a string! */ warning(W_INIT2LONG); sz = *dim; gltptr = sz; *(glbq + sz - 1) = '\0'; /* Terminate string */ } dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab, glbq); *dim -= sz; gltptr = 0; dumpzero(size, *dim); return; } else { /* * Store the literals in the queue! */ storeq(sz, glbq, &value); gltptr = 0; defword(); printlabel(litlab); outbyte('+'); outdec(value); nl(); --*dim; return; } } /* * djm, catch label names in structures (for (*name)() initialisation */ else { char sname[NAMEMAX + 1]; SYMBOL *ptr; if (symname(sname) && strcmp(sname,"sizeof") ) { /* We have got something.. */ if ((ptr = findglb(sname))) { /* Actually found sommat..very good! */ if (ident == POINTER || (ident == ARRAY && more)) { defword(); outname(ptr->name, dopref(ptr)); nl(); --*dim; } else if (ptr->type == ENUM) { value = ptr->size; goto constdecl; } else { error(E_DDECL); } } else error(E_UNSYMB, sname); } else if (rcmatch('}')) { #if 0 dumpzero(size,*dim); #endif } else if (constexpr(&value, 1)) { constdecl: if (ident == POINTER) { /* 24/1/03 dom - We want to be able to assign values to pointers or they're a bit useless.. */ #if 0 /* the only constant which can be assigned to a pointer is 0 */ if (value != 0) warning(W_ASSPTR); #endif size = 2; dump = YES; } if (dump) { /* struct member or array of pointer to char */ if (size == 4) { /* there appears to be a bug in z80asm regarding defl */ defbyte(); outdec((value % 65536UL) % 256); outbyte(','); outdec((value % 65536UL) / 256); outbyte(','); outdec((value / 65536UL) % 256); outbyte(','); outdec((value / 65536UL) / 256); } else { if (size == 1) defbyte(); else defword(); outdec(value); } nl(); /* Dump out a train of zeros as appropriate */ if (ident == ARRAY && more == 0) { dumpzero(size,(*dim)-1); } } else stowlit(value, size); --*dim; } } }
/* * initialise global object */ int initials(char *sname, int type, int ident, int dim, int more, TAG_SYMBOL * tag, char zfar) { int size, desize = 0; int olddim = dim; if (cmatch('=')) { /* initialiser present */ defstatic = 1; /* So no 2nd redefine djm */ gltptr = 0; glblab = getlabel(); if (dim == 0) dim = -1; switch (type) { case CCHAR: size = 1; break; case LONG: size = 4; break; case CINT: default: size = 2; } output_section("data_compiler"); // output_section("text"); prefix(); outname(sname, YES); col(); nl(); if (cmatch('{')) { /* aggregate initialiser */ if ((ident == POINTER || ident == VARIABLE) && type == STRUCT) { /* aggregate is structure or pointer to structure */ dim = 0; olddim = 1; if (ident == POINTER) point(); str_init(tag); } else { /* aggregate is not struct or struct pointer */ agg_init(size, type, ident, &dim, more, tag); } needchar('}'); } else { /* single initialiser */ init(size, ident, &dim, more, 0, 0); } /* dump literal queue and fill tail of array with zeros */ if ((ident == ARRAY && more == CCHAR) || type == STRUCT) { if (type == STRUCT) { dumpzero(tag->size, dim); desize = dim < 0 ? abs(dim+1)*tag->size : olddim * tag->size; } else { /* Handles unsized arrays of chars */ dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } dumplits(0, YES, gltptr, glblab, glbq); } else { if (!(ident == POINTER && type == CCHAR)) { dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab,glbq); if ( type != CCHAR ) /* Already dumped by init? */ desize = dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } } output_section("code_compiler"); // output_section("code"); } else { char *dosign, *typ; dosign = ""; if (ident == ARRAY && (dim == 0)) { typ = ExpandType(more, &dosign, (tag - tagtab)); warning(W_NULLARRAY, dosign, typ); } /* no initialiser present, let loader insert zero */ if (ident == POINTER) type = (zfar ? CPTR : CINT); cscale(type, tag, &dim); desize = dim; } return (desize); }