func appendPathToLibrariesFolders(librariesFolders []string, newLibrariesFolder string) []string {
	if stat, err := os.Stat(newLibrariesFolder); os.IsNotExist(err) || !stat.IsDir() {
		return librariesFolders
	}

	return utils.AppendIfNotPresent(librariesFolders, newLibrariesFolder)
}
func (s *IncludesFinderWithRegExp) Run(ctx *types.Context) error {
	source := *s.Source

	matches := INCLUDE_REGEXP.FindAllStringSubmatch(source, -1)
	includes := []string{}
	for _, match := range matches {
		includes = append(includes, strings.TrimSpace(match[1]))
	}
	if len(includes) == 0 {
		include := findIncludesForOldCompilers(source)
		if include != "" {
			includes = append(includes, include)
		}
	}

	ctx.IncludesJustFound = includes
	ctx.Includes = utils.AppendIfNotPresent(ctx.Includes, includes...)
	return nil
}
func (s *GCCMinusMOutputParser) Run(ctx *types.Context) error {
	output := ctx.OutputGccMinusM

	rows := strings.Split(output, "\n")
	includes := make([]string, 0)
	if len(rows) > 2 {
		for _, row := range rows[2:] {
			if !strings.HasPrefix(row, " ") {
				row = strings.TrimSpace(row)
				if row != "" {
					row = strings.TrimSuffix(row, ":")
					row = strings.Replace(row, "\\ ", " ", -1)
					includes = append(includes, row)
				}
			}
		}
	}

	ctx.Includes = utils.AppendIfNotPresent(ctx.Includes, includes...)

	return nil
}
func (s *LibrariesLoader) Run(context map[string]interface{}) error {
	sortedLibrariesFolders := []string{}

	builtInLibrariesFolders := []string{}
	if utils.MapHas(context, constants.CTX_BUILT_IN_LIBRARIES_FOLDERS) {
		builtInLibrariesFolders = context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS].([]string)
	}
	builtInLibrariesFolders, err := utils.AbsolutizePaths(builtInLibrariesFolders)
	if err != nil {
		return utils.WrapError(err)
	}
	sortedLibrariesFolders = utils.AppendIfNotPresent(sortedLibrariesFolders, builtInLibrariesFolders...)

	platform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform)
	debugLevel := utils.DebugLevel(context)
	logger := context[constants.CTX_LOGGER].(i18n.Logger)

	actualPlatform := context[constants.CTX_ACTUAL_PLATFORM].(*types.Platform)
	if actualPlatform != platform {
		sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(actualPlatform.Folder, constants.FOLDER_LIBRARIES))
	}

	sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(platform.Folder, constants.FOLDER_LIBRARIES))

	librariesFolders := []string{}
	if utils.MapHas(context, constants.CTX_OTHER_LIBRARIES_FOLDERS) {
		librariesFolders = context[constants.CTX_OTHER_LIBRARIES_FOLDERS].([]string)
	}
	librariesFolders, err = utils.AbsolutizePaths(librariesFolders)
	if err != nil {
		return utils.WrapError(err)
	}
	sortedLibrariesFolders = utils.AppendIfNotPresent(sortedLibrariesFolders, librariesFolders...)

	context[constants.CTX_LIBRARIES_FOLDERS] = sortedLibrariesFolders

	var libraries []*types.Library
	for _, libraryFolder := range sortedLibrariesFolders {
		subFolders, err := utils.ReadDirFiltered(libraryFolder, utils.FilterDirs)
		if err != nil {
			return utils.WrapError(err)
		}
		for _, subFolder := range subFolders {
			library, err := makeLibrary(filepath.Join(libraryFolder, subFolder.Name()), debugLevel, logger)
			if err != nil {
				return utils.WrapError(err)
			}
			libraries = append(libraries, library)
		}
	}

	context[constants.CTX_LIBRARIES] = libraries

	headerToLibraries := make(map[string][]*types.Library)
	for _, library := range libraries {
		headers, err := utils.ReadDirFiltered(library.SrcFolder, utils.FilterFilesWithExtension(".h"))
		if err != nil {
			return utils.WrapError(err)
		}
		for _, header := range headers {
			headerFileName := header.Name()
			headerToLibraries[headerFileName] = append(headerToLibraries[headerFileName], library)
		}
	}

	context[constants.CTX_HEADER_TO_LIBRARIES] = headerToLibraries

	return nil
}
func (s *LibrariesLoader) Run(ctx *types.Context) error {
	builtInLibrariesFolders := ctx.BuiltInLibrariesFolders
	builtInLibrariesFolders, err := utils.AbsolutizePaths(builtInLibrariesFolders)
	if err != nil {
		return i18n.WrapError(err)
	}
	sortedLibrariesFolders := []string{}
	sortedLibrariesFolders = utils.AppendIfNotPresent(sortedLibrariesFolders, builtInLibrariesFolders...)

	platform := ctx.TargetPlatform
	debugLevel := ctx.DebugLevel
	logger := ctx.GetLogger()

	actualPlatform := ctx.ActualPlatform
	if actualPlatform != platform {
		sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(actualPlatform.Folder, constants.FOLDER_LIBRARIES))
	}

	sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(platform.Folder, constants.FOLDER_LIBRARIES))

	librariesFolders := ctx.OtherLibrariesFolders
	librariesFolders, err = utils.AbsolutizePaths(librariesFolders)
	if err != nil {
		return i18n.WrapError(err)
	}
	sortedLibrariesFolders = utils.AppendIfNotPresent(sortedLibrariesFolders, librariesFolders...)

	ctx.LibrariesFolders = sortedLibrariesFolders

	var libraries []*types.Library
	for _, libraryFolder := range sortedLibrariesFolders {
		subFolders, err := utils.ReadDirFiltered(libraryFolder, utils.FilterDirs)
		if err != nil {
			return i18n.WrapError(err)
		}
		for _, subFolder := range subFolders {
			library, err := makeLibrary(filepath.Join(libraryFolder, subFolder.Name()), debugLevel, logger)
			if err != nil {
				return i18n.WrapError(err)
			}
			libraries = append(libraries, library)
		}
	}

	ctx.Libraries = libraries

	headerToLibraries := make(map[string][]*types.Library)
	for _, library := range libraries {
		headers, err := utils.ReadDirFiltered(library.SrcFolder, utils.FilterFilesWithExtensions(".h", ".hpp", ".hh"))
		if err != nil {
			return i18n.WrapError(err)
		}
		for _, header := range headers {
			headerFileName := header.Name()
			headerToLibraries[headerFileName] = append(headerToLibraries[headerFileName], library)
		}
	}

	ctx.HeaderToLibraries = headerToLibraries

	return nil
}