void testInputFiles(int numFilenames, char* filename[]) { inputFilenames = (const char**)malloc((numFilenames+1)*sizeof(char*)); int i; char achar; for (i = 0; i < numFilenames; i++) { if (!isRecognizedSource(filename[i])) { USR_FATAL(astr("file '", filename[i], "' does not have a recognized suffix")); } // WE SHOULDN"T TRY TO OPEN .h files, just .c and .chpl and .o if (!isCHeader(filename[i])) { FILE* testfile = openInputFile(filename[i]); if (fscanf(testfile, "%c", &achar) != 1) { USR_FATAL(astr("source file '", filename[i], "' is either empty or a directory")); } closeInputFile(testfile); } inputFilenames[i] = astr(filename[i]); } inputFilenames[i] = NULL; if (!foundChplSource) USR_FATAL("Command line contains no .chpl source files"); }
const char* createDebuggerFile(const char* debugger, int argc, char* argv[]) { const char* dbgfilename = genIntermediateFilename(astr(debugger, ".commands")); FILE* dbgfile = openfile(dbgfilename); int i; if (strcmp(debugger, "gdb") == 0) { fprintf(dbgfile, "set args"); } else if (strcmp(debugger, "lldb") == 0) { fprintf(dbgfile, "settings set -- target.run-args"); } else { INT_FATAL(astr("createDebuggerFile doesn't know how to handle the given " "debugger: '", debugger, "'")); } for (i=1; i<argc; i++) { if (strcmp(argv[i], astr("--", debugger)) != 0) { fprintf(dbgfile, " %s", argv[i]); } } fprintf(dbgfile, "\n"); closefile(dbgfile); mysystem(astr("cat ", CHPL_HOME, "/compiler/etc/", debugger, ".commands >> ", dbgfilename), astr("appending ", debugger, " commands"), false); return dbgfilename; }
const char* makeTempDir(const char* dirPrefix) { const char* tmpdirprefix = astr(getTempDir(), "/", dirPrefix); const char* tmpdirsuffix = ".deleteme"; pid_t mypid = getpid(); #ifdef DEBUGTMPDIR mypid = 0; #endif char mypidstr[MAX_CHARS_PER_PID]; snprintf(mypidstr, MAX_CHARS_PER_PID, "-%d", (int)mypid); struct passwd* passwdinfo = getpwuid(geteuid()); const char* userid; if (passwdinfo == NULL) { userid = "anon"; } else { userid = passwdinfo->pw_name; } char* myuserid = strdup(userid); removeSpacesBackslashesFromString(myuserid); const char* tmpDir = astr(tmpdirprefix, myuserid, mypidstr, tmpdirsuffix); ensureDirExists(tmpDir, "making temporary directory"); free(myuserid); myuserid = NULL; return tmpDir; }
// NOTE: We are leaking memory here by dropping astr() results on the ground. static void recordCodeGenStrings(int argc, char* argv[]) { compileCommand = astr("chpl "); // WARNING: This does not handle arbitrary sequences of escaped characters // in string arguments for (int i = 1; i < argc; i++) { char *arg = argv[i]; // Handle " and \" in strings while (char *dq = strchr(arg, '"')) { char targ[strlen(argv[i])+4]; memcpy(targ, arg, dq-arg); if ((dq==argv[i]) || ((dq!=argv[i]) && (*(dq-1)!='\\'))) { targ[dq-arg] = '\\'; targ[dq-arg+1] = '"'; targ[dq-arg+2] = '\0'; } else { targ[dq-arg] = '"'; targ[dq-arg+1] = '\0'; } arg = dq+1; compileCommand = astr(compileCommand, targ); if (arg == NULL) break; } if (arg) compileCommand = astr(compileCommand, arg, " "); } get_version(compileVersion); }
static void create_arg_bundle_class(FnSymbol* fn, CallExpr* fcall, ModuleSymbol* mod, BundleArgsFnData &baData) { INT_ASSERT(!baData.ctype); SET_LINENO(fn); // Here, 'fcall' is the first of fn's callees and so it acts as a // representative of all the other callees, if any. // As of this writing, this should be OK because the callees are // obtained by duplicating the original call, which resulted in // outlining a block into 'fn' and so is unique. // To eliminate 'fcall' in create_arg_bundle_class(), we need // to rely on fn's formal types instead of fcall's actual types. // create a new class to capture refs to locals AggregateType* ctype = new AggregateType(AGGREGATE_CLASS); TypeSymbol* new_c = new TypeSymbol(astr("_class_locals", fn->name), ctype); new_c->addFlag(FLAG_NO_OBJECT); new_c->addFlag(FLAG_NO_WIDE_CLASS); // add the function args as fields in the class int i = 0; // Fields are numbered for uniqueness. for_actuals(arg, fcall) { SymExpr *s = toSymExpr(arg); Symbol *var = s->var; // arg or var if (var->type->symbol->hasFlag(FLAG_REF) || isClass(var->type)) // Only a variable that is passed by reference out of its current scope // is concurrently accessed -- which means that it has to be passed by // reference. var->addFlag(FLAG_CONCURRENTLY_ACCESSED); VarSymbol* field = new VarSymbol(astr("_", istr(i), "_", var->name), var->type); ctype->fields.insertAtTail(new DefExpr(field)); i++; }
void openCFile(fileinfo* fi, const char* name, const char* ext) { if (ext) fi->filename = astr(name, ".", ext); else fi->filename = astr(name); fi->pathname = genIntermediateFilename(fi->filename); openfile(fi, "w"); }
void appendCFile(fileinfo* fi, const char* name, const char* ext) { if (ext) fi->filename = astr(name, ".", ext); else fi->filename = astr(name); fi->pathname = genIntermediateFilename(fi->filename); fi->fptr = fopen(fi->pathname, "a+"); }
const char* getDirectory(const char* filename) { const char* filenamebase = strrchr(filename, '/'); if (filenamebase == NULL) { return astr("."); } else { char dir[FILENAME_MAX]; const int len = filenamebase - filename; strncpy(dir, filename, len); dir[len] = '\0'; return astr(dir); } }
static void setupEnvVar(std::istringstream& iss, const char** var, const char* varname) { std::string line; std::string value; std::getline(iss, line); if (!iss.good() || line.find(varname) == std::string::npos) { INT_FATAL(astr("Parsing ", varname)); } value = line.substr(line.find('=')+1, std::string::npos); *var = astr(value.c_str()); // astr call is to canonicalize parseCmdLineConfig(varname, astr("\"", *var, "\"")); }
void addSourceFiles(int numNewFilenames, const char* filename[]) { static int numInputFiles = 0; int cursor = numInputFiles; char achar; numInputFiles += numNewFilenames; inputFilenames = (const char**)realloc(inputFilenames, (numInputFiles+1)*sizeof(char*)); for (int i = 0; i < numNewFilenames; i++) { if (!isRecognizedSource(filename[i])) { USR_FATAL(astr("file '", filename[i], "' does not have a recognized suffix")); } // WE SHOULDN"T TRY TO OPEN .h files, just .c and .chpl and .o if (!isCHeader(filename[i])) { FILE* testfile = openInputFile(filename[i]); if (fscanf(testfile, "%c", &achar) != 1) { USR_FATAL(astr("source file '", filename[i], "' is either empty or a directory")); } closeInputFile(testfile); } // // Don't add the same file twice -- it's unnecessary and can mess // up things like unprotected headers // bool duplicate = false; const char* newFilename = astr(filename[i]); for (int j = 0; j < cursor; j++) { if (inputFilenames[j] == newFilename) { // legal due to astr() duplicate = true; break; } } if (duplicate) { numInputFiles--; } else { inputFilenames[cursor++] = newFilename; } } inputFilenames[cursor] = NULL; if (!foundChplSource && fUseIPE == false) USR_FATAL("Command line contains no .chpl source files"); }
// // Do a breadth first search starting from functions generated for local blocks // for all function calls in each level of the search, if they directly cause // communication, add a local temp that isn't wide. If it is a resolved call, // meaning that it isn't a primitive or external function, clone it and add it // to the queue of functions to handle at the next iteration of the BFS. // static void handleLocalBlocks() { Map<FnSymbol*,FnSymbol*> cache; // cache of localized functions Vec<BlockStmt*> queue; // queue of blocks to localize forv_Vec(BlockStmt, block, gBlockStmts) { if (block->parentSymbol) { // NOAKES 2014/11/25 Transitional. Avoid calling blockInfoGet() if (block->isLoopStmt() == true) { } else if (block->blockInfoGet()) { if (block->blockInfoGet()->isPrimitive(PRIM_BLOCK_LOCAL)) { queue.add(block); } } } } forv_Vec(BlockStmt, block, queue) { std::vector<CallExpr*> calls; collectCallExprs(block, calls); for_vector(CallExpr, call, calls) { localizeCall(call); if (FnSymbol* fn = call->isResolved()) { SET_LINENO(fn); if (FnSymbol* alreadyLocal = cache.get(fn)) { call->baseExpr->replace(new SymExpr(alreadyLocal)); } else { if (!fn->hasFlag(FLAG_EXTERN)) { FnSymbol* local = fn->copy(); local->addFlag(FLAG_LOCAL_FN); local->name = astr("_local_", fn->name); local->cname = astr("_local_", fn->cname); fn->defPoint->insertBefore(new DefExpr(local)); call->baseExpr->replace(new SymExpr(local)); queue.add(local->body); cache.put(fn, local); cache.put(local, local); // to handle recursion if (local->retType->symbol->hasFlag(FLAG_WIDE_REF)) { CallExpr* ret = toCallExpr(local->body->body.tail); INT_ASSERT(ret && ret->isPrimitive(PRIM_RETURN)); // Capture the return expression in a local temp. insertLocalTemp(ret->get(1)); local->retType = ret->get(1)->typeInfo(); } } } } }
static void buildWideClass(Type* type) { SET_LINENO(type->symbol); AggregateType* wide = new AggregateType(AGGREGATE_RECORD); TypeSymbol* wts = new TypeSymbol(astr("__wide_", type->symbol->cname), wide); wts->addFlag(FLAG_WIDE_CLASS); theProgram->block->insertAtTail(new DefExpr(wts)); wide->fields.insertAtTail(new DefExpr(new VarSymbol("locale", dtLocaleID))); wide->fields.insertAtTail(new DefExpr(new VarSymbol("addr", type))); // // Strings need an extra field in their wide class to hold their length // if (type == dtString) { wide->fields.insertAtTail(new DefExpr(new VarSymbol("size", dtInt[INT_SIZE_DEFAULT]))); if (wideStringType) { INT_FATAL("Created two wide string types"); } wideStringType = wide; } // // set reference type of wide class to reference type of class since // it will be widened // if (type->refType) wide->refType = type->refType; wideClassMap.put(type, wide); }
const char* genIntermediateFilename(const char* filename) { const char* slash = "/"; ensureTmpDirExists(); return astr(intDirName, slash, filename); }
static void runCompilerInLLDB(int argc, char* argv[]) { const char* lldbCommandFilename = createDebuggerFile("lldb", argc, argv); const char* command = astr("lldb -s ", lldbCommandFilename, " ", argv[0]); int status = mysystem(command, "running lldb", false); clean_exit(status); }
void deleteTmpDir() { static int inDeleteTmpDir = 0; // break infinite recursion if (inDeleteTmpDir) { return; } inDeleteTmpDir = 1; #ifndef DEBUGTMPDIR if (tmpdirname != NULL) { if (strlen(tmpdirname) < 1 || strchr(tmpdirname, '*') != NULL || strcmp(tmpdirname, "//") == 0) { INT_FATAL("tmp directory name looks fishy"); } const char* rmdircommand = "rm -r "; const char* command = astr(rmdircommand, tmpdirname); mysystem(command, "removing temporary directory"); tmpdirname = NULL; } #endif inDeleteTmpDir = 0; }
bool send_init_oft2(file_transfer *ft, char* file) { aimString astr(file); unsigned short len = max(0x100, 0xc0 + astr.getTermSize()); oft2 *oft = (oft2*)alloca(len); memset(oft, 0, len); memcpy(oft->protocol_version, "OFT2", 4); oft->length = _htons(len); oft->type = 0x0101; oft->total_files = _htons(ft->pfts.totalFiles); oft->num_files_left = _htons(ft->pfts.totalFiles - ft->pfts.currentFileNumber); oft->total_parts = _htons(1); oft->parts_left = _htons(1); oft->total_size = _htonl(ft->pfts.totalBytes); oft->size = _htonl(ft->pfts.currentFileSize); oft->mod_time = _htonl(ft->pfts.currentFileTime); oft->checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile)); oft->recv_RFchecksum = 0x0000FFFF; oft->RFchecksum = 0x0000FFFF; oft->recv_checksum = 0x0000FFFF; memcpy(oft->idstring, "Cool FileXfer", 13); oft->flags = 0x20; oft->list_name_offset = 0x1c; oft->list_size_offset = 0x11; oft->encoding = _htons(astr.isUnicode() ? 2 : 0); memcpy(oft->filename, astr.getBuf(), astr.getTermSize()); if (!ft->requester || ft->pfts.currentFileNumber) memcpy(oft->icbm_cookie, ft->icbm_cookie, 8); return Netlib_Send(ft->hConn, (char*)oft, len, 0) > 0; }
static void runCompilerInGDB(int argc, char* argv[]) { const char* gdbCommandFilename = createGDBFile(argc, argv); const char* command = astr("gdb -q ", argv[0]," -x ", gdbCommandFilename); int status = mysystem(command, "running gdb", 0); clean_exit(status); }
const char* istr(int i) { char s[64]; if (sprintf(s, "%d", i) > 63) INT_FATAL("istr buffer overflow"); return astr(s); }
void closefile(FILE* thefile) { if (fclose(thefile) != 0) { const char* errorstr = "closing file: "; const char* errormsg = astr(errorstr, strerror(errno)); USR_FATAL(errormsg); } }
void AstDumpToHtml::init() { if (!(sIndexFP = fopen(astr(log_dir, "index.html"), "w"))) { USR_FATAL("cannot open html index file \"%s\" for writing", astr(log_dir, "index.html")); } fprintf(sIndexFP, "<HTML>\n"); fprintf(sIndexFP, "<HEAD>\n"); fprintf(sIndexFP, "<TITLE> Compilation Dump </TITLE>\n"); fprintf(sIndexFP, "<SCRIPT SRC=\"http://chapel.cray.com/developer/mktree.js\" LANGUAGE=\"JavaScript\"></SCRIPT>"); fprintf(sIndexFP, "<LINK REL=\"stylesheet\" HREF=\"http://chapel.cray.com/developer/mktree.css\">"); fprintf(sIndexFP, "</HEAD>\n"); fprintf(sIndexFP, "<div style=\"text-align: center;\"><big><big><span style=\"font-weight: bold;\">"); fprintf(sIndexFP, "Compilation Dump<br><br></span></big></big>\n"); fprintf(sIndexFP, "<div style=\"text-align: left;\">\n\n"); fprintf(sIndexFP, "<TABLE CELLPADDING=\"0\" CELLSPACING=\"0\">"); }
Flag pragma2flag(const char* str) { Flag lookup = (Flag)flagMap.get(astr(str)); if (lookup == FLAG_UNKNOWN || !flagPragma[lookup]) return FLAG_UNKNOWN; else return lookup; }
// wstring → string inline std::string to_astr(const std::wstring& wstr) { setlocale(LC_ALL, "japanese"); std::string astr(wcstombs(0, wstr.c_str(), 0) + 1, 0); wcstombs(&astr[0], wstr.c_str(), astr.size()); return astr; }
void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, bool skip_compile_link) { fileinfo makefile; openCFile(&makefile, "Makefile"); const char* tmpDirName = intDirName; const char* strippedExeFilename = stripdirectories(executableFilename); const char* exeExt = ""; const char* tmpbin = ""; fprintf(makefile.fptr, "CHPL_MAKE_HOME = %s\n\n", CHPL_HOME); fprintf(makefile.fptr, "TMPDIRNAME = %s\n", tmpDirName); // LLVM builds just use the makefile for the launcher and // so want to skip the actual program generation. if( skip_compile_link ) { fprintf(makefile.fptr, "SKIP_COMPILE_LINK = skip\n"); } if (fLibraryCompile) { if (fLinkStyle==LS_DYNAMIC) exeExt = ".so"; else exeExt = ".a"; } fprintf(makefile.fptr, "BINNAME = %s%s\n\n", executableFilename, exeExt); // BLC: This munging is done so that cp won't complain if the source // and destination are the same file (e.g., a.out and ./a.out) tmpbin = astr(tmpDirName, "/", strippedExeFilename, ".tmp", exeExt); if( tmpbinname ) *tmpbinname = tmpbin; fprintf(makefile.fptr, "TMPBINNAME = %s\n", tmpbin); // BLC: We generate a TMPBINNAME which is the name that will be used // by the C compiler in creating the executable, and is in the // --savec directory (a /tmp directory by default). We then copy it // over to BINNAME -- the name given by the user, or a.out by // default -- after linking is done. As it turns out, this saves a // factor of 5 or so in time in running the test system, as opposed // to specifying BINNAME on the C compiler command line. fprintf(makefile.fptr, "COMP_GEN_CFLAGS ="); if (ccwarnings) { fprintf(makefile.fptr, " $(WARN_GEN_CFLAGS)"); } if (debugCCode) { fprintf(makefile.fptr, " $(DEBUG_CFLAGS)"); } if (optimizeCCode) { fprintf(makefile.fptr, " $(OPT_CFLAGS)"); } if (specializeCCode) { fprintf(makefile.fptr, " $(SPECIALIZE_CFLAGS)"); } if (fieeefloat) { fprintf(makefile.fptr, " $(IEEE_FLOAT_GEN_CFLAGS)"); } else { fprintf(makefile.fptr, " $(NO_IEEE_FLOAT_GEN_CFLAGS)"); } if (fLibraryCompile && (fLinkStyle==LS_DYNAMIC)) fprintf(makefile.fptr, " $(SHARED_LIB_CFLAGS)"); forv_Vec(const char*, dirName, incDirs) { fprintf(makefile.fptr, " -I%s", dirName); }
const char* cleanFilename(BaseAST* ast) { const char* astFname = ast->fname(); if (astFname) return cleanFilename(astFname); else if (yyfilename) return cleanFilename(yyfilename); else return astr("<unknown>"); }
fileinfo* openTmpFile(const char* tmpfilename, const char* mode) { fileinfo* newfile = (fileinfo*)malloc(sizeof(fileinfo)); newfile->filename = astr(tmpfilename); newfile->pathname = genIntermediateFilename(tmpfilename); openfile(newfile, mode); return newfile; }
const char* cleanFilename(const char* name) { static int chplHomeLen = strlen(CHPL_HOME); if (!strncmp(name, CHPL_HOME, chplHomeLen)) { return astr("$CHPL_HOME", name + chplHomeLen); } else { return name; } }
static const char* subChar(Symbol* sym, const char* ch, const char* x) { char* tmp = (char*)malloc(ch-sym->cname+1); strncpy(tmp, sym->cname, ch-sym->cname); tmp[ch-sym->cname] = '\0'; sym->cname = astr(tmp, x, ch+1); free(tmp); return sym->cname; }
ModuleSymbol* IpeModuleRoot::createDeclaration() { ModuleSymbol* retval = new ModuleSymbol("ChapelRoot", MOD_INTERNAL, new BlockStmt()); retval->filename = astr("<ChapelRoot>"); return retval; }
IpeModule* IpeModule::moduleByName(const char* name) const { const char* identifier = astr(name); LcnSymbol* varSym = mEnv->findVariable(identifier); INT_ASSERT(varSym); INT_ASSERT(varSym->type == gIpeTypeModule); return (IpeModule*) mEnv->fetchPtr(varSym); }
void ResolutionCandidate::resolveTypeConstructor(CallInfo& info) { SET_LINENO(fn); // Ignore tuple constructors; they were generated // with their type constructors. if (fn->hasFlag(FLAG_PARTIAL_TUPLE) == false) { CallExpr* typeConstructorCall = new CallExpr(astr("_type", fn->name)); for_formals(formal, fn) { if (formal->hasFlag(FLAG_IS_MEME) == false) { if (fn->_this->type->symbol->hasFlag(FLAG_TUPLE)) { if (formal->instantiatedFrom != NULL) { typeConstructorCall->insertAtTail(formal->type->symbol); } else if (formal->hasFlag(FLAG_INSTANTIATED_PARAM)) { typeConstructorCall->insertAtTail(paramMap.get(formal)); } } else { if (strcmp(formal->name, "outer") == 0 || formal->type == dtMethodToken) { typeConstructorCall->insertAtTail(formal); } else if (formal->instantiatedFrom != NULL) { SymExpr* se = new SymExpr(formal->type->symbol); NamedExpr* ne = new NamedExpr(formal->name, se); typeConstructorCall->insertAtTail(ne); } else if (formal->hasFlag(FLAG_INSTANTIATED_PARAM)) { SymExpr* se = new SymExpr(paramMap.get(formal)); NamedExpr* ne = new NamedExpr(formal->name, se); typeConstructorCall->insertAtTail(ne); } } } } info.call->insertBefore(typeConstructorCall); // If instead we call resolveCallAndCallee(typeConstructorCall) // then the line number reported in an error would change // e.g.: domains/deitz/test_generic_class_of_sparse_domain // or: classes/diten/multipledestructor resolveCall(typeConstructorCall); INT_ASSERT(typeConstructorCall->isResolved()); resolveFunction(typeConstructorCall->resolvedFunction()); fn->_this->type = typeConstructorCall->resolvedFunction()->retType; typeConstructorCall->remove(); }