Ejemplo n.º 1
0
string_view path::__parent_path() const
{
    if (empty() || pbegin(*this) == --pend(*this)) {
        return {};
    }
    auto end_it = --(--pend(*this));
    auto end_i = parser::end_of(__pn_, end_it.__pos_);
    return string_view(__pn_).substr(0, end_i+1);
}
Ejemplo n.º 2
0
	inline string_view to_string( inclusion_style i ) {
		switch ( i ) {
		case inclusion_style::angle_bracket:
			return "angle bracket";
		case inclusion_style::quote:
			return "quote";
		}
		return string_view();
	}
Ejemplo n.º 3
0
string Panel::GetTitle() const
{
	if (m_PanelMode == panel_mode::NORMAL_PANEL)
		return m_ShowShortNames? ConvertNameToShort(m_CurDir) : m_CurDir;

	OpenPanelInfo Info;
	GetOpenPanelInfo(&Info);
	return string(trim(string_view(NullToEmpty(Info.PanelTitle))));
}
Ejemplo n.º 4
0
int DialogBuilder::AddTextWrap(const wchar_t *text, bool center, int width)
{
	int LineCount = 0;
	for(const auto& i: wrapped_text(string_view(text), width <= 0? ScrX - 1 - 10 : width))
	{
		const auto Text = AddText(null_terminated(i).c_str());
		Text->Flags = center? DIF_CENTERTEXT : 0;
		++LineCount;
	}

	return LineCount;
}
Ejemplo n.º 5
0
static string_view_t
signature_tail(string_view_t str)
{
	string_view_t tail = str;

	const char * p = find_next_arrow(str);
	if (p == NULL)
		return string_view();

	tail.begin = p+1;
	return tail;
}
Ejemplo n.º 6
0
string Panel::CreateFullPathName(string_view const Name, bool const Directory, bool const UNC, bool const ShortNameAsIs) const
{
	auto FullName = FindSlash(Name) == string::npos? ConvertNameToFull(Name) : string(Name);

	if (m_ShowShortNames && ShortNameAsIs)
		FullName = ConvertNameToShort(FullName);

	/* $ 29.01.2001 VVM
	  + По CTRL+ALT+F в командную строку сбрасывается UNC-имя текущего файла. */
	if (UNC)
		FullName = ConvertNameToUNC(FullName);

	// $ 20.10.2000 SVS Сделаем фичу Ctrl-F опциональной!
	if (Global->Opt->PanelCtrlFRule)
	{
		/* $ 13.10.2000 tran
		  по Ctrl-f имя должно отвечать условиям на панели */
		if (m_ViewSettings.Flags&PVS_FOLDERUPPERCASE)
		{
			if (Directory)
			{
				inplace::upper(FullName);
			}
			else
			{
				inplace::upper(FullName, 0, FindLastSlash(FullName));
			}
		}

		if ((m_ViewSettings.Flags&PVS_FILEUPPERTOLOWERCASE) && !Directory)
		{
			const auto pos = FindLastSlash(FullName);
			if (pos != string::npos && !IsCaseMixed(string_view(FullName).substr(pos)))
			{
				inplace::lower(FullName, pos);
			}
		}

		if ((m_ViewSettings.Flags&PVS_FILELOWERCASE) && !Directory)
		{
			const auto pos = FindLastSlash(FullName);
			if (pos != string::npos)
			{
				inplace::lower(FullName, pos);
			}
		}
	}

	return FullName;
}
Ejemplo n.º 7
0
string_view path::__relative_path() const
{
    if (empty()) {
        return {__pn_};
    }
    auto end_i = parser::root_directory_end(__pn_);
    if (not parser::good(end_i)) {
        end_i = parser::root_name_end(__pn_);
    }
    if (not parser::good(end_i)) {
        return {__pn_};
    }
    return string_view(__pn_).substr(end_i+1);
}
Ejemplo n.º 8
0
string ConvertNameToUNC(string_view const Object)
{
	auto strFileName = ConvertNameToFull(Object);
	// Посмотрим на тип файловой системы
	string strFileSystemName;
	os::fs::GetVolumeInformation(GetPathRoot(strFileName), nullptr, nullptr, nullptr, nullptr, &strFileSystemName);

	DWORD uniSize = 1024;
	block_ptr<UNIVERSAL_NAME_INFO> uni(uniSize);

	// применяем WNetGetUniversalName для чего угодно, только не для Novell`а
	if (!equal_icase(strFileSystemName, L"NWFS"sv))
	{
		switch (WNetGetUniversalName(strFileName.c_str(), UNIVERSAL_NAME_INFO_LEVEL, uni.get(), &uniSize))
		{
			case NO_ERROR:
				strFileName = uni->lpUniversalName;
				break;

			case ERROR_MORE_DATA:
				uni.reset(uniSize);
				if (WNetGetUniversalName(strFileName.c_str(),UNIVERSAL_NAME_INFO_LEVEL,uni.get(),&uniSize)==NO_ERROR)
					strFileName = uni->lpUniversalName;
				break;
		}
	}
	else if (strFileName.size() > 1 && strFileName[1] == L':')
	{
		// BugZ#449 - Неверная работа CtrlAltF с ресурсами Novell DS
		// Здесь, если не получилось получить UniversalName и если это
		// мапленный диск - получаем как для меню выбора дисков
		string strTemp;
		if (DriveLocalToRemoteName(DRIVE_UNKNOWN,strFileName[0],strTemp))
		{
			const auto SlashPos = FindSlash(strFileName);
			if (SlashPos != string::npos)
				path::append(strTemp, string_view(strFileName).substr(SlashPos + 1));

			strFileName = strTemp;
		}
	}

	return ConvertNameToReal(strFileName);
}
Ejemplo n.º 9
0
/*
  Преобразует Src в полный РЕАЛЬНЫЙ путь с учетом reparse point.
  Note that Src can be partially non-existent.
*/
string ConvertNameToReal(string_view const Object)
{
	SCOPED_ACTION(elevation::suppress);

	// Получим сначала полный путь до объекта обычным способом
	const auto FullPath = ConvertNameToFull(Object);
	auto strDest = FullPath;

	string Path = FullPath;
	os::fs::file File;

	for (;;)
	{
		if (File.Open(Path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING))
			break;

		if (IsRootPath(Path))
			break;

		Path = ExtractFilePath(Path);
	}

	if (File)
	{
		string FinalFilePath;
		File.GetFinalPathName(FinalFilePath);
		File.Close();

		//assert(!FinalFilePath.empty());

		if (!FinalFilePath.empty())
		{
			// append non-existent path part (if present)
			DeleteEndSlash(Path);

			if (FullPath.size() > Path.size() + 1)
				path::append(FinalFilePath, string_view(FullPath).substr(Path.size() + 1));

			FinalFilePath = TryConvertVolumeGuidToDrivePath(FinalFilePath);
			strDest = FinalFilePath;
		}
	}
	return strDest;
}
Ejemplo n.º 10
0
int main()
{
	{
		string_view_t f0 =  string_view();
		string_view_t f1 =  make_string_view("");
		string_view_t f2 =  make_string_view("CInt");
		string_view_t f3 =  make_string_view("  CInt   ");
		string_view_t f4 =  make_string_view("CInt   ");
		string_view_t f5 =  make_string_view("   CInt   ");
		string_view_t f6 =  make_string_view("Action SkBuff");
		string_view_t f7 =  make_string_view("   Action   SkBuff");
		string_view_t f8 =  make_string_view("   Action   SkBuff    ");
		string_view_t f9 =  make_string_view("Action   SkBuff    ");

		assert(compare_argument(f0, f0) == true);
		assert(compare_argument(f1, f0) == true);
		assert(compare_argument(f0, f1) == true);

		assert(compare_argument(f2, f2) == true);
		assert(compare_argument(f2, f3) == true);
		assert(compare_argument(f2, f4) == true);
		assert(compare_argument(f2, f5) == true);

		assert(compare_argument(f3, f3) == true);
		assert(compare_argument(f3, f4) == true);
		assert(compare_argument(f3, f5) == true);

		assert(compare_argument(f4, f4) == true);
		assert(compare_argument(f4, f5) == true);

		assert(compare_argument(f5, f5) == true);

		assert(compare_argument(f6, f6) == true);
		assert(compare_argument(f6, f7) == true);
		assert(compare_argument(f6, f8) == true);
		assert(compare_argument(f6, f9) == true);

		assert(compare_argument(f7, f7) == true);
		assert(compare_argument(f7, f8) == true);
		assert(compare_argument(f7, f9) == true);

		assert(compare_argument(f8, f8) == true);
		assert(compare_argument(f8, f9) == true);

		assert(compare_argument(f9, f9) == true);

		assert(compare_argument(f0, f2) == false);
		assert(compare_argument(f0, f3) == false);
		assert(compare_argument(f0, f4) == false);
		assert(compare_argument(f0, f5) == false);
		assert(compare_argument(f0, f6) == false);
		assert(compare_argument(f0, f7) == false);
		assert(compare_argument(f0, f8) == false);
		assert(compare_argument(f0, f9) == false);

	}

	{
		string_view_t f0 =  string_view();
		string_view_t f1 =  make_string_view("");
		string_view_t f2 =  make_string_view("CInt");
		string_view_t f3 =  make_string_view("  CInt   ");
		string_view_t f4 =  make_string_view("CInt   ");
		string_view_t f5 =  make_string_view("   CInt   ");
		string_view_t f6 =  make_string_view("Action SkBuff");
		string_view_t f7 =  make_string_view("   Action   SkBuff");
		string_view_t f8 =  make_string_view("   Action   SkBuff    ");
		string_view_t f9 =  make_string_view("Action   SkBuff    ");

		string_view_t f10 =  string_view();
		string_view_t f11 =  make_string_view("");
		string_view_t f12 =  make_string_view("CInt");
		string_view_t f13 =  make_string_view("  CInt  -> CInt  ");
		string_view_t f14 =  make_string_view("CInt -> (CInt)  ");
		string_view_t f15 =  make_string_view("   CInt   ");
		string_view_t f16 =  make_string_view("Action SkBuff -> ( (CInt ) )");
		string_view_t f17 =  make_string_view("   Action   SkBuff");
		string_view_t f18 =  make_string_view("   Action   SkBuff    ");
		string_view_t f19 =  make_string_view("Action   SkBuff    ");

		assert(count_outmost_brackets(f0) == 0);
		assert(count_outmost_brackets(f1) == 0);
		assert(count_outmost_brackets(f2) == 0);
		assert(count_outmost_brackets(f3) == 0);
		assert(count_outmost_brackets(f4) == 0);
		assert(count_outmost_brackets(f5) == 0);
		assert(count_outmost_brackets(f6) == 0);
		assert(count_outmost_brackets(f7) == 0);
		assert(count_outmost_brackets(f8) == 0);
		assert(count_outmost_brackets(f9) == 0);

		assert(count_outmost_brackets(f10) == 0);
		assert(count_outmost_brackets(f11) == 0);
		assert(count_outmost_brackets(f12) == 0);
		assert(count_outmost_brackets(f13) == 0);
		assert(count_outmost_brackets(f14) == 0);
		assert(count_outmost_brackets(f15) == 0);
		assert(count_outmost_brackets(f16) == 0);
		assert(count_outmost_brackets(f17) == 0);
		assert(count_outmost_brackets(f18) == 0);
		assert(count_outmost_brackets(f19) == 0);

	}

	{
		string_view_t g1 =  make_string_view("()");
		string_view_t g2 =  make_string_view("(CInt)");
		string_view_t g3 =  make_string_view("(  CInt   )");
		string_view_t g4 =  make_string_view("(CInt  )");
		string_view_t g5 =  make_string_view("(   CInt )  ");
		string_view_t g6 =  make_string_view("(Action SkBuff)");
		string_view_t g7 =  make_string_view("(  Action   SkBuff)");
		string_view_t g8 =  make_string_view("(   Action   SkBuff    )");
		string_view_t g9 =  make_string_view("(Action   SkBuff    )");

		assert(count_outmost_brackets(g1) == 1);
		assert(count_outmost_brackets(g2) == 1);
		assert(count_outmost_brackets(g3) == 1);
		assert(count_outmost_brackets(g4) == 1);
		assert(count_outmost_brackets(g5) == 1);
		assert(count_outmost_brackets(g6) == 1);
		assert(count_outmost_brackets(g7) == 1);
		assert(count_outmost_brackets(g8) == 1);
		assert(count_outmost_brackets(g9) == 1);
	}

	{
		string_view_t g1 =  make_string_view("(CInt) -> Bool");
		string_view_t g2 =  make_string_view("(  CInt   )-> Char");
		string_view_t g3 =  make_string_view("(CInt  ) ->Char");
		string_view_t g4 =  make_string_view("(   CInt )  ->(Char)");
		string_view_t g5 =  make_string_view("(Action SkBuff) ->   ( (Char))");
		string_view_t g6 =  make_string_view("(  Action   SkBuff)-> Char");
		string_view_t g7 =  make_string_view("(   Action   SkBuff    ) ->(Char)");
		string_view_t g8 =  make_string_view("(Action   SkBuff    )    -> ((  Char ))");

		assert(count_outmost_brackets(g1) == 0);
		assert(count_outmost_brackets(g2) == 0);
		assert(count_outmost_brackets(g3) == 0);
		assert(count_outmost_brackets(g4) == 0);
		assert(count_outmost_brackets(g5) == 0);
		assert(count_outmost_brackets(g6) == 0);
		assert(count_outmost_brackets(g7) == 0);
		assert(count_outmost_brackets(g8) == 0);
	}


	{
		string_view_t g1 =  make_string_view("((CInt) -> Bool)");
		string_view_t g2 =  make_string_view("((  CInt   )-> Char)");
		string_view_t g3 =  make_string_view("((CInt  ) ->Char  )");
		string_view_t g4 =  make_string_view("((   CInt )  ->(Char))");
		string_view_t g5 =  make_string_view("((Action SkBuff) ->   ( (Char)))");
		string_view_t g6 =  make_string_view("((  Action   SkBuff)-> Char)");
		string_view_t g7 =  make_string_view("((   Action   SkBuff    ) ->(Char))");
		string_view_t g8 =  make_string_view("((Action   SkBuff    )    -> ((  Char )))");

		assert(count_outmost_brackets(g1) == 1);
		assert(count_outmost_brackets(g2) == 1);
		assert(count_outmost_brackets(g3) == 1);
		assert(count_outmost_brackets(g4) == 1);
		assert(count_outmost_brackets(g5) == 1);
		assert(count_outmost_brackets(g6) == 1);
		assert(count_outmost_brackets(g7) == 1);
		assert(count_outmost_brackets(g8) == 1);
	}

	{
		string_view_t g1 =  make_string_view("(((CInt) -> Bool))");
		string_view_t g2 =  make_string_view("( ((  CInt   )-> Char) )");
		string_view_t g3 =  make_string_view("(  ((CInt  ) ->Char  ))");
		string_view_t g4 =  make_string_view("(( (   CInt )  ->(Char)) )");
		string_view_t g5 =  make_string_view("( ((Action SkBuff) ->   ( (Char))))");
		string_view_t g6 =  make_string_view("(((  Action   SkBuff)-> Char))");
		string_view_t g7 =  make_string_view("((  (   Action   SkBuff    ) ->(Char)) )");
		string_view_t g8 =  make_string_view("( ((Action   SkBuff    )    -> ((  Char ) )) )");

		assert(count_outmost_brackets(g1) == 2);
		assert(count_outmost_brackets(g2) == 2);
		assert(count_outmost_brackets(g3) == 2);
		assert(count_outmost_brackets(g4) == 2);
		assert(count_outmost_brackets(g5) == 2);
		assert(count_outmost_brackets(g6) == 2);
		assert(count_outmost_brackets(g7) == 2);
		assert(count_outmost_brackets(g8) == 2);
	}

	{
		string_view_t f0 =  string_view();
		string_view_t f1 =  make_string_view("");
		string_view_t f2 =  make_string_view("CInt");
		string_view_t f3 =  make_string_view("  CInt   ");
		string_view_t f4 =  make_string_view("CInt   ");
		string_view_t f5 =  make_string_view("   CInt   ");
		string_view_t f6 =  make_string_view("Action SkBuff");
		string_view_t f7 =  make_string_view("   Action   SkBuff");
		string_view_t f8 =  make_string_view("   Action   SkBuff    ");
		string_view_t f9 =  make_string_view("Action   SkBuff    ");
		string_view_t f10 =  make_string_view("(CInt) -> Bool");
		string_view_t f11 =  make_string_view("(  CInt   )-> Char");
		string_view_t f12 =  make_string_view("(CInt  ) ->Char");
		string_view_t f13 =  make_string_view("(   CInt )  ->(Char)");
		string_view_t f14 =  make_string_view("(Action SkBuff) ->   ( (Char))");
		string_view_t f15 =  make_string_view("(  Action   SkBuff)-> Char");
		string_view_t f16 =  make_string_view("(   Action   SkBuff    ) ->(Char)");
		string_view_t f17 =  make_string_view("(Action   SkBuff    )    -> ((  Char ))");


		assert(find_next_arrow(f0) == NULL);
		assert(find_next_arrow(f1) == NULL);
		assert(find_next_arrow(f2) == NULL);
		assert(find_next_arrow(f3) == NULL);
		assert(find_next_arrow(f4) == NULL);
		assert(find_next_arrow(f5) == NULL);
		assert(find_next_arrow(f6) == NULL);
		assert(find_next_arrow(f7) == NULL);
		assert(find_next_arrow(f8) == NULL);
		assert(find_next_arrow(f9) == NULL);
		assert(find_next_arrow(f10) != NULL);
		assert(find_next_arrow(f11) != NULL);
		assert(find_next_arrow(f12) != NULL);
		assert(find_next_arrow(f13) != NULL);
		assert(find_next_arrow(f14) != NULL);
		assert(find_next_arrow(f15) != NULL);
		assert(find_next_arrow(f16) != NULL);
		assert(find_next_arrow(f17) != NULL);
	}

	printf("All test passed.\n");
	return 0;
}
Ejemplo n.º 11
0
// try to replace volume GUID (if present) with drive letter
// used by ConvertNameToReal() only
static string TryConvertVolumeGuidToDrivePath(string_view const Path, const string_view AbsPath = {})
{
	string Result(Path);
	size_t DirectoryOffset;
	if (ParsePath(Path, &DirectoryOffset) == root_type::volume)
	{
		if (imports.GetVolumePathNamesForVolumeNameW)
		{
			string VolumePathNames;
			if (os::fs::GetVolumePathNamesForVolumeName(ExtractPathRoot(Path), VolumePathNames))
			{
				for(const auto& i: enum_substrings(VolumePathNames.c_str()))
				{
					if (!AbsPath.empty() && starts_with_icase(AbsPath, i))
						return string(i);

					if (IsRootPath(i))
					{
						Result.replace(0, DirectoryOffset, i.data(), i.size());
						break;
					}
				}
			}

			if (!AbsPath.empty())
				Result.clear();
		}

		else if (!AbsPath.empty())
			Result.clear();

		else
		{
			string strVolumeGuid;
			const os::fs::enum_drives Enumerator(os::fs::get_logical_drives());
			const auto ItemIterator = std::find_if(ALL_CONST_RANGE(Enumerator), [&](const auto& i)
			{
				return os::fs::GetVolumeNameForVolumeMountPoint(os::fs::get_root_directory(i), strVolumeGuid) && starts_with(Path, string_view(strVolumeGuid).substr(0, DirectoryOffset));
			});
			if (ItemIterator != Enumerator.cend())
			{
				Result.replace(0, DirectoryOffset, os::fs::get_drive(*ItemIterator));
			}
		}
	}

	else if (!AbsPath.empty())
		Result.clear();

	return Result;
}
Ejemplo n.º 12
0
// Кусок для создания SymLink для каталогов.
int MkSymLink(const string& Target, const string& LinkName, ReparsePointTypes LinkType, bool Silent, bool HoldTarget)
{
	if (!Target.empty() && !LinkName.empty())
	{
		string strFullTarget;
		// выделим имя
		auto strSelOnlyName = Target;
		DeleteEndSlash(strSelOnlyName);
		const auto SlashPos = FindLastSlash(strSelOnlyName);

		const auto symlink = LinkType==RP_SYMLINK || LinkType==RP_SYMLINKFILE || LinkType==RP_SYMLINKDIR;

		if (Target[1] == L':' && (!Target[2] || (IsSlash(Target[2]) && !Target[3]))) // C: или C:/
		{
//      if(Flags&FCOPY_VOLMOUNT)
			{
				strFullTarget = Target;
				AddEndSlash(strFullTarget);
			}
			/*
			  Вот здесь - ну очень умное поведение!
			  Т.е. если в качестве SelName передали "C:", то в этом куске происходит
			  коррекция типа линка - с symlink`а на volmount
			*/
			LinkType=RP_VOLMOUNT;
		}
		else
			strFullTarget = ConvertNameToFull(Target);

		auto strFullLink = ConvertNameToFull(LinkName);

		if (IsSlash(strFullLink.back()))
		{
			if (LinkType != RP_VOLMOUNT)
			{
				const auto SelName = SlashPos != string::npos? string_view(strSelOnlyName).substr(SlashPos + 1) : string_view(strSelOnlyName);
				append(strFullLink, SelName);
			}
			else
			{
				append(strFullLink, L"Disk_"sv, Target.front());
			}
		}

		if (LinkType==RP_VOLMOUNT)
		{
			AddEndSlash(strFullTarget);
			AddEndSlash(strFullLink);
		}

			if (symlink)
			{
				// в этом случае создается путь, но не сам каталог
				string strPath=strFullLink;

				if (CutToSlash(strPath))
				{
					if (!os::fs::exists(strPath))
						CreatePath(strPath);
				}
			}
			else
			{
				bool CreateDir=true;

				if (LinkType==RP_EXACTCOPY)
				{
					// в этом случае создается или каталог, или пустой файл
					if (os::fs::is_file(strFullTarget))
						CreateDir=false;
				}

				if (CreateDir)
				{
					if (os::fs::create_directory(strFullLink))
						TreeList::AddTreeName(strFullLink);
					else
						CreatePath(strFullLink);
				}
				else
				{
					string strPath=strFullLink;

					if (CutToSlash(strPath))
					{
						if (!os::fs::exists(strPath))
							CreatePath(strPath);
						os::fs::file(strFullLink, 0, 0, nullptr, CREATE_NEW, os::fs::get_file_attributes(strFullTarget));
					}
				}

				if (!os::fs::exists(strFullLink))
				{
					if (!Silent)
					{
						const auto ErrorState = error_state::fetch();

						Message(MSG_WARNING, ErrorState,
							msg(lng::MError),
							{
								msg(lng::MCopyCannotCreateLink),
								strFullLink
							},
							{ lng::MOk });
					}

					return 0;
				}
			}

		if (LinkType!=RP_VOLMOUNT)
		{
			if (CreateReparsePoint(HoldTarget && symlink ? Target : strFullTarget, strFullLink, LinkType))
			{
				return 1;
			}
			else
			{
				if (!Silent)
				{
					const auto ErrorState = error_state::fetch();

					Message(MSG_WARNING, ErrorState,
						msg(lng::MError),
						{
							msg(lng::MCopyCannotCreateLink),
							strFullLink
						},
						{ lng::MOk });
				}

				return 0;
			}
		}
		else
		{
			if (CreateVolumeMountPoint(strFullTarget,strFullLink))
			{
				return 1;
			}
			else
			{
				if (!Silent)
				{
					const auto ErrorState = error_state::fetch();

					Message(MSG_WARNING, ErrorState,
						msg(lng::MError),
						{
							format(msg(lng::MCopyMountVolFailed), Target),
							format(msg(lng::MCopyMountVolFailed2), strFullLink)
						},
						{ lng::MOk });
				}

				return 0;
			}
		}
	}

	return 2;
}
Ejemplo n.º 13
0
static string_view ProcessMetasymbol(string_view const CurStr, subst_data& SubstData, string& Out)
{
	const auto append_with_escape = [EscapeAmpersands = SubstData.EscapeAmpersands](string& Destination, string_view const Str)
	{
		if (EscapeAmpersands && contains(Str, L"&"sv))
		{
			string Escaped(Str);
			replace(Escaped, L"&"sv, L"&&"sv);
			append(Destination, Escaped);
		}
		else
		{
			append(Destination, Str);
		}
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::passive_panel))
	{
		SubstData.PassivePanel = true;
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::active_panel))
	{
		SubstData.PassivePanel = false;
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::exclamation))
	{
		if (!starts_with(Tail, L'?'))
		{
			Out.push_back(L'!');
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::name_extension))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Normal.Name);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name))
	{
		append_with_escape(Out, SubstData.Default().Short.NameOnly);
		return Tail;
	}

	const auto GetExtension = [](string_view const Name)
	{
		const auto Extension = PointToExt(Name);
		return Extension.empty()? Extension : Extension.substr(1);
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::short_extension))
	{
		append_with_escape(Out, GetExtension(SubstData.Default().Short.Name));
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::extension))
	{
		append_with_escape(Out, GetExtension(SubstData.Default().Normal.Name));
		return Tail;
	}

	const auto CollectNames = [&SubstData, &append_with_escape](string& Str, auto const Selector)
	{
		append_with_escape(Str, join(select(SubstData.Default().Panel->enum_selected(), Selector), L" "sv));
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::short_list))
	{
		if (!starts_with(Tail, L'?'))
		{
			CollectNames(Out, &os::fs::find_data::AlternateFileName);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::list))
	{
		if (!starts_with(Tail, L'?'))
		{
			CollectNames(Out, [](const os::fs::find_data& Data)
			{
				return quote_space(Data.FileName);
			});

			return Tail;
		}
	}

	const auto GetListName = [&Out, &append_with_escape](string_view const Tail, subst_data& Data, bool Short)
	{
		const auto ExclPos = Tail.find(L'!');
		if (ExclPos == Tail.npos || starts_with(Tail.substr(ExclPos + 1), L'?'))
			return size_t{};

		const auto Modifiers = Tail.substr(0, ExclPos);

		if (Data.ListNames)
		{
			string Str;
			if (Data.Default().Panel->MakeListFile(Str, Short, Modifiers))
			{
				if (Short)
					Str = ConvertNameToShort(Str);

				append_with_escape(Out, Str);
				Data.ListNames->add(std::move(Str));
			}
		}
		else
		{
			append(Out, L'!', Short? L'$' : L'@', Modifiers, L'!');
		}

		return Modifiers.size() + 1;
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::list_file))
	{
		if (const auto Offset = GetListName(Tail, SubstData, false))
			return string_view(Tail).substr(Offset);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_list_file))
	{
		if (const auto Offset = GetListName(Tail, SubstData, true))
			return string_view(Tail).substr(Offset);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name_extension))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Short.Name);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name_extension_safe))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Short.Name);
			SubstData.PreserveLFN = true;
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::current_drive))
	{
		const auto CurDir =
			IsAbsolutePath(SubstData.This.Normal.Name)?
				SubstData.This.Normal.Name :
				SubstData.PassivePanel?
					SubstData.Another.Panel->GetCurDir() :
					SubstData.CmdDir;

		auto RootDir = GetPathRoot(CurDir);
		DeleteEndSlash(RootDir);
		append_with_escape(Out, RootDir);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::description))
	{
		Out += SubstData.Default().GetDescription();
		return Tail;
	}

	const auto GetPath = [](string_view const Tail, const subst_data& Data, bool Short, bool Real)
	{
		// TODO: paths on plugin panels are ambiguous

		auto CurDir = Data.PassivePanel? Data.Another.Panel->GetCurDir() : Data.CmdDir;

		if (Real)
			CurDir = ConvertNameToReal(CurDir);

		if (Short)
			CurDir = ConvertNameToShort(CurDir);

		AddEndSlash(CurDir);
		return CurDir;
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::path))
	{
		Out += GetPath(Tail, SubstData, false, false);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_path))
	{
		Out += GetPath(Tail, SubstData, true, false);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::real_path))
	{
		Out += GetPath(Tail, SubstData, false, true);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::real_short_path))
	{
		Out += GetPath(Tail, SubstData, true, true);
		return Tail;
	}

	// !?<title>?<init>!
	if (const auto Tail = tokens::skip(CurStr, tokens::input))
	{
		auto SkipSize = SkipInputToken(CurStr);
		// if bad format string skip 1 char
		if (!SkipSize)
			SkipSize = 1;

		Out.append(CurStr.data(), SkipSize);
		return CurStr.substr(SkipSize);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::name))
	{
		append(Out, PointToName(SubstData.Default().Normal.NameOnly));
		return Tail;
	}

	return CurStr;
}
Ejemplo n.º 14
0
size_t
TypeDesc::fromstring (const char *typestring)
{
    return fromstring (string_view(typestring));
}
Ejemplo n.º 15
0
		string_view gview() const
		{
			auto const sz = base::egptr() - base::gptr();
			return string_view(base::gptr(), sz);
		}
Ejemplo n.º 16
0
		string_view pview() const
		{
			auto const sz = base::pptr() - base::pbase();
			return string_view(pbase(), sz);
		}
Ejemplo n.º 17
0
tpool::TaskSPtr CxxIwyu::iwyuCommand(const doim::FsDirectorySPtr& directory,
                                     const doim::CxxFileSPtr& cxxFile) const
{
    auto arguments =
        CxxCompiler::includeArguments(directory, cxxFile->cxxIncludeDirectories());
    arguments->insert(CxxCompiler::gStdCpp14Argument);
    arguments->insert(CxxCompiler::gOptimizationLevel0Argument);

    const string& file = cxxFile->file()->path(directory);

    auto argument_file = doim::SysArgument::unique(file);
    arguments->insert(argument_file);
    arguments = doim::SysArgumentSet::unique(arguments);

    auto command = doim::SysCommand::unique(nullptr, mTool, arguments);

    auto fn = [directory, cxxFile](int exit, const string& output) -> ECode {
        if (exit == 0)
        {
            ELOG("Unexpected exit code from iwyu tool: {}", exit);
            EHBan(kUnexpected);
        }

        bool success = true;
        static std::regex removeItemsRegex(
            "(?:^|\n)(.*?) should remove these lines:"
            "(?:[\\s\\r\\n]+- #include.*?\\/\\/ lines \\d+-\\d+)+");
        static std::regex removeItemRegex("- (#include.*?)\\s*\\/\\/ lines (\\d+)-\\d+");

        auto its = std::sregex_iterator(output.begin(), output.end(), removeItemsRegex);
        for (std::sregex_iterator items = its; items != std::sregex_iterator(); ++items)
        {
            std::smatch smatchs = *items;
            const auto& removes = smatchs.str();
            auto it =
                std::sregex_iterator(removes.begin(), removes.end(), removeItemRegex);

            for (std::sregex_iterator item = it; item != std::sregex_iterator(); ++item)
            {
                success = false;
                std::smatch smatch = *item;
                ELOG("\n{}:{}:1: error: extra {} ",
                     smatchs[1].str(),
                     smatch[2].str(),
                     smatch[1].str());
            }
        }

        static std::regex addItemsRegex("(?:^|\n)(.*?) should add these lines:"
                                        "(?:[\\s\\r\\n]+#include.*?\\/\\/[^\\n]*)+");
        static std::regex addItemRegex("(#include\\s[\"<]([^\">]+)[^\\n]+)");

        struct Warning
        {
            std::string erroredFile;
            std::string missingHeader;
        };

        std::vector<Warning> warnings;

        its = std::sregex_iterator(output.begin(), output.end(), addItemsRegex);
        for (std::sregex_iterator items = its; items != std::sregex_iterator(); ++items)
        {
            std::smatch smatchs = *items;
            const auto& adds = smatchs.str();
            auto it = std::sregex_iterator(adds.begin(), adds.end(), addItemRegex);

            for (std::sregex_iterator item = it; item != std::sregex_iterator(); ++item)
            {
                std::smatch smatch = *item;
                warnings.push_back(Warning{smatchs[1].str(), smatch[2].str()});
            }
        }

        for (const auto& warning : warnings)
        {
            auto file = doim::FsFile::find(directory, warning.erroredFile);
            if (file == nullptr)
            {
                success = false;
                ELOG("IWYU reports issues for unknown file {}", warning.erroredFile);
                continue;
            }
            doim::CxxIncludeDirectory::CxxHeaderInfo headerInfo;
            if (cxxFile->file() == file)
            {
                EHLog(doim::CxxIncludeDirectory::findHeaderDeep(
                    string_view(warning.missingHeader),
                    nullptr,
                    cxxFile->cxxIncludeDirectories(),
                    headerInfo));
            }
            else
            {
                EHLog(doim::CxxIncludeDirectory::findHeaderDeep(
                    file, nullptr, cxxFile->cxxIncludeDirectories(), headerInfo));

                if (headerInfo.mHeader == nullptr)
                {
                    success = false;
                    ELOG("IWYU reports issues for unknown file {}", warning.erroredFile);
                    continue;
                }

                EHLog(doim::CxxIncludeDirectory::findHeaderDeep(
                    string_view(warning.missingHeader),
                    headerInfo.mIncludeDirectory,
                    headerInfo.mHeader->cxxIncludeDirectories(),
                    headerInfo));
            }

            if (headerInfo.mHeader == nullptr)
            {
                success = false;
                ELOG("IWYU suggest adding unknown header {}", warning.missingHeader);
                continue;
            }

            if (headerInfo.mHeader->visibility() ==
                doim::CxxHeader::EVisibility::kProtected)
            {
                TLOG("IWYU suggest protected header {}, ignore those",
                     warning.missingHeader);
                continue;
            }

            success = false;
            ELOG("\n{}:1:1: warning: missing {} ",
                 warning.erroredFile,
                 warning.missingHeader);
        }

        if (!success)
        {
            ELOG("\n{}", output);
            EHBan(kFailed);
        }

        EHEnd;
    };

    return task::ParseStdoutTask::valid(
        command, nullptr, rtti::RttiInfo<CxxIwyu>::classId(), fn, "Iwyu " + file);
}
Ejemplo n.º 18
0
bool
JpgInput::open(const std::string& name, ImageSpec& newspec)
{
    m_filename = name;

    if (m_io) {
        // If an IOProxy was passed, it had better be a File or a
        // MemReader, that's all we know how to use with jpeg.
        std::string proxytype = m_io->proxytype();
        if (proxytype != "file" && proxytype != "memreader") {
            errorf("JPEG reader can't handle proxy type %s", proxytype);
            return false;
        }
    } else {
        // If no proxy was supplied, create a file reader
        m_io = new Filesystem::IOFile(name, Filesystem::IOProxy::Mode::Read);
        m_local_io.reset(m_io);
    }
    if (!m_io || m_io->mode() != Filesystem::IOProxy::Mode::Read) {
        errorf("Could not open file \"%s\"", name);
        return false;
    }

    // Check magic number to assure this is a JPEG file
    uint8_t magic[2] = { 0, 0 };
    if (m_io->pread(magic, sizeof(magic), 0) != sizeof(magic)) {
        errorf("Empty file \"%s\"", name);
        close_file();
        return false;
    }

    if (magic[0] != JPEG_MAGIC1 || magic[1] != JPEG_MAGIC2) {
        close_file();
        errorf(
            "\"%s\" is not a JPEG file, magic number doesn't match (was 0x%x%x)",
            name, int(magic[0]), int(magic[1]));
        return false;
    }

    // Set up the normal JPEG error routines, then override error_exit and
    // output_message so we intercept all the errors.
    m_cinfo.err               = jpeg_std_error((jpeg_error_mgr*)&m_jerr);
    m_jerr.pub.error_exit     = my_error_exit;
    m_jerr.pub.output_message = my_output_message;
    if (setjmp(m_jerr.setjmp_buffer)) {
        // Jump to here if there's a libjpeg internal error
        // Prevent memory leaks, see example.c in jpeg distribution
        jpeg_destroy_decompress(&m_cinfo);
        close_file();
        return false;
    }

    // initialize decompressor
    jpeg_create_decompress(&m_cinfo);
    m_decomp_create = true;
    // specify the data source
    if (!strcmp(m_io->proxytype(), "file")) {
        auto fd = ((Filesystem::IOFile*)m_io)->handle();
        jpeg_stdio_src(&m_cinfo, fd);
    } else {
        auto buffer = ((Filesystem::IOMemReader*)m_io)->buffer();
        jpeg_mem_src(&m_cinfo, const_cast<unsigned char*>(buffer.data()),
                     buffer.size());
    }

    // Request saving of EXIF and other special tags for later spelunking
    for (int mark = 0; mark < 16; ++mark)
        jpeg_save_markers(&m_cinfo, JPEG_APP0 + mark, 0xffff);
    jpeg_save_markers(&m_cinfo, JPEG_COM, 0xffff);  // comment marker

    // read the file parameters
    if (jpeg_read_header(&m_cinfo, FALSE) != JPEG_HEADER_OK || m_fatalerr) {
        error("Bad JPEG header for \"%s\"", filename().c_str());
        return false;
    }

    int nchannels = m_cinfo.num_components;

    if (m_cinfo.jpeg_color_space == JCS_CMYK
        || m_cinfo.jpeg_color_space == JCS_YCCK) {
        // CMYK jpegs get converted by us to RGB
        m_cinfo.out_color_space = JCS_CMYK;  // pre-convert YCbCrK->CMYK
        nchannels               = 3;
        m_cmyk                  = true;
    }

    if (m_raw)
        m_coeffs = jpeg_read_coefficients(&m_cinfo);
    else
        jpeg_start_decompress(&m_cinfo);  // start working
    if (m_fatalerr)
        return false;
    m_next_scanline = 0;  // next scanline we'll read

    m_spec = ImageSpec(m_cinfo.output_width, m_cinfo.output_height, nchannels,
                       TypeDesc::UINT8);

    // Assume JPEG is in sRGB unless the Exif or XMP tags say otherwise.
    m_spec.attribute("oiio:ColorSpace", "sRGB");

    if (m_cinfo.jpeg_color_space == JCS_CMYK)
        m_spec.attribute("jpeg:ColorSpace", "CMYK");
    else if (m_cinfo.jpeg_color_space == JCS_YCCK)
        m_spec.attribute("jpeg:ColorSpace", "YCbCrK");

    // If the chroma subsampling is detected and matches something
    // we expect, then set an attribute so that it can be preserved
    // in future operations.
    std::string subsampling = comp_info_to_attr(m_cinfo);
    if (!subsampling.empty())
        m_spec.attribute(JPEG_SUBSAMPLING_ATTR, subsampling);

    for (jpeg_saved_marker_ptr m = m_cinfo.marker_list; m; m = m->next) {
        if (m->marker == (JPEG_APP0 + 1)
            && !strcmp((const char*)m->data, "Exif")) {
            // The block starts with "Exif\0\0", so skip 6 bytes to get
            // to the start of the actual Exif data TIFF directory
            decode_exif(string_view((char*)m->data + 6, m->data_length - 6),
                        m_spec);
        } else if (m->marker == (JPEG_APP0 + 1)
                   && !strcmp((const char*)m->data,
                              "http://ns.adobe.com/xap/1.0/")) {
#ifndef NDEBUG
            std::cerr << "Found APP1 XMP! length " << m->data_length << "\n";
#endif
            std::string xml((const char*)m->data, m->data_length);
            decode_xmp(xml, m_spec);
        } else if (m->marker == (JPEG_APP0 + 13)
                   && !strcmp((const char*)m->data, "Photoshop 3.0"))
            jpeg_decode_iptc((unsigned char*)m->data);
        else if (m->marker == JPEG_COM) {
            if (!m_spec.find_attribute("ImageDescription", TypeDesc::STRING))
                m_spec.attribute("ImageDescription",
                                 std::string((const char*)m->data,
                                             m->data_length));
        }
    }

    // Handle density/pixelaspect. We need to do this AFTER the exif is
    // decoded, in case it contains useful information.
    float xdensity = m_spec.get_float_attribute("XResolution");
    float ydensity = m_spec.get_float_attribute("YResolution");
    if (!xdensity || !ydensity) {
        xdensity = float(m_cinfo.X_density);
        ydensity = float(m_cinfo.Y_density);
        if (xdensity && ydensity) {
            m_spec.attribute("XResolution", xdensity);
            m_spec.attribute("YResolution", ydensity);
        }
    }
    if (xdensity && ydensity) {
        float aspect = ydensity / xdensity;
        if (aspect != 1.0f)
            m_spec.attribute("PixelAspectRatio", aspect);
        switch (m_cinfo.density_unit) {
        case 0: m_spec.attribute("ResolutionUnit", "none"); break;
        case 1: m_spec.attribute("ResolutionUnit", "in"); break;
        case 2: m_spec.attribute("ResolutionUnit", "cm"); break;
        }
    }

    read_icc_profile(&m_cinfo, m_spec);  /// try to read icc profile

    newspec = m_spec;
    return true;
}
Ejemplo n.º 19
0
static void
exif_parser_cb (ImageSpec* spec, int tag, int tifftype, int len,
                unsigned int byteorder, LibRaw_abstract_datastream* ifp)
{
    // Oy, the data offsets are all going to be relative to the start of the
    // stream, not relative to our current position and data block. So we
    // need to remember that offset and pass its negative as the
    // offset_adjustment to the handler.
    size_t streampos = ifp->tell();
    // std::cerr << "Stream position " << streampos << "\n";

    TypeDesc type = tiff_datatype_to_typedesc (TIFFDataType(tifftype), size_t(len));
    const TagInfo* taginfo = tag_lookup ("Exif", tag);
    if (! taginfo) {
        // Strutil::fprintf (std::cerr, "NO TAGINFO FOR CALLBACK tag=%d (0x%x): tifftype=%d,len=%d (%s), byteorder=0x%x\n",
        //                   tag, tag, tifftype, len, type, byteorder);
        return;
    }
    if (type.size() >= (1<<20))
        return;   // sanity check -- too much memory
    size_t size = tiff_data_size(TIFFDataType(tifftype)) * len;
    std::vector<unsigned char> buf (size);
    ifp->read (buf.data(), size, 1);

    // debug scaffolding
    // Strutil::fprintf (std::cerr, "CALLBACK tag=%s: tifftype=%d,len=%d (%s), byteorder=0x%x\n",
    //                   taginfo->name, tifftype, len, type, byteorder);
    // for (int i = 0; i < std::min(16UL,size); ++i) {
    //     if (buf[i] >= ' ' && buf[i] < 128)
    //         std::cerr << char(buf[i]);
    //     Strutil::fprintf (std::cerr, "(%d) ", int(buf[i]));
    // }
    // std::cerr << "\n";

    bool swab = (littleendian() != (byteorder == 0x4949));
    if (swab) {
        if (type.basetype == TypeDesc::UINT16)
            swap_endian ((uint16_t *)buf.data(), len);
        if (type.basetype == TypeDesc::UINT32)
            swap_endian ((uint32_t *)buf.data(), len);
    }

    if (taginfo->handler) {
        TIFFDirEntry dir;
        dir.tdir_tag = uint16_t(tag);
        dir.tdir_type = uint16_t(tifftype);
        dir.tdir_count = uint32_t(len);
        dir.tdir_offset = 0;
        taginfo->handler (*taginfo, dir, buf, *spec, swab, -int(streampos));
        // std::cerr << "HANDLED " << taginfo->name << "\n";
        return;
    }
    if (taginfo->tifftype == TIFF_NOTYPE)
        return;   // skip
    if (tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) {
        spec->attribute (taginfo->name, type, buf.data());
        return;
    }
    if (type.basetype == TypeDesc::UINT16) {
        spec->attribute (taginfo->name, type, buf.data());
        return;
    }
    if (type.basetype == TypeDesc::UINT32) {
        spec->attribute (taginfo->name, type, buf.data());
        return;
    }
    if (type == TypeString) {
        spec->attribute (taginfo->name, string_view((char*)buf.data(), size));
        return;
    }
    // Strutil::fprintf (std::cerr, "RAW metadata NOT HANDLED: tag=%s: tifftype=%d,len=%d (%s), byteorder=0x%x\n",
    //                   taginfo->name, tifftype, len, type, byteorder);
}