diff --git a/compiler/AST/AstDump.cpp b/compiler/AST/AstDump.cpp index e859977eac7c..5abd83d51a06 100644 --- a/compiler/AST/AstDump.cpp +++ b/compiler/AST/AstDump.cpp @@ -114,7 +114,7 @@ bool AstDump::open(const ModuleSymbol* module, const char* passName, int passNum snprintf(numBuf, 4, "%02d", passNum); mName = astr(module->name, "_", numBuf, passName, ".ast"); - mPath = astr(log_dir, mName); + mPath = astr(log_dir.c_str(), mName); mFP = fopen(mPath, "w"); mIndent = 0; mNeedSpace = false; diff --git a/compiler/AST/AstDumpToHtml.cpp b/compiler/AST/AstDumpToHtml.cpp index e1773bf55e46..101ae9a7568e 100644 --- a/compiler/AST/AstDumpToHtml.cpp +++ b/compiler/AST/AstDumpToHtml.cpp @@ -57,8 +57,9 @@ AstDumpToHtml::~AstDumpToHtml() { } 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")); + if (!(sIndexFP = fopen(astr(log_dir.c_str(), "index.html"), "w"))) { + USR_FATAL("cannot open html index file \"%s\" for writing", + astr(log_dir.c_str(), "index.html")); } fprintf(sIndexFP, "\n"); @@ -118,7 +119,7 @@ void AstDumpToHtml::view(const char* passName) { bool AstDumpToHtml::open(ModuleSymbol* module, const char* passName) { const char* name = html_file_name(sPassIndex, module->name); - const char* path = astr(log_dir, name); + const char* path = astr(log_dir.c_str(), name); mFP = fopen(path, "w"); diff --git a/compiler/codegen/cg-symbol.cpp b/compiler/codegen/cg-symbol.cpp index a9f31ded9b87..e1c44d35ebe1 100644 --- a/compiler/codegen/cg-symbol.cpp +++ b/compiler/codegen/cg-symbol.cpp @@ -155,7 +155,7 @@ void addNameToPrintLlvmIrRequestedNames(const char* name) { llvmPrintIrRequestedNames.emplace(astr(name), false); } -static void addCNameToPrintLlvmIr(const char* name) { +static void addCNameToPrintLlvmIr(std::string_view name) { llvmPrintIrCNames.insert(astr(name)); } @@ -312,9 +312,9 @@ void preparePrintLlvmIrForCodegen() { // This is so that handlePrintAsm can access them later from the makeBinary // phase, when we don't have a way to determine name->cname correspondence. if (fDriverCompilationPhase) { - saveDriverTmpMultiple(cnamesToPrintFilename, - std::vector(llvmPrintIrCNames.begin(), - llvmPrintIrCNames.end())); + saveDriverTmpMultiple(cnamesToPrintFilename, std::vector( + llvmPrintIrCNames.begin(), + llvmPrintIrCNames.end())); } } @@ -661,7 +661,7 @@ GenRet VarSymbol::codegenVarSymbol(bool lhsInSetReference) { // Print string contents in a comment if developer mode // and savec is set. if (developer && - 0 != strcmp(saveCDir, "") && + !saveCDir.empty() && immediate && ret.chplType == dtString && immediate->const_kind == CONST_KIND_STRING) { @@ -2769,7 +2769,7 @@ void FnSymbol::codegenDef() { info->cLocalDecls.clear(); if( outfile ) { - if (strcmp(saveCDir, "")) { + if (saveCDir.empty()) { if (const char* rawname = fname()) { zlineToFileIfNeeded(this, outfile); const char* name = strrchr(rawname, '/'); diff --git a/compiler/codegen/codegen.cpp b/compiler/codegen/codegen.cpp index 7ac12522db60..77a6b8f5b8f9 100644 --- a/compiler/codegen/codegen.cpp +++ b/compiler/codegen/codegen.cpp @@ -901,9 +901,9 @@ static void genFilenameTable() { std::string & path = (*it); std::string genPath; - if(!strncmp(CHPL_HOME, path.c_str(), strlen(CHPL_HOME))) { + if(!strncmp(CHPL_HOME.c_str(), path.c_str(), CHPL_HOME.length())) { genPath = "$CHPL_HOME"; - genPath += (path.c_str()+strlen(CHPL_HOME)); + genPath += (path.c_str()+CHPL_HOME.length()); } else { genPath = path; } @@ -1247,7 +1247,7 @@ static void genConfigGlobalsAndAbout() { // if we are running as compiler-driver, retrieve compile command saved to tmp if (!fDriverDoMonolithic) { - restoreDriverTmp(compileCommandFilename, [](const char* restoredCommand) { + restoreDriverTmp(compileCommandFilename, [](std::string_view restoredCommand) { compileCommand = astr(restoredCommand); }); } @@ -1255,14 +1255,14 @@ static void genConfigGlobalsAndAbout() { genGlobalString("chpl_compileCommand", compileCommand); genGlobalString("chpl_compileVersion", compileVersion); genGlobalString("chpl_compileDirectory", getCwd()); - if (strcmp(saveCDir, "") != 0) { - char *actualPath = realpath(saveCDir, NULL); + if (!saveCDir.empty()) { + char *actualPath = realpath(saveCDir.c_str(), NULL); genGlobalString("chpl_saveCDir", actualPath); } else { genGlobalString("chpl_saveCDir", ""); } - genGlobalString("CHPL_HOME", CHPL_HOME); + genGlobalString("CHPL_HOME", CHPL_HOME.c_str()); genGlobalInt("CHPL_STACK_CHECKS", !fNoStackChecks, false); genGlobalInt("CHPL_CACHE_REMOTE", fCacheRemote, false); @@ -1304,7 +1304,7 @@ static void genConfigGlobalsAndAbout() { codegenCallPrintf(astr("Compilation command: ", compileCommand, "\\n")); codegenCallPrintf(astr("Chapel compiler version: ", compileVersion, "\\n")); codegenCallPrintf("Chapel environment:\\n"); - codegenCallPrintf(astr(" CHPL_HOME: ", CHPL_HOME, "\\n")); + codegenCallPrintf(astr(" CHPL_HOME: ", CHPL_HOME.c_str(), "\\n")); for (std::map::iterator env=envMap.begin(); env!=envMap.end(); ++env) { if (env->first != "CHPL_HOME") { codegenCallPrintf(astr(" ", env->first.c_str(), ": ", env->second, "\\n")); @@ -2260,43 +2260,34 @@ codegen_config() { } } -static const char* generateFileName(ChainHashMap& filenames, const char* name, const char* currentModuleName){ +static const char* generateFileName(ChainHashMap& filenames, const char* name, const char* currentModuleName){ // Macs are case-insensitive when it comes to files, so // the following bit of code creates a unique filename // with case-insensitivity taken into account // create the lowercase filename - char lowerFilename[FILENAME_MAX]; - snprintf(lowerFilename, sizeof(lowerFilename), "%s", currentModuleName); - for (unsigned int i=0; i= sizeof(filename)) { - USR_FATAL("module name '%s' is too long to be the basis for a file name", - currentModuleName); - } + filename = lowerFilename + std::to_string(version); } - filenames.put(filename, 1); + filenames.put(astr(filename), 1); // build the real filename using that version number -- preserves // case by default by going back to currentModule->name rather // than using the lowercase filename if (version == 1) { - snprintf(filename, sizeof(filename), "%s", currentModuleName); + filename = currentModuleName; } else { - snprintf(filename, sizeof(filename), "%s%d", currentModuleName, version); + filename = currentModuleName + std::to_string(version); } name = astr(filename); @@ -2411,7 +2402,7 @@ static const char* getMainModuleFilename() { const char* filename = nullptr; if (fDriverMakeBinaryPhase) { // Retrieve saved main module filename - restoreDriverTmp(mainModTmpFilename, [&filename](const char* mainModName) { + restoreDriverTmp(mainModTmpFilename, [&filename](std::string_view mainModName) { filename = astr(mainModName); }); } else { @@ -2455,82 +2446,65 @@ void setupDefaultFilenames() { // and just the main module name in normal compilation. if (fLibraryCompile) { // If the header name isn't set either, don't use the prefix version - if (libmodeHeadername[0] == '\0') { - // copy from that slash onwards into the libmodeHeadername, - // saving space for a `\0` terminator - if (strlen(filename) >= sizeof(libmodeHeadername)) { - INT_FATAL("input filename exceeds header filename buffer size"); - } - strncpy(libmodeHeadername, filename, sizeof(libmodeHeadername)-1); - libmodeHeadername[sizeof(libmodeHeadername)-1] = '\0'; + if (libmodeHeadername.empty()) { + // copy from that slash onwards into the libmodeHeadername + libmodeHeadername = filename; // remove the filename extension from the library header name. - char* lastDot = strrchr(libmodeHeadername, '.'); - if (lastDot == NULL) { + size_t lastDot = libmodeHeadername.find_last_of('.'); + if (lastDot == std::string::npos) { INT_ASSERT(!fDriverMakeBinaryPhase && "encountered error in makeBinary phase that should only be " "reachable in compilation phase"); INT_FATAL(mainMod, "main module filename is missing its extension: %s\n", - libmodeHeadername); + libmodeHeadername.c_str()); } - *lastDot = '\0'; - } - if (strlen(filename) >= sizeof(executableFilename) - 3) { - INT_FATAL("input filename exceeds executable filename buffer size"); + libmodeHeadername = libmodeHeadername.substr(0, lastDot); } - strncpy(executableFilename, filename, - sizeof(executableFilename)-1); - - if (fLibraryPython && pythonModulename[0] == '\0') { - strncpy(pythonModulename, filename, sizeof(pythonModulename)-1); - pythonModulename[sizeof(pythonModulename)-1] = '\0'; - char* lastDot = strrchr(pythonModulename, '.'); - if (lastDot == NULL) { + executableFilename = filename; + + if (fLibraryPython && pythonModulename.empty()) { + pythonModulename = filename; + size_t lastDot = pythonModulename.find_last_of('.'); + if (lastDot == std::string::npos) { INT_ASSERT(!fDriverMakeBinaryPhase && "encountered error in makeBinary phase that should only be " "reachable in compilation phase"); INT_FATAL(mainMod, "main module filename is missing its extension: %s\n", - pythonModulename); + pythonModulename.c_str()); } - *lastDot = '\0'; + pythonModulename = pythonModulename.substr(0, lastDot); } } else { - // copy from that slash onwards into the executableFilename, - // saving space for a `\0` terminator - if (strlen(filename) >= sizeof(executableFilename)) { - INT_FATAL("input filename exceeds executable filename buffer size"); - } - strncpy(executableFilename, filename, sizeof(executableFilename)-1); - executableFilename[sizeof(executableFilename)-1] = '\0'; + // copy from that slash onwards into the executableFilename + executableFilename = filename; } // remove the filename extension from the executable filename - char* lastDot = strrchr(executableFilename, '.'); - if (lastDot == NULL) { + size_t lastDot = executableFilename.find_last_of('.'); + if (lastDot == std::string::npos) { INT_ASSERT(!fDriverMakeBinaryPhase && "encountered error in makeBinary phase that should only be " "reachable in compilation phase"); INT_FATAL(mainMod, "main module filename is missing its extension: %s\n", - executableFilename); + executableFilename.c_str()); } - *lastDot = '\0'; + executableFilename = executableFilename.substr(0, lastDot); } // If we're in library mode and the executable name was set but the header // name wasn't, use the executable name for the header name as well - if (fLibraryCompile && libmodeHeadername[0] == '\0') { - strncpy(libmodeHeadername, executableFilename, sizeof(libmodeHeadername)-1); - libmodeHeadername[sizeof(libmodeHeadername)-1] = '\0'; + if (fLibraryCompile && libmodeHeadername.empty()) { + libmodeHeadername = executableFilename; } // If we're in library mode and the library name was explicitly set, use that // name for the python module. - if (fLibraryCompile && fLibraryPython && pythonModulename[0] == '\0') { - strncpy(pythonModulename, executableFilename, sizeof(pythonModulename)-1); - pythonModulename[sizeof(pythonModulename)-1] = '\0'; + if (fLibraryCompile && fLibraryPython && pythonModulename.empty()) { + pythonModulename = executableFilename; } // Set the name of the library dir in library mode. @@ -3137,15 +3111,13 @@ static void codegenPartTwo() { std::vector userFileName; if(fIncrementalCompilation) { - ChainHashMap fileNameHashMap; + ChainHashMap fileNameHashMap; forv_Vec(ModuleSymbol, currentModule, allModules) { const char* filename = NULL; filename = generateFileName(fileNameHashMap, filename, currentModule->name); openCFile(&modulefile, filename, "c"); - int modulePathLen = strlen(astr(modulefile.pathname)); - char path[FILENAME_MAX]; - strncpy(path, astr(modulefile.pathname), modulePathLen-2); - path[modulePathLen-2]='\0'; + // cut off .o extension + std::string path(modulefile.pathname, strlen(modulefile.pathname) - 2); userFileName.push_back(astr(path)); closeCFile(&modulefile); } @@ -3208,7 +3180,7 @@ static void codegenPartTwo() { #endif } else { - ChainHashMap fileNameHashMap; + ChainHashMap fileNameHashMap; forv_Vec(ModuleSymbol, currentModule, allModules) { const char* filename = NULL; filename = generateFileName(fileNameHashMap, filename,currentModule->name); diff --git a/compiler/codegen/library.cpp b/compiler/codegen/library.cpp index 71c87a96b493..d2cb3d54cefc 100644 --- a/compiler/codegen/library.cpp +++ b/compiler/codegen/library.cpp @@ -33,7 +33,7 @@ std::map exportedArrayElementType; -char libDir[FILENAME_MAX + 1] = ""; +std::string libDir; std::string pxdName = ""; // TypeSymbol -> (pxdName, pyxName) Will be "" if the cname should be used @@ -144,35 +144,41 @@ static void setupMakeEnvVars(std::string var, const char* value, // Save the value of the environment variable "var" into the CMake file, so it // can be referenced in the other variables for legibility purposes. -static void setupCMakeEnvVars(std::string var, const char* value, +static void setupCMakeEnvVars(const std::string& var, const std::string& value, fileinfo cmakelists) { - fprintf(cmakelists.fptr, "set(%s %s)\n\n", var.c_str(), value); + fprintf(cmakelists.fptr, "set(%s %s)\n\n", var.c_str(), value.c_str()); } static void printMakefileIncludes(fileinfo makefile); static void printMakefileLibraries(fileinfo makefile, std::string name); -void codegen_library_makefile() { - std::string name = ""; - int libLength = strlen("lib"); - bool startsWithLib = strncmp(executableFilename, "lib", libLength) == 0; - if (startsWithLib) { - name += &executableFilename[libLength]; +// Return string, without any "lib" prefix if present +static std::string stripLibPrefix(const std::string& name) { + std::string ret; + + static const std::string libStr = "lib"; + + if (name.find(libStr) != std::string::npos) { + ret = name.substr(libStr.length()); } else { - // libname = executableFilename when executableFilename does not start with - // "lib" - name = executableFilename; + ret = name; } + return ret; +} + +void codegen_library_makefile() { + std::string name = stripLibPrefix(executableFilename); + fileinfo makefile; openLibraryHelperFile(&makefile, "Makefile", name.c_str()); // Save the CHPL_HOME location so it can be used in the other makefile // variables instead of letting them be cluttered with its value - setupMakeEnvVars("CHPL_RUNTIME_LIB", CHPL_RUNTIME_LIB, makefile); - setupMakeEnvVars("CHPL_RUNTIME_INCL", CHPL_RUNTIME_INCL, makefile); - setupMakeEnvVars("CHPL_THIRD_PARTY", CHPL_THIRD_PARTY, makefile); - setupMakeEnvVars("CHPL_HOME", CHPL_HOME, makefile); + setupMakeEnvVars("CHPL_RUNTIME_LIB", CHPL_RUNTIME_LIB.c_str(), makefile); + setupMakeEnvVars("CHPL_RUNTIME_INCL", CHPL_RUNTIME_INCL.c_str(), makefile); + setupMakeEnvVars("CHPL_THIRD_PARTY", CHPL_THIRD_PARTY.c_str(), makefile); + setupMakeEnvVars("CHPL_HOME", CHPL_HOME.c_str(), makefile); printMakefileIncludes(makefile); printMakefileLibraries(makefile, name); @@ -227,7 +233,7 @@ static void printMakefileIncludes(fileinfo makefile) { std::string includes = getCompilelineOption("includes-and-defines"); fprintf(makefile.fptr, "CHPL_CFLAGS = -I%s %s", - libDir, + libDir.c_str(), cflags.c_str()); if (requireIncludes != "") { @@ -253,7 +259,7 @@ static void printMakefileLibraries(fileinfo makefile, std::string name) { std::string requires_ = getRequireLibraries(); fprintf(makefile.fptr, "CHPL_LDFLAGS = -L%s %s", - libDir, + libDir.c_str(), libname.c_str()); // @@ -363,16 +369,7 @@ static void printCMakeListsLibraries(fileinfo cmakelists, std::string name) { } void codegen_library_cmakelists() { - std::string name = ""; - int libLength = strlen("lib"); - bool startsWithLib = strncmp(executableFilename, "lib", libLength) == 0; - if (startsWithLib) { - name += &executableFilename[libLength]; - } else { - // libname = executableFilename when executableFilename does not start with - // "lib" - name = executableFilename; - } + std::string name = stripLibPrefix(executableFilename); fileinfo cmakelists; openLibraryHelperFile(&cmakelists, name.c_str(), "cmake"); @@ -413,29 +410,27 @@ const char* getLibraryExtension() { } void ensureLibDirExists() { - if (libDir[0] == '\0') { + if (libDir.empty()) { // // When compiling Python, the default name of the directory where // generated library files are stored is as same as the Python // module name. // - const char* dir = fLibraryPython ? pythonModulename : "lib"; - INT_ASSERT(strlen(dir) < sizeof(libDir)); - strcpy(libDir, dir); + libDir = fLibraryPython ? pythonModulename : "lib"; } - ensureDirExists(libDir, "ensuring --library-dir directory exists"); + ensureDirExists(libDir.c_str(), "ensuring --library-dir directory exists"); } void -openLibraryHelperFile(fileinfo* fi, const char* name, const char* ext) { +openLibraryHelperFile(fileinfo* fi, const std::string& name, const char* ext) { if (ext) - fi->filename = astr(name, ".", ext); + fi->filename = astr(name.c_str(), ".", ext); else - fi->filename = astr(name); + fi->filename = astr(name.c_str()); ensureLibDirExists(); - fi->pathname = astr(libDir, "/", fi->filename); + fi->pathname = astr(libDir.c_str(), "/", fi->filename); openfile(fi, "w"); } @@ -592,8 +587,8 @@ void codegen_library_fortran(std::vector functions) { } void makeFortranModule(std::vector functions) { - const char* filename = fortranModulename[0] != '\0' ? fortranModulename - : libmodeHeadername; + const char* filename = !fortranModulename.empty() ? fortranModulename.c_str() + : libmodeHeadername.c_str(); int indent = 0; fileinfo fort = { NULL, NULL, NULL }; @@ -640,7 +635,7 @@ static void makePXDFile(std::vector functions) { // Get the permanent runtime definitions fprintf(pxd.fptr, "from chplrt cimport *\n\n"); - fprintf(pxd.fptr, "cdef extern from \"%s.h\":\n", libmodeHeadername); + fprintf(pxd.fptr, "cdef extern from \"%s.h\":\n", libmodeHeadername.c_str()); for_vector(FnSymbol, fn, functions) { if (isUserRoutine(fn)) { @@ -763,14 +758,14 @@ static void makePYXSetupFunctions(std::vector moduleInits) { numLocalesType.c_str()); fprintf(outfile, "\tcdef char** args = ['%s', '-nl', str(numLocales).encode()]\n", - libmodeHeadername); + libmodeHeadername.c_str()); // TODO: is there a way to get the number of indices from args? fprintf(outfile, "\tchpl_library_init(3, args)\n"); } else { // Define `chpl_setup` for single locale Python modules. fprintf(outfile, "def chpl_setup():\n"); - fprintf(outfile, "\tcdef char** args = ['%s']\n", libmodeHeadername); + fprintf(outfile, "\tcdef char** args = ['%s']\n", libmodeHeadername.c_str()); fprintf(outfile, "\tchpl_library_init(1, args)\n"); } @@ -821,14 +816,7 @@ static void makePYFile() { gGenInfo->cfile = py.fptr; - std::string libname = ""; - int libLength = strlen("lib"); - bool startsWithLib = strncmp(executableFilename, "lib", libLength) == 0; - if (startsWithLib) { - libname += &executableFilename[libLength]; - } else { - libname = executableFilename; - } + std::string libname = stripLibPrefix(executableFilename); // Imports fprintf(py.fptr, "from setuptools import setup\n"); @@ -880,11 +868,11 @@ static void makePYFile() { fprintf(py.fptr, "]\n"); // Cythonize me, Captain! - fprintf(py.fptr, "setup(name = '%s library',\n", pythonModulename); + fprintf(py.fptr, "setup(name = '%s library',\n", pythonModulename.c_str()); fprintf(py.fptr, "\text_modules = cythonize(\n"); - fprintf(py.fptr, "\t\tExtension(\"%s\",\n", pythonModulename); + fprintf(py.fptr, "\t\tExtension(\"%s\",\n", pythonModulename.c_str()); fprintf(py.fptr, "\t\t\tinclude_dirs=[numpy.get_include()],\n"); - fprintf(py.fptr, "\t\t\tsources=[\"%s.pyx\"],\n", pythonModulename); + fprintf(py.fptr, "\t\t\tsources=[\"%s.pyx\"],\n", pythonModulename.c_str()); fprintf(py.fptr, "\t\t\tlibraries=[\"%s\"] + chpl_libraries + " "[\"%s\"])))\n", libname.c_str(), libname.c_str()); @@ -898,11 +886,11 @@ static void makePYFile() { static void makePYInitFile() { fileinfo py = { NULL, NULL, NULL }; - char* path = dirHasFile(libDir, "__init__.py"); + char* path = dirHasFile(libDir.c_str(), "__init__.py"); if (path != NULL) { free(path); USR_WARN("Cannot generate %s/__init__.py because it would overwrite " - "existing file", libDir); + "existing file", libDir.c_str()); return; } @@ -929,12 +917,12 @@ static void makePYInitFile() { fprintf(py.fptr, "\n"); fprintf(py.fptr, "import atexit\n"); fprintf(py.fptr, "\n"); - fprintf(py.fptr, "from %s.%s import *\n", libDir, pythonModulename); + fprintf(py.fptr, "from %s.%s import *\n", libDir.c_str(), pythonModulename.c_str()); fprintf(py.fptr, "\n"); fprintf(py.fptr, "# Register cleanup function to be called at " "program exit.\n"); fprintf(py.fptr, "atexit.register(%s.chpl_cleanup)\n", - pythonModulename); + pythonModulename.c_str()); // Restore the previous file used for codegen. gGenInfo->cfile = save_cfile; @@ -1005,14 +993,7 @@ void codegen_make_python_module() { libraries.erase(libraries.length() - 1); } - std::string name = "-l"; - int libLength = strlen("lib"); - bool startsWithLib = strncmp(executableFilename, "lib", libLength) == 0; - if (startsWithLib) { - name += &executableFilename[libLength]; - } else { - name += executableFilename; - } + std::string name = "-l" + stripLibPrefix(executableFilename); std::string cythonPortion = "python3 "; cythonPortion += pythonModulename; diff --git a/compiler/include/driver.h b/compiler/include/driver.h index cc2af3464386..6be018cdea75 100644 --- a/compiler/include/driver.h +++ b/compiler/include/driver.h @@ -103,10 +103,10 @@ bool useDefaultEnv(std::string key, bool isCrayPrgEnv); extern std::map envMap; -extern char CHPL_HOME[FILENAME_MAX+1]; -extern char CHPL_RUNTIME_LIB[FILENAME_MAX+1]; -extern char CHPL_RUNTIME_INCL[FILENAME_MAX+1]; -extern char CHPL_THIRD_PARTY[FILENAME_MAX+1]; +extern std::string CHPL_HOME; +extern std::string CHPL_RUNTIME_LIB; +extern std::string CHPL_RUNTIME_INCL; +extern std::string CHPL_THIRD_PARTY; extern const char* CHPL_HOST_PLATFORM; extern const char* CHPL_HOST_ARCH; @@ -174,7 +174,7 @@ extern bool fParseOnly; extern bool fDriverDoMonolithic; extern bool fDriverCompilationPhase; extern bool fDriverMakeBinaryPhase; -extern char driverTmpDir[FILENAME_MAX]; +extern std::string driverTmpDir; // end compiler driver control flags extern bool fExitLeaks; extern bool fPrintAllCandidates; diff --git a/compiler/include/files.h b/compiler/include/files.h index 61f848c01d07..895ab73d5680 100644 --- a/compiler/include/files.h +++ b/compiler/include/files.h @@ -24,15 +24,16 @@ #include #include #include +#include #include #include #include "vec.h" -extern char executableFilename[FILENAME_MAX+1]; -extern char libmodeHeadername[FILENAME_MAX+1]; -extern char fortranModulename[FILENAME_MAX+1]; -extern char pythonModulename[FILENAME_MAX+1]; -extern char saveCDir[FILENAME_MAX+1]; +extern std::string executableFilename; +extern std::string libmodeHeadername; +extern std::string fortranModulename; +extern std::string pythonModulename; +extern std::string saveCDir; extern std::string ccflags; extern std::string ldflags; extern bool ccwarnings; @@ -97,25 +98,27 @@ void addLibFile(const char* filename, bool fromCmdLine = false); void addIncInfo(const char* incDir, bool fromCmdLine = false); // Save (append) provided string into the given tmp file. +// Input string is assumed to be null-terminated. // For storing information that needs to be saved between driver phases. -void saveDriverTmp(const char* tmpFilePath, const char* stringToSave, +void saveDriverTmp(const char* tmpFilePath, std::string_view stringToSave, bool appendNewline = true); // Like saveDriverTmp, but accepts a vector of strings to save in one go without // repeatedly opening/closing file. Newline separated by default unless // noNewlines is true. void saveDriverTmpMultiple(const char* tmpFilePath, - std::vector stringsToSave, + std::vector stringsToSave, bool noNewlines = false); // Feed strings from the specified tmp file (one per line) into the given // restoring function, which should copy any it needs to keep. +// Restored string will be null-terminated. // For accessing information saved between driver phases with saveDriverTmp. void restoreDriverTmp(const char* tmpFilePath, - std::function restoreSavedString); + std::function restoreSavedString); // Like restoreDriverTmp, but just saves the entire contents of the file into // the given string including newlines. void restoreDriverTmpMultiline( const char* tmpFilePath, - std::function restoreSavedString); + std::function restoreSavedString); // Restore lib dir, lib name, and inc dir info that was saved to disk, for // compiler-driver use. diff --git a/compiler/include/library.h b/compiler/include/library.h index 2cf5d3baaf39..c544b885e9dc 100644 --- a/compiler/include/library.h +++ b/compiler/include/library.h @@ -45,7 +45,7 @@ enum PythonFileType { // array return type extern std::map exportedArrayElementType; -extern char libDir[FILENAME_MAX + 1]; +extern std::string libDir; extern std::map > pythonNames; extern std::map fortranKindNames; extern std::map fortranTypeNames; @@ -62,7 +62,7 @@ void codegen_make_python_module(); void ensureLibDirExists(); void openLibraryHelperFile(fileinfo* fi, - const char* name, + const std::string& name, const char* ext = NULL); void closeLibraryHelperFile(fileinfo* fi, bool beautifyIt = true); const char* getLibraryExtension(); diff --git a/compiler/include/log.h b/compiler/include/log.h index 741075e49881..7fc252612592 100644 --- a/compiler/include/log.h +++ b/compiler/include/log.h @@ -49,7 +49,7 @@ void logWriteLog(const char* passName, int passNum, char logTag); bool deletedIdON(); -extern char log_dir [FILENAME_MAX + 1]; +extern std::string log_dir; extern std::set log_modules; extern bool fLogDir; // was --log-dir passed? @@ -58,13 +58,13 @@ extern bool fLog; extern bool fLogIds; extern LogFormat fLogFormat; -extern int fdump_html; -extern char fdump_html_chpl_home[FILENAME_MAX + 1]; -extern bool fdump_html_include_system_modules; -extern bool fdump_html_wrap_lines; -extern bool fdump_html_print_block_IDs; +extern int fdump_html; +extern std::string fdump_html_chpl_home; +extern bool fdump_html_include_system_modules; +extern bool fdump_html_wrap_lines; +extern bool fdump_html_print_block_IDs; -extern FILE* deletedIdHandle; -extern char deletedIdFilename[FILENAME_MAX + 1]; +extern FILE* deletedIdHandle; +extern std::string deletedIdFilename; #endif diff --git a/compiler/include/stringutil.h b/compiler/include/stringutil.h index d09f5919d4d6..6c573b4ce151 100644 --- a/compiler/include/stringutil.h +++ b/compiler/include/stringutil.h @@ -27,6 +27,7 @@ using chpl::UniqueString; #include #include +#include #include const char* astr(const char* s1, @@ -41,6 +42,7 @@ const char* astr(const char* s1, const char* astr(const char* s1); const char* astr(const std::string& s); +const char* astr(std::string_view s); const char* astr(UniqueString s); const char* istr(int i); diff --git a/compiler/llvm/clangUtil.cpp b/compiler/llvm/clangUtil.cpp index 1f47d23c0071..e7afc434a5bd 100644 --- a/compiler/llvm/clangUtil.cpp +++ b/compiler/llvm/clangUtil.cpp @@ -4881,7 +4881,7 @@ static void makeBinaryLLVMForHIP(const std::string& artifactFilename, // Save the current state of the LLVM IR to an LLVM bitcode file if needed static void saveIrToBcFileIfNeeded(const std::string& filename, bool forceSave = false) { - bool shouldSave = forceSave || saveCDir[0]; + bool shouldSave = forceSave || !saveCDir.empty(); if (shouldSave) { GenInfo* info = gGenInfo; std::error_code tmpErr; @@ -5167,7 +5167,7 @@ void makeBinaryLLVM(void) { const char* bin = "dsymutil"; const char* sfx = ".dSYM"; const char* tmp = astr(tmpbinname, sfx); - const char* out = astr(executableFilename, sfx); + const char* out = astr(executableFilename.c_str(), sfx); // TODO: The innermost binary in the .dSYM with all the DWARF info // will have the name "executable.tmp", is there a way to give it a @@ -5183,7 +5183,7 @@ void makeBinaryLLVM(void) { if (fLibraryCompile) { moveGeneratedLibraryFile(tmpbinname); } else { - moveResultFromTmp(executableFilename, tmpbinname); + moveResultFromTmp(executableFilename.c_str(), tmpbinname); } } else { @@ -5727,7 +5727,7 @@ static std::string getLibraryOutputPath() { const char* exeExt = getLibraryExtension(); const char* libraryPrefix = ""; int libLength = strlen("lib"); - bool startsWithLib = strncmp(executableFilename, "lib", libLength) == 0; + bool startsWithLib = strncmp(executableFilename.c_str(), "lib", libLength) == 0; if (!startsWithLib) { libraryPrefix = "lib"; diff --git a/compiler/main/arg.cpp b/compiler/main/arg.cpp index 197f37d79591..818673431f9f 100644 --- a/compiler/main/arg.cpp +++ b/compiler/main/arg.cpp @@ -182,6 +182,12 @@ void usage(const ArgumentState* state, break; case 'P': + if (desc[i].location != 0) + printf("'%s'", ((std::string*) desc[i].location)->c_str()); + else + printf("''"); + break; + case 'S': if (desc[i].location != 0) printf("'%s'", (char*) desc[i].location); @@ -343,8 +349,8 @@ void init_arg_desc(ArgumentState* state, ArgumentDescription* arg_desc, Flag types: I = int - P = path - S = string + P = path (std::string) + S = string (char*) D = double f = set to false F = set to true @@ -496,7 +502,7 @@ static void ApplyValue(const ArgumentState* state, break; case 'P': - strncpy((char*) location, value, FILENAME_MAX); + *((std::string*) location) = value; break; case 'S': @@ -719,7 +725,7 @@ static void process_arg(const ArgumentState* state, case 'P': if (desc->location != NULL) { - strncpy((char*) desc->location, arg, FILENAME_MAX); + *((std::string*)desc->location) = arg; } break; diff --git a/compiler/main/driver.cpp b/compiler/main/driver.cpp index d533e813d7bb..69de3c974d6a 100644 --- a/compiler/main/driver.cpp +++ b/compiler/main/driver.cpp @@ -75,13 +75,13 @@ std::map envMap; // envMap used as input to getChplEnv static std::map envMapChplEnvInput; -char CHPL_HOME[FILENAME_MAX+1] = ""; +std::string CHPL_HOME; // These are more specific than CHPL_HOME, to work in // settings where Chapel is installed. -char CHPL_RUNTIME_LIB[FILENAME_MAX+1] = ""; -char CHPL_RUNTIME_INCL[FILENAME_MAX+1] = ""; -char CHPL_THIRD_PARTY[FILENAME_MAX+1] = ""; +std::string CHPL_RUNTIME_LIB; +std::string CHPL_RUNTIME_INCL; +std::string CHPL_THIRD_PARTY; const char* CHPL_HOST_PLATFORM = NULL; const char* CHPL_HOST_ARCH = NULL; @@ -135,8 +135,8 @@ const char* CHPL_ROCM_AMDGCN_PATH = NULL; const char* CHPL_GPU = NULL; const char* CHPL_GPU_ARCH = NULL; -static char libraryFilename[FILENAME_MAX] = ""; -static char incFilename[FILENAME_MAX] = ""; +static std::string libraryFilename; +static std::string incFilename; static bool fBaseline = false; // Flags that were in commonFlags.h/cpp for awhile @@ -152,7 +152,7 @@ bool fDriverMakeBinaryPhase = false; bool fDriverDoMonolithic = false; bool driverDebugPhaseSpecified = false; // Tmp dir path managed by compiler driver -char driverTmpDir[FILENAME_MAX] = ""; +std::string driverTmpDir; bool fExitLeaks = false; bool fLibraryCompile = false; bool fLibraryFortran = false; @@ -390,7 +390,7 @@ bool fDynoGenStdLib = false; bool fDynoLibGenOrUse = false; // .dyno file or --dyno-gen-lib/std size_t fDynoBreakOnHash = 0; bool fDynoNoBreakError = false; -static char fDynoTimingPath[FILENAME_MAX] = ""; +static std::string fDynoTimingPath; bool fResolveConcreteFns = false; bool fIdBasedMunging = false; @@ -431,28 +431,21 @@ std::unordered_set gDynoGenLibModuleNameAstrs; std::string gMainModuleName; static void setChplHomeDerivedVars() { - int rc; - rc = snprintf(CHPL_RUNTIME_LIB, FILENAME_MAX, "%s/%s", - CHPL_HOME, "lib"); - if ( rc >= FILENAME_MAX ) USR_FATAL("CHPL_HOME pathname too long"); - rc = snprintf(CHPL_RUNTIME_INCL, FILENAME_MAX, "%s/%s", - CHPL_HOME, "runtime/include"); - if ( rc >= FILENAME_MAX ) USR_FATAL("CHPL_HOME pathname too long"); - rc = snprintf(CHPL_THIRD_PARTY, FILENAME_MAX, "%s/%s", - CHPL_HOME, "third-party"); - if ( rc >= FILENAME_MAX ) USR_FATAL("CHPL_HOME pathname too long"); + CHPL_RUNTIME_LIB = CHPL_HOME + "/lib"; + CHPL_RUNTIME_INCL = CHPL_HOME + "/runtime/include"; + CHPL_THIRD_PARTY = CHPL_HOME + "/third-party"; } static void saveChplHomeDerivedInEnv() { int rc; - envMap["CHPL_RUNTIME_LIB"] = strdup(CHPL_RUNTIME_LIB); - rc = setenv("CHPL_RUNTIME_LIB", CHPL_RUNTIME_LIB, 1); + envMap["CHPL_RUNTIME_LIB"] = strdup(CHPL_RUNTIME_LIB.c_str()); + rc = setenv("CHPL_RUNTIME_LIB", envMap["CHPL_RUNTIME_LIB"], 1); if( rc ) USR_FATAL("Could not setenv CHPL_RUNTIME_LIB"); - envMap["CHPL_RUNTIME_INCL"] = strdup(CHPL_RUNTIME_INCL); - rc = setenv("CHPL_RUNTIME_INCL", CHPL_RUNTIME_INCL, 1); + envMap["CHPL_RUNTIME_INCL"] = strdup(CHPL_RUNTIME_INCL.c_str()); + rc = setenv("CHPL_RUNTIME_INCL", envMap["CHPL_RUNTIME_INCL"], 1); if( rc ) USR_FATAL("Could not setenv CHPL_RUNTIME_INCL"); - envMap["CHPL_THIRD_PARTY"] = strdup(CHPL_THIRD_PARTY); - rc = setenv("CHPL_THIRD_PARTY", CHPL_THIRD_PARTY, 1); + envMap["CHPL_THIRD_PARTY"] = strdup(CHPL_THIRD_PARTY.c_str()); + rc = setenv("CHPL_THIRD_PARTY", envMap["CHPL_THIRD_PARTY"], 1); if( rc ) USR_FATAL("Could not setenv CHPL_THIRD_PARTY"); } @@ -463,21 +456,21 @@ static bool restoreChplHomeDerivedFromEnv() { envVar = getenv("CHPL_RUNTIME_LIB"); if (envVar) { - strncpy(CHPL_RUNTIME_LIB, envVar, FILENAME_MAX); + CHPL_RUNTIME_LIB = envVar; } else { haveAll = false; } envVar = getenv("CHPL_RUNTIME_INCL"); if (envVar) { - strncpy(CHPL_RUNTIME_INCL, envVar, FILENAME_MAX); + CHPL_RUNTIME_INCL = envVar; } else { haveAll = false; } envVar = getenv("CHPL_THIRD_PARTY"); if (envVar) { - strncpy(CHPL_THIRD_PARTY, envVar, FILENAME_MAX); + CHPL_THIRD_PARTY = envVar; } else { haveAll = false; } @@ -510,11 +503,7 @@ static void setupChplHome(const char* argv0) { USR_FATAL("$CHPL_HOME must be set to run chpl"); } - if (foundChplHome.size() > FILENAME_MAX) { - USR_FATAL("$CHPL_HOME=%s path too long", foundChplHome.c_str()); - } - strncpy(CHPL_HOME, foundChplHome.c_str(), FILENAME_MAX); - + CHPL_HOME = foundChplHome; // Get derived-from-home vars if (restoreChplHomeDerivedFromEnv()) { @@ -522,27 +511,14 @@ static void setupChplHome(const char* argv0) { } else if( installed ) { // detected we are installed in a prefix, calculate values from that - int rc; // E.g. /usr/lib/chapel/1.16/runtime/lib - rc = snprintf(CHPL_RUNTIME_LIB, FILENAME_MAX, "%s/%s/%s/%s", - get_configured_prefix(), // e.g. /usr - "lib/chapel", - majMinorVers, - "runtime/lib"); - if ( rc >= FILENAME_MAX ) USR_FATAL("Installed pathname too long"); - rc = snprintf(CHPL_RUNTIME_INCL, FILENAME_MAX, "%s/%s/%s/%s", - get_configured_prefix(), // e.g. /usr - "lib/chapel", - majMinorVers, - "runtime/include"); - if ( rc >= FILENAME_MAX ) USR_FATAL("Installed pathname too long"); - rc = snprintf(CHPL_THIRD_PARTY, FILENAME_MAX, "%s/%s/%s/%s", - get_configured_prefix(), // e.g. /usr - "lib/chapel", - majMinorVers, - "third-party"); - if ( rc >= FILENAME_MAX ) USR_FATAL("Installed pathname too long"); - + std::string configuredPrefix = get_configured_prefix(); + CHPL_RUNTIME_LIB = + configuredPrefix + "/lib/chapel/" + majMinorVers + "/runtime/lib"; + CHPL_RUNTIME_INCL = + configuredPrefix + "/lib/chapel/" + majMinorVers + "/runtime/include"; + CHPL_THIRD_PARTY = + configuredPrefix + "/lib/chapel/" + majMinorVers + "/third-party"; } else { // set to default values based on home path setChplHomeDerivedVars(); @@ -600,18 +576,8 @@ static void recordCodeGenStrings(int argc, char* argv[]) { } static void setHome(const ArgumentDescription* desc, const char* arg) { - // Wipe previous CHPL_HOME when comp flag is given - CHPL_HOME[0] = '\0'; - - // Copy arg into CHPL_HOME - size_t arglen = strlen(arg) + 1; // room for \0 - if (arglen <= sizeof(CHPL_HOME)) { - memcpy(CHPL_HOME, arg, arglen); - // Update envMap - envMap["CHPL_HOME"] = CHPL_HOME; - } else { - USR_FATAL("CHPL_HOME argument too long"); - } + CHPL_HOME = arg; + envMap["CHPL_HOME"] = CHPL_HOME.c_str(); setChplHomeDerivedVars(); saveChplHomeDerivedInEnv(); @@ -752,15 +718,15 @@ static void setLLVMPrintPasses(const ArgumentDescription* desc, const char* arg) } static void handleLibrary(const ArgumentDescription* desc, const char* arg_unused) { - addLibFile(libraryFilename, /* fromCmdLine */ true); + addLibFile(libraryFilename.c_str(), /* fromCmdLine */ true); } static void handleLibPath(const ArgumentDescription* desc, const char* arg_unused) { - addLibPath(libraryFilename, /* fromCmdLine */ true); + addLibPath(libraryFilename.c_str(), /* fromCmdLine */ true); } static void handleIncDir(const ArgumentDescription* desc, const char* arg_unused) { - addIncInfo(incFilename, /* fromCmdLine */ true); + addIncInfo(incFilename.c_str(), /* fromCmdLine */ true); } static int invokeChplWithArgs(int argc, char* argv[], @@ -927,7 +893,7 @@ static void verifySaveCDir(const ArgumentDescription* desc, const char* unused) if (saveCDir[0] == '-') { USR_FATAL("--savec takes a directory name as its argument\n" " (you specified '%s', assumed to be another flag)", - saveCDir); + saveCDir.c_str()); } } @@ -937,7 +903,7 @@ static void verifySaveLibDir(const ArgumentDescription* desc, const char* unused if (libDir[0] == '-') { USR_FATAL("--library-dir takes a directory name as its argument\n" " (you specified '%s', assumed to be another flag)", - libDir); + libDir.c_str()); } setLibmode(desc, unused); } @@ -1311,19 +1277,19 @@ static ArgumentDescription arg_desc[] = { {"cpp-lines", ' ', NULL, "[Don't] Generate #line annotations", "N", &printCppLineno, "CHPL_CG_CPP_LINES", noteCppLinesSet}, {"max-c-ident-len", ' ', NULL, "Maximum length of identifiers in generated code, 0 for unlimited", "I", &fMaxCIdentLen, "CHPL_MAX_C_IDENT_LEN", NULL}, {"munge-user-idents", ' ', NULL, "[Don't] Munge user identifiers to avoid naming conflicts with external code", "N", &fMungeUserIdents, "CHPL_MUNGE_USER_IDENTS"}, - {"savec", ' ', "", "Save generated C code in directory", "P", saveCDir, "CHPL_SAVEC_DIR", verifySaveCDir}, + {"savec", ' ', "", "Save generated C code in directory", "P", &saveCDir, "CHPL_SAVEC_DIR", verifySaveCDir}, {"", ' ', NULL, "C Code Compilation Options", NULL, NULL, NULL, NULL}, {"ccflags", ' ', "", "Back-end C compiler flags (can be specified multiple times)", "S", NULL, "CHPL_CC_FLAGS", setCCFlags}, {"debug", 'g', NULL, "[Don't] Support debugging of generated C code", "N", &debugCCode, "CHPL_DEBUG", setChapelDebug}, {"dynamic", ' ', NULL, "Generate a dynamically linked binary", "F", &fLinkStyle, NULL, setDynamicLink}, - {"hdr-search-path", 'I', "", "C header search path", "P", incFilename, "CHPL_INCLUDE_PATH", handleIncDir}, + {"hdr-search-path", 'I', "", "C header search path", "P", &incFilename, "CHPL_INCLUDE_PATH", handleIncDir}, {"ldflags", ' ', "", "Back-end C linker flags (can be specified multiple times)", "S", NULL, "CHPL_LD_FLAGS", setLDFlags}, - {"lib-linkage", 'l', "", "C library linkage", "P", libraryFilename, "CHPL_LIB_NAME", handleLibrary}, - {"lib-search-path", 'L', "", "C library search path", "P", libraryFilename, "CHPL_LIB_PATH", handleLibPath}, + {"lib-linkage", 'l', "", "C library linkage", "P", &libraryFilename, "CHPL_LIB_NAME", handleLibrary}, + {"lib-search-path", 'L', "", "C library search path", "P", &libraryFilename, "CHPL_LIB_PATH", handleLibPath}, {"optimize", 'O', NULL, "[Don't] Optimize generated C code", "N", &optimizeCCode, "CHPL_OPTIMIZE", NULL}, {"specialize", ' ', NULL, "[Don't] Specialize generated C code for CHPL_TARGET_CPU", "N", &specializeCCode, "CHPL_SPECIALIZE", NULL}, - {"output", 'o', "", "Name output executable", "P", executableFilename, "CHPL_EXE_NAME", NULL}, + {"output", 'o', "", "Name output executable", "P", &executableFilename, "CHPL_EXE_NAME", NULL}, {"static", ' ', NULL, "Generate a statically linked binary", "F", &fLinkStyle, NULL, NULL}, {"", ' ', NULL, "LLVM Code Generation Options", NULL, NULL, NULL, NULL}, @@ -1391,9 +1357,9 @@ static ArgumentDescription arg_desc[] = { {"html-user", ' ', NULL, "Dump IR in HTML for user module(s) only (toggle)", "T", &fdump_html, "CHPL_HTML_USER", setHtmlUser}, {"html-wrap-lines", ' ', NULL, "[Don't] allow wrapping lines in HTML dumps", "N", &fdump_html_wrap_lines, "CHPL_HTML_WRAP_LINES", NULL}, {"html-print-block-ids", ' ', NULL, "[Don't] print block IDs in HTML dumps", "N", &fdump_html_print_block_IDs, "CHPL_HTML_PRINT_BLOCK_IDS", NULL}, - {"html-chpl-home", ' ', NULL, "Path to use instead of CHPL_HOME in HTML dumps", "P", fdump_html_chpl_home, "CHPL_HTML_CHPL_HOME", NULL}, + {"html-chpl-home", ' ', NULL, "Path to use instead of CHPL_HOME in HTML dumps", "P", &fdump_html_chpl_home, "CHPL_HTML_CHPL_HOME", NULL}, {"log", ' ', NULL, "Dump IR in text format.", "F", &fLog, "CHPL_LOG", NULL}, - {"log-dir", ' ', "", "Specify log directory", "P", log_dir, "CHPL_LOG_DIR", setLogDir}, + {"log-dir", ' ', "", "Specify log directory", "P", &log_dir, "CHPL_LOG_DIR", setLogDir}, {"log-ids", ' ', NULL, "[Don't] include BaseAST::ids in log files", "N", &fLogIds, "CHPL_LOG_IDS", NULL}, {"log-module", ' ', "", "Restrict IR dump to the named module. Can be specified multiple times", "S", NULL, "CHPL_LOG_MODULE", setLogModule}, {"log-pass", ' ', "", "Restrict IR dump to the named pass. Can be specified multiple times", "S", NULL, "CHPL_LOG_PASS", setLogPass}, @@ -1471,19 +1437,19 @@ static ArgumentDescription arg_desc[] = { {"gpu-ptxas-enforce-optimization", ' ', NULL, "Modify generated .ptxas file to enable optimizations", "F", &fGpuPtxasEnforceOpt, NULL, NULL}, {"gpu-specialization", ' ', NULL, "Enable [disable] an optimization that clones functions into copies assumed to run on a GPU locale.", "N", &fGpuSpecialization, "CHPL_GPU_SPECIALIZATION", NULL}, {"library", ' ', NULL, "Generate a Chapel library file", "F", &fLibraryCompile, NULL, NULL}, - {"library-dir", ' ', "", "Save generated library helper files in directory", "P", libDir, "CHPL_LIB_SAVE_DIR", verifySaveLibDir}, - {"library-header", ' ', "", "Name generated header file", "P", libmodeHeadername, NULL, setLibmode}, + {"library-dir", ' ', "", "Save generated library helper files in directory", "P", &libDir, "CHPL_LIB_SAVE_DIR", verifySaveLibDir}, + {"library-header", ' ', "", "Name generated header file", "P", &libmodeHeadername, NULL, setLibmode}, {"library-makefile", ' ', NULL, "Generate a makefile to help use the generated library", "F", &fLibraryMakefile, NULL, setLibmode}, {"library-cmakelists", ' ', NULL, "Generate a CMakeLists file to help use the generated library", "F", &fLibraryCMakeLists, NULL, setLibmode}, {"library-fortran", ' ', NULL, "Generate a module compatible with Fortran", "F", &fLibraryFortran, NULL, setLibmode}, - {"library-fortran-name", ' ', "", "Name generated Fortran module", "P", fortranModulename, NULL, setFortranAndLibmode}, + {"library-fortran-name", ' ', "", "Name generated Fortran module", "P", &fortranModulename, NULL, setFortranAndLibmode}, {"library-python", ' ', NULL, "Generate a module compatible with Python", "F", &fLibraryPython, NULL, setLibmode}, - {"library-python-name", ' ', "", "Name generated Python module", "P", pythonModulename, NULL, setPythonAndLibmode}, + {"library-python-name", ' ', "", "Name generated Python module", "P", &pythonModulename, NULL, setPythonAndLibmode}, {"library-ml-debug", ' ', NULL, "Enable [disable] generation of debug messages in multi-locale libraries", "N", &fMultiLocaleLibraryDebug, NULL, NULL}, {"localize-global-consts", ' ', NULL, "Enable [disable] optimization of global constants", "n", &fNoGlobalConstOpt, "CHPL_DISABLE_GLOBAL_CONST_OPT", NULL}, {"munge-with-ids", ' ', NULL, "[Don't] use ID-based munging", "N", &fIdBasedMunging, NULL, NULL}, {"local-temp-names", ' ', NULL, "[Don't] Generate locally-unique temp names", "N", &localTempNames, "CHPL_LOCAL_TEMP_NAMES", NULL}, - {"log-deleted-ids-to", ' ', "", "Log AST id and memory address of each deleted node to the specified file", "P", deletedIdFilename, "CHPL_DELETED_ID_FILENAME", NULL}, + {"log-deleted-ids-to", ' ', "", "Log AST id and memory address of each deleted node to the specified file", "P", &deletedIdFilename, "CHPL_DELETED_ID_FILENAME", NULL}, {"memory-frees", ' ', NULL, "Enable [disable] memory frees in the generated code", "n", &fNoMemoryFrees, "CHPL_DISABLE_MEMORY_FREES", NULL}, {"override-checking", ' ', NULL, "[Don't] check use of override keyword", "N", &fOverrideChecking, NULL, NULL}, // These flags enable us to diagnose problems with our internal modules in @@ -1614,12 +1580,12 @@ static void printStuff(const char* argv0) { printedSomething = true; } if( fPrintChplHome ) { - printf("%s\n", CHPL_HOME); + printf("%s\n", CHPL_HOME.c_str()); printedSomething = true; } if ( fPrintBootstrapCommands ) { - printf("export CHPL_HOME='%s'\n", CHPL_HOME); - printf("export CHPL_THIRD_PARTY='%s'\n", CHPL_THIRD_PARTY); + printf("export CHPL_HOME='%s'\n", CHPL_HOME.c_str()); + printf("export CHPL_THIRD_PARTY='%s'\n", CHPL_THIRD_PARTY.c_str()); printedSomething = true; } if ( fPrintChplLoc ) { @@ -1633,25 +1599,19 @@ static void printStuff(const char* argv0) { } if( fPrintChplSettings ) { - char buf[FILENAME_MAX+1] = ""; - printf("CHPL_HOME: %s\n", CHPL_HOME); - printf("CHPL_RUNTIME_LIB: %s\n", CHPL_RUNTIME_LIB); - printf("CHPL_RUNTIME_INCL: %s\n", CHPL_RUNTIME_INCL); - printf("CHPL_THIRD_PARTY: %s\n", CHPL_THIRD_PARTY); + std::string buf; + printf("CHPL_HOME: %s\n", CHPL_HOME.c_str()); + printf("CHPL_RUNTIME_LIB: %s\n", CHPL_RUNTIME_LIB.c_str()); + printf("CHPL_RUNTIME_INCL: %s\n", CHPL_RUNTIME_INCL.c_str()); + printf("CHPL_THIRD_PARTY: %s\n", CHPL_THIRD_PARTY.c_str()); printf("\n"); const char* internalFlag = ""; if (developer) internalFlag = "--internal"; - int wanted_to_write = snprintf(buf, sizeof(buf), - "%s/util/printchplenv --all %s", - CHPL_HOME, internalFlag); - if (wanted_to_write < 0) { - USR_FATAL("character encoding error in CHPL_HOME path name"); - } else if ((size_t)wanted_to_write >= sizeof(buf)) { - USR_FATAL("CHPL_HOME path name is too long"); - } + + buf = CHPL_HOME + "/util/printchplenv --all " + internalFlag; fflush(stdout); // make sure output is flushed before running subprocess - int status = mysystem(buf, "running printchplenv", false); + int status = mysystem(buf.c_str(), "running printchplenv", false); if (compilerSetChplLLVM) { printf("---\n"); printf("* Note: CHPL_LLVM was set by 'chpl' since it was built without LLVM support.\n"); @@ -1726,7 +1686,7 @@ static void populateEnvMap() { // This is a driver sub-invocation, so restore and use saved output. restoreDriverTmpMultiline( printchplenvOutputFilename, - [&printchplenvOutput](const char* restoredOutput) { + [&printchplenvOutput](std::string_view restoredOutput) { printchplenvOutput = restoredOutput; }); } @@ -1740,8 +1700,8 @@ static void populateEnvMap() { } // Get printchplenv output and collect into a map - auto chplEnvResult = - chpl::getChplEnv(envMap, CHPL_HOME, printchplenvOutputPtr); + auto chplEnvResult = chpl::getChplEnv(envMap, CHPL_HOME.c_str(), + printchplenvOutputPtr); if (!chplEnvResult) { if (auto err = chplEnvResult.getError()) { USR_FATAL("failed to get environment settings (error while running printchplenv: %s)", @@ -1754,7 +1714,7 @@ static void populateEnvMap() { // If in initial driver invocation, save printchplenv command output to disk // for use in sub-invocations. if (!fDriverDoMonolithic && !driverInSubInvocation) { - saveDriverTmp(printchplenvOutputFilename, printchplenvOutput.c_str(), + saveDriverTmp(printchplenvOutputFilename, printchplenvOutput, /* appendNewline */ false); } @@ -1862,7 +1822,7 @@ static void setupChplGlobals(const char* argv0) { setupChplHome(argv0); // Keep envMap updated - envMap["CHPL_HOME"] = CHPL_HOME; + envMap["CHPL_HOME"] = CHPL_HOME.c_str(); } setupChplLLVM(); @@ -2010,7 +1970,7 @@ static void checkCompilerDriverFlags() { "Requested monolithic compilation, but an internal compiler-driver " "flag was set"); } - if (driverTmpDir[0]) { + if (!driverTmpDir.empty()) { USR_FATAL("Can't set driver temp dir for monolithic compilation"); } } @@ -2298,16 +2258,16 @@ static void bootstrapTmpDir() { // We are in a sub-invocation and can assume that a tmp dir has been // established for us by the driver already, and will be deleted for us // later if necessary. - INT_ASSERT(driverTmpDir[0] && + INT_ASSERT(!driverTmpDir.empty() && "driver sub-invocation was not supplied a tmp dir path"); - config.tmpDir = driverTmpDir; + config.tmpDir = driverTmpDir.c_str(); config.keepTmpDir = true; } else { // This is an initial invocation of the driver, or monolithic. - if (saveCDir[0]) { + if (!saveCDir.empty()) { // Bootstrap with specified savecdir. - ensureDirExists(saveCDir, "ensuring --savec directory exists"); - config.tmpDir = saveCDir; + ensureDirExists(saveCDir.c_str(), "ensuring --savec directory exists"); + config.tmpDir = saveCDir.c_str(); config.keepTmpDir = true; } else { // No specified savecdir, so we don't do anything for bootstrapping. @@ -2577,7 +2537,7 @@ int main(int argc, char* argv[]) { tracker.ReportPassGroupTotals(&groupTimes); // Save times to file - std::vector groupTimesStrs; + std::vector groupTimesStrs; for (const unsigned long groupTime : groupTimes) { groupTimesStrs.emplace_back(astr(std::to_string(groupTime).c_str())); } @@ -2587,10 +2547,10 @@ int main(int argc, char* argv[]) { // and report out everything. // Restore times from file - restoreDriverTmp(groupTimesFilename, - [&groupTimes](const char* timeStr) { - groupTimes.emplace_back(std::stoul(timeStr)); - }); + restoreDriverTmp( + groupTimesFilename, [&groupTimes](std::string_view timeStr) { + groupTimes.emplace_back(std::stoul(std::string(timeStr))); + }); // Unless stopping early, expect frontend, middle-end, and (incomplete) // backend results from compilation phase, plus the other half of diff --git a/compiler/main/log.cpp b/compiler/main/log.cpp index bbd63031e50d..24a7bfbf8fcb 100644 --- a/compiler/main/log.cpp +++ b/compiler/main/log.cpp @@ -33,7 +33,7 @@ #include #include -char log_dir [FILENAME_MAX + 1] = "./log"; +std::string log_dir = "./log"; std::set log_modules; bool fLog = false; @@ -42,13 +42,13 @@ bool fLogIds = true; LogFormat fLogFormat = LogFormat::DEFAULT; int fdump_html = 0; -char fdump_html_chpl_home[FILENAME_MAX + 1] = ""; +std::string fdump_html_chpl_home = ""; bool fdump_html_include_system_modules = true; bool fdump_html_wrap_lines = true; bool fdump_html_print_block_IDs = false; FILE* deletedIdHandle = NULL; -char deletedIdFilename[FILENAME_MAX + 1] = ""; +std::string deletedIdFilename = ""; // Keeping names of available passes static bool availableInitialized = false; @@ -124,27 +124,27 @@ void setupLogfiles() { if (fLogDir == true) fLog = true; - if (fLog || fdump_html || *deletedIdFilename) { + if (fLog || fdump_html || !deletedIdFilename.empty()) { // Remove the log directory to make sure there is no stale data. // Only do this for the driver compilation phase (or monolithic mode) to // avoid overwriting. if (fDriverDoMonolithic || fDriverCompilationPhase) { - deleteDir(log_dir); - ensureDirExists(log_dir, "ensuring directory for log files exists"); + deleteDir(log_dir.c_str()); + ensureDirExists(log_dir.c_str(), "ensuring directory for log files exists"); } } - if (log_dir[strlen(log_dir) - 1] != '/') { - strcat(log_dir, "/"); + if (log_dir.back() != '/') { + log_dir += "/"; } if (fdump_html) { AstDumpToHtml::init(); } - if (deletedIdFilename[0] != '\0') { - if ((deletedIdHandle = fopen(deletedIdFilename, "w")) == 0) { - USR_FATAL("cannot open file \"%s\", to log deleted AST ids, for writing", deletedIdFilename); + if (!deletedIdFilename.empty()) { + if ((deletedIdHandle = fopen(deletedIdFilename.c_str(), "w")) == 0) { + USR_FATAL("cannot open file \"%s\", to log deleted AST ids, for writing", deletedIdFilename.c_str()); } } } @@ -154,7 +154,7 @@ void teardownLogfiles() { AstDumpToHtml::done(); } - if (deletedIdFilename[0] != '\0') { + if (!deletedIdFilename.empty()) { fclose(deletedIdHandle); deletedIdHandle = NULL; } @@ -174,5 +174,5 @@ void logWriteLog(const char* passName, int passNum, char logTag) { } bool deletedIdON() { - return (deletedIdFilename[0] != '\0') ? true : false; + return (!deletedIdFilename.empty()) ? true : false; } diff --git a/compiler/resolution/functionResolution.cpp b/compiler/resolution/functionResolution.cpp index 0e9c0c8671ab..5ef659d843ef 100644 --- a/compiler/resolution/functionResolution.cpp +++ b/compiler/resolution/functionResolution.cpp @@ -13093,9 +13093,8 @@ static void printUnusedFunctions() { checking. */ #ifdef PRINT_UNUSED_FNS_TO_FILE - char fname[FILENAME_MAX+1]; - snprintf(fname, FILENAME_MAX, "%s.%s", executableFilename, "unused"); - FILE* outFile = fopen(fname, "w"); + std::string fname = executableFilename + ".unused"; + FILE* outFile = fopen(fname.c_str(), "w"); #else FILE* outFile = stdout; #endif diff --git a/compiler/util/files.cpp b/compiler/util/files.cpp index 4183614988d1..24bd2926de00 100644 --- a/compiler/util/files.cpp +++ b/compiler/util/files.cpp @@ -47,11 +47,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -60,11 +62,11 @@ #include -char executableFilename[FILENAME_MAX + 1] = ""; -char libmodeHeadername[FILENAME_MAX + 1] = ""; -char fortranModulename[FILENAME_MAX + 1] = ""; -char pythonModulename[FILENAME_MAX + 1] = ""; -char saveCDir[FILENAME_MAX + 1] = ""; +std::string executableFilename; +std::string libmodeHeadername; +std::string fortranModulename; +std::string pythonModulename; +std::string saveCDir; const char* additionalFilenamesListFilename = "additionalSourceFiles.tmp"; @@ -147,11 +149,11 @@ static void checkDriverTmp() { assert(!fDriverDoMonolithic && "meant for use in driver mode only"); bool valid = false; - if (driverTmpDir[0] == '\0') { + if (driverTmpDir.empty()) { // We are in an initial invocation, all good. valid = true; } - if (gContext->tmpDir() == std::string(driverTmpDir)) { + if (gContext->tmpDir() == driverTmpDir) { // In subinvocation and context's tmp dir has been set to driver // specification, all good. valid = true; @@ -164,13 +166,13 @@ static void checkDriverTmp() { "attempted to save info to tmp dir before it is set up for driver use"); } -void saveDriverTmp(const char* tmpFilePath, const char* stringToSave, +void saveDriverTmp(const char* tmpFilePath, std::string_view stringToSave, bool appendNewline) { saveDriverTmpMultiple(tmpFilePath, {stringToSave}, !appendNewline); } void saveDriverTmpMultiple(const char* tmpFilePath, - std::vector stringsToSave, + std::vector stringsToSave, bool noNewlines) { checkDriverTmp(); @@ -194,50 +196,39 @@ void saveDriverTmpMultiple(const char* tmpFilePath, // Write into tmp file fileinfo* file = openTmpFile(pathAsAstr, fileOpenMode); - for (const auto stringToSave : stringsToSave) { - fprintf(file->fptr, "%s%s", stringToSave, (noNewlines ? "" : "\n")); + for (auto stringToSave : stringsToSave) { + fprintf(file->fptr, "%s%s", stringToSave.data(), (noNewlines ? "" : "\n")); } closefile(file); } void restoreDriverTmp(const char* tmpFilePath, - std::function restoreSavedString) { + std::function restoreSavedString) { assert(!fDriverDoMonolithic && "meant for use in driver mode only"); // Create file iff it did not already exist, for simpler reading logic in the // rest of the function. fileinfo* tmpFileDummy = openTmpFile(tmpFilePath, "a"); + const char* path = tmpFileDummy->pathname; closefile(tmpFileDummy); - fileinfo* tmpFile = openTmpFile(tmpFilePath, "r"); - - char strBuf[4096]; - while (fgets(strBuf, sizeof(strBuf), tmpFile->fptr)) { - // Note: Using strlen here (instead of strnlen) is safe because fgets - // guarantees null termination. - size_t len = strlen(strBuf); - // remove trailing newline, which fgets preserves unless buffer is exceeded - assert(strBuf[len - 1] == '\n' && "stored line exceeds maximum length"); - strBuf[--len] = '\0'; - - // invoke restoring function - restoreSavedString(strBuf); + std::ifstream fileStream(path); + std::string line; + while (std::getline(fileStream, line)) { + restoreSavedString(line); } - - closefile(tmpFile); } void restoreDriverTmpMultiline( const char* tmpFilePath, - std::function restoreSavedString) { + std::function restoreSavedString) { std::ostringstream os; // Just call line-by-line restore for simplicity, adding newlines back in. restoreDriverTmp(tmpFilePath, - [&os](const char* line) { os << line << "\n"; }); + [&os](std::string_view line) { os << line << "\n"; }); - std::string restoredString = os.str(); - restoreSavedString(restoredString.c_str()); + restoreSavedString(os.str()); } void restoreLibraryAndIncludeInfo() { @@ -245,14 +236,14 @@ void restoreLibraryAndIncludeInfo() { "should only be restoring library and include info in driver " "makeBinary phase"); - restoreDriverTmp(libDirsFilename, [](const char* filename) { - addLibPath(filename, /* fromCmdLine */ false); + restoreDriverTmp(libDirsFilename, [](std::string_view filename) { + addLibPath(filename.data(), /* fromCmdLine */ false); }); - restoreDriverTmp(libFilesFilename, [](const char* filename) { - addLibFile(filename, /* fromCmdLine */ false); + restoreDriverTmp(libFilesFilename, [](std::string_view filename) { + addLibFile(filename.data(), /* fromCmdLine */ false); }); - restoreDriverTmp(incDirsFilename, [](const char* filename) { - addIncInfo(filename, /* fromCmdLine */ false); + restoreDriverTmp(incDirsFilename, [](std::string_view filename) { + addIncInfo(filename.data(), /* fromCmdLine */ false); }); } @@ -262,7 +253,7 @@ void restoreAdditionalSourceFiles() { std::vector additionalFilenames; restoreDriverTmp(additionalFilenamesListFilename, - [&additionalFilenames](const char* filename) { + [&additionalFilenames](std::string_view filename) { additionalFilenames.push_back(astr(filename)); }); addSourceFiles(additionalFilenames.size(), &additionalFilenames[0]); @@ -303,8 +294,8 @@ const char* getDirectory(const char* filename) { if (filenamebase == NULL) { return astr("."); } else { - char dir[FILENAME_MAX]; const int len = filenamebase - filename; + char dir[len + 1]; strncpy(dir, filename, len); dir[len] = '\0'; return astr(dir); @@ -390,7 +381,7 @@ void closeCFile(fileinfo* fi, bool beautifyIt) { // beautify without also improving indentation and such which could // save some time. // - if (beautifyIt && (saveCDir[0] || printCppLineno)) + if (beautifyIt && (!saveCDir.empty() || printCppLineno)) beautify(fi); } @@ -530,7 +521,7 @@ void addSourceFiles(int numNewFilenames, const char* filename[]) { if (!fDriverDoMonolithic && fDriverCompilationPhase && firstAddedIdx >= 0) { saveDriverTmpMultiple( additionalFilenamesListFilename, - std::vector(inputFilenames + firstAddedIdx, + std::vector(inputFilenames + firstAddedIdx, inputFilenames + cursor)); } @@ -622,7 +613,7 @@ const char* createDebuggerFile(const char* debugger, int argc, char* argv[]) { fprintf(dbgfile, "\n"); closefile(dbgfile); - myshell(astr("cat ", CHPL_HOME, "/compiler/etc/", debugger, ".commands >> ", + myshell(astr("cat ", CHPL_HOME.c_str(), "/compiler/etc/", debugger, ".commands >> ", dbgfilename), astr("appending ", debugger, " commands"), false); @@ -753,12 +744,12 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, bool skip_compile_link, const std::vector& splitFiles) { const char* tmpDirName = gContext->tmpDir().c_str(); - const char* strippedExeFilename = stripdirectories(executableFilename); + const char* strippedExeFilename = stripdirectories(executableFilename.c_str()); const char* exeExt = getLibraryExtension(); const char* server = ""; const char* tmpserver = ""; const char* tmpbin = ""; - bool startsWithLib = !strncmp(executableFilename, "lib", 3); + bool startsWithLib = !strncmp(executableFilename.c_str(), "lib", 3); bool dyn = (fLinkStyle == LS_DYNAMIC); std::string makeallvars; fileinfo makefile; @@ -766,10 +757,10 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, openCFile(&makefile, "Makefile"); // Capture different compiler directories. - fprintf(makefile.fptr, "CHPL_MAKE_HOME = %s\n\n", CHPL_HOME); - fprintf(makefile.fptr, "CHPL_MAKE_RUNTIME_LIB = %s\n\n", CHPL_RUNTIME_LIB); - fprintf(makefile.fptr, "CHPL_MAKE_RUNTIME_INCL = %s\n\n", CHPL_RUNTIME_INCL); - fprintf(makefile.fptr, "CHPL_MAKE_THIRD_PARTY = %s\n\n", CHPL_THIRD_PARTY); + fprintf(makefile.fptr, "CHPL_MAKE_HOME = %s\n\n", CHPL_HOME.c_str()); + fprintf(makefile.fptr, "CHPL_MAKE_RUNTIME_LIB = %s\n\n", CHPL_RUNTIME_LIB.c_str()); + fprintf(makefile.fptr, "CHPL_MAKE_RUNTIME_INCL = %s\n\n", CHPL_RUNTIME_INCL.c_str()); + fprintf(makefile.fptr, "CHPL_MAKE_THIRD_PARTY = %s\n\n", CHPL_THIRD_PARTY.c_str()); fprintf(makefile.fptr, "TMPDIRNAME = %s\n\n", tmpDirName); // Store chapel environment variables in a cache. @@ -792,9 +783,9 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, if (fLibraryCompile) { ensureLibDirExists(); - fprintf(makefile.fptr, "BINNAME = %s/", libDir); + fprintf(makefile.fptr, "BINNAME = %s/", libDir.c_str()); if (!startsWithLib) { fprintf(makefile.fptr, "lib"); } - fprintf(makefile.fptr, "%s%s\n\n", executableFilename, exeExt); + fprintf(makefile.fptr, "%s%s\n\n", executableFilename.c_str(), exeExt); // // Now that the client and launcher are merged, the server name becomes @@ -803,12 +794,12 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, // from the file name. // if (fMultiLocaleInterop) { - server = astr(executableFilename, "_server"); + server = astr(executableFilename.c_str(), "_server"); fprintf(makefile.fptr, "SERVERNAME = %s\n\n", server); } } else { - fprintf(makefile.fptr, "BINNAME = %s%s\n\n", executableFilename, exeExt); + fprintf(makefile.fptr, "BINNAME = %s%s\n\n", executableFilename.c_str(), exeExt); } // @@ -875,7 +866,7 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, includedirs.c_str(), ccflags.c_str(), // We only need to compute and store dependencies if --savec is used - (saveCDir[0] ? " $(DEPEND_CFLAGS)" : "")); + (!saveCDir.empty() ? " $(DEPEND_CFLAGS)" : "")); // Linker flags for each deliverable. const char* lmode = ""; @@ -901,7 +892,7 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, // Block of code for generating TAGS command, developer convenience. fprintf(makefile.fptr, "TAGS_COMMAND = "); - if (developer && saveCDir[0] && !printCppLineno) { + if (developer && !saveCDir.empty() && !printCppLineno) { fprintf(makefile.fptr, "-@which $(CHPL_TAGS_UTIL) > /dev/null 2>&1 && " "test -f $(CHPL_MAKE_HOME)/runtime/$(CHPL_TAGS_FILE) && " @@ -909,7 +900,7 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, "cp $(CHPL_MAKE_HOME)/runtime/$(CHPL_TAGS_FILE) . && " "$(CHPL_TAGS_UTIL) $(CHPL_TAGS_FLAGS) " "$(CHPL_TAGS_APPEND_FLAG) *.c *.h", - saveCDir); + saveCDir.c_str()); } fprintf(makefile.fptr, "\n\n"); @@ -990,7 +981,7 @@ void codegen_makefile(fileinfo* mainfile, const char** tmpbinname, fprintf(makefile.fptr, "%s\n\n", incpath.c_str()); // We only need to compute and store dependencies if --savec is used - if (saveCDir[0]) { + if (!saveCDir.empty()) { fprintf(makefile.fptr, "DEPENDS = output/*.d\n\n"); fprintf(makefile.fptr, "-include $(DEPENDS)\n"); } @@ -1069,10 +1060,10 @@ bool readArgsFromFile(std::string path, std::vector& args, // Expands variables like $CHPL_HOME in the string void expandInstallationPaths(std::string& s) { - const char* tofix[] = {"$CHPL_RUNTIME_LIB", CHPL_RUNTIME_LIB, - "$CHPL_RUNTIME_INCL", CHPL_RUNTIME_INCL, - "$CHPL_THIRD_PARTY", CHPL_THIRD_PARTY, - "$CHPL_HOME", CHPL_HOME, + const char* tofix[] = {"$CHPL_RUNTIME_LIB", CHPL_RUNTIME_LIB.c_str(), + "$CHPL_RUNTIME_INCL", CHPL_RUNTIME_INCL.c_str(), + "$CHPL_THIRD_PARTY", CHPL_THIRD_PARTY.c_str(), + "$CHPL_HOME", CHPL_HOME.c_str(), NULL}; // For each of the patterns in tofix, find/replace all occurrences. diff --git a/compiler/util/misc.cpp b/compiler/util/misc.cpp index 2f24c32f5d1f..54c92d4caae5 100644 --- a/compiler/util/misc.cpp +++ b/compiler/util/misc.cpp @@ -38,6 +38,7 @@ #include #include +#include #include static const char* help_url = "https://chapel-lang.org/bugs.html"; @@ -160,11 +161,10 @@ bool requireOutlinedOn() { } const char* cleanFilename(const char* name) { - static int chplHomeLen = strlen(CHPL_HOME); - const char* retval = NULL; + const char* retval = NULL; - if (strncmp(name, CHPL_HOME, chplHomeLen) == 0) { - retval = astr("$CHPL_HOME", name + chplHomeLen); + if (std::string_view(name).compare(0, CHPL_HOME.length(), CHPL_HOME) == 0) { + retval = astr("$CHPL_HOME", name + CHPL_HOME.length()); } else { retval = name; } diff --git a/compiler/util/stringutil.cpp b/compiler/util/stringutil.cpp index 0748ef0b039d..3be4eea34a76 100644 --- a/compiler/util/stringutil.cpp +++ b/compiler/util/stringutil.cpp @@ -56,6 +56,11 @@ const char* astr(const std::string& s) { return astr(s.c_str()); } +const char* astr(std::string_view s) +{ + // Make a std::string copy of the string_view to guarantee null termination. + return astr(std::string(s)); +} const char* astr(UniqueString s) { return s.astr(gContext);