예제 #1
0
void FileLocator::addPathFromFile(const char* fileName)
	{
	/* Find the final '/': */
	const char* slashPtr=findLastOf(fileName,'/');
	if(slashPtr!=0)
		{
		/* Add the file's directory to the search path list: */
		addPath(fileName,slashPtr);
		}
	else
		{
		/* Add the current directory to the search path list: */
		pathList.push_back(getCurrentDirectory());
		}
	}
예제 #2
0
void FileLocator::addPathFromApplication(const char* executablePath)
	{
	/* Separate the executable name from the executable path: */
	const char* slashPtr=findLastOf(executablePath,'/');
	std::string appName=slashPtr!=0?std::string(slashPtr+1):std::string(executablePath);
	
	/* Add the standard resource search path for private installed applications: */
	if(getenv("HOME")!=0)
		{
		std::string path=getenv("HOME");
		path.append("/.");
		path.append(appName);
		addPath(path);
		}
	
	/* Add the standard resource search paths for system-wide installed applications: */
	addPath("/usr/share/"+appName);
	addPath("/usr/local/share/"+appName);
	
	/* Construct the fully-qualified executable name: */
	std::string fullExePath;
	if(executablePath[0]=='/')
		fullExePath=executablePath;
	else
		{
		/* Try to find the full path to the executable: */
		#if 0
		/* Get the full executable path through the /proc interface: */
		char pse[PATH_MAX];
		int pseLength=readlink("/proc/self/exe",pse,PATH_MAX);
		if(pseLength>=0)
			fullExePath=std::string(pse,pse+pseLength);
		else
			{
		#else
		/* Search for the executable just as the shell did: */
		if(slashPtr==0&&getenv("PATH")!=0)
			{
			/* Search for the executable in the PATH list: */
			const char* pathBegin=getenv("PATH");
			while(*pathBegin!='\0')
				{
				/* Find the end of the next path: */
				const char* pathEnd;
				for(pathEnd=pathBegin;*pathEnd!='\0'&&*pathEnd!=':';++pathEnd)
					;
				
				/* Test the path if it is non-empty: */
				if(pathEnd!=pathBegin)
					{
					/* Construct the full path name: */
					std::string testName;
					if(*pathBegin!='/')
						{
						/* Start the path name with the current directory: */
						testName=getCurrentDirectory();
						testName.push_back('/');
						}
					testName.append(pathBegin,pathEnd);
					testName.push_back('/');
					testName.append(appName);
					
					/* Test if the file exists and is an executable: */
					if(Misc::isPathFile(testName.c_str()))
						{
						/* Save the matching full path and stop searching: */
						fullExePath=testName;
						break;
						}
					}
				
				/* Go to the next path: */
				if(*pathEnd!='\0')
					++pathEnd;
				pathBegin=pathEnd;
				}
			}
		else
			{
			/* Use the provided path starting at the current directory: */
			fullExePath=getCurrentDirectory();
			fullExePath.push_back('/');
			fullExePath.append(executablePath);
			}
		#endif
		#if 0
			}
		#endif
		}
	
	/* Find the last slash in the cleaned fully-qualified executable path name: */
	std::string cleanFullExePath=cleanPath(fullExePath.c_str());
	executablePath=cleanFullExePath.c_str();
	slashPtr=findLastOf(executablePath,'/');
	
	#ifdef __linux__
	/* Check if the executable is part of a Linux application bundle: */
	if(slashPtr!=0)
		{
		if(slashPtr-executablePath>=4&&strncasecmp(slashPtr-4,"/exe",4)==0)
			{
			/* Add the bundle's base directory to the search path list: */
			addPath(executablePath,slashPtr-4);
			}
		else if(slashPtr-executablePath>=7&&strncasecmp(slashPtr-7,"/exe/64",7)==0)
			{
			/* Add the bundle's base directory to the search path list: */
			addPath(executablePath,slashPtr-7);
			}
		}
	#endif
	
	#ifdef __APPLE__
	/* Check if the executable is part of a Mac OS X application bundle: */
	if(slashPtr!=0&&slashPtr-executablePath>=19&&strncasecmp(slashPtr-19,".app/Contents/MacOS",19)==0)
		{
		/* Add the bundle's resource directory to the search path list: */
		addPath(std::string(executablePath,slashPtr-5)+"Resources");
		}
	#endif
	}
예제 #3
0
void Logfile::writeLine(const String& caller, const UnicodeString& lineContent, OutputType type, bool writeTimestamp)
{
    auto lock = ScopedMutexLock(m->mutex);

    m->currentOutputType = type;

    // Open div for this output type
    *this << "<div class='";
    if (type == Info)
        *this << "info";
    else if (type == Debug)
        *this << "debug";
    else if (type == Warning)
        *this << "warning";
    else if (type == Error)
        *this << "error";
    else if (type == Console)
        *this << "console";
    *this << "'>";

    m->isHookingEnabled = true;

    if (writeTimestamp)
        *this << "[" << FileSystem::getShortDateTime() << "] ";

    // Add the prefix for this output type
    if (type == Warning)
        *this << "Warning: ";
    else if (type == Error)
        *this << "Error: ";

    if (caller.length())
    {
        // Format the result of CARBON_CURRENT_FUNCTION in a consistent way across all platforms.
        // CARBON_CURRENT_FUNCTION uses either __FUNCTION__ or __PRETTY_FUNCTION__ depending on the compiler. Aim for a
        // string in the format Class::Method() regardless of which macro the name originated from.

        auto formattedCaller = caller;

        // Cut off everything after the final ')'
        auto index = formattedCaller.findLastOf(")");
        if (index != -1)
        {
            formattedCaller = formattedCaller.substr(0, index + 1);

            // Cut out all the parameter type information. Parentheses need to be counted to determine where the
            // parameter type information stops because function pointer parameters will have parentheses in them.
            auto parenthesisCount = 0;
            for (auto i = int(formattedCaller.length()) - 1; i >= 0; i--)
            {
                if (formattedCaller.at(i) == ')')
                    parenthesisCount++;
                else if (formattedCaller.at(i) == '(')
                {
                    parenthesisCount--;
                    if (parenthesisCount <= 0)
                    {
                        formattedCaller = formattedCaller.substr(0, i);
                        break;
                    }
                }
            }
        }

        // Cut out the return type information if present
        index = formattedCaller.findLastOf(String::Space);
        if (index != -1)
        {
            formattedCaller = formattedCaller.substr(index + 1);
            formattedCaller.trimLeft("*&");
        }

        *this << formattedCaller.withoutPrefix("Carbon::") << "() - ";
    }

    *this << lineContent << UnicodeString::Newline;

    m->isHookingEnabled = false;

    *this << "</div>";

#ifdef CARBON_DEBUG
    // Trigger assertions on warnings/errors if enabled
    if (type == Warning && AssertOnWarnings)
        assert(false && "Asserting because a warning was reported");
    else if (type == Error && AssertOnErrors)
        assert(false && "Asserting because an error was reported");
#endif
}