Blame src/internal/slibtool_mkvars_impl.c

c6ecfc
/*******************************************************************/
c6ecfc
/*  slibtool: a strong libtool implementation, written in C        */
c6ecfc
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
c6ecfc
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
c6ecfc
/*******************************************************************/
c6ecfc
c6ecfc
#include <ctype.h>
c6ecfc
#include <stdio.h>
c6ecfc
#include <stdint.h>
c6ecfc
#include <stdbool.h>
c6ecfc
c6ecfc
#include "slibtool_mkvars_impl.h"
c6ecfc
#include "slibtool_driver_impl.h"
c6ecfc
#include "slibtool_errinfo_impl.h"
c6ecfc
#include "slibtool_symlink_impl.h"
c6ecfc
#include "slibtool_readlink_impl.h"
c6ecfc
#include "slibtool_realpath_impl.h"
c6ecfc
#include "slibtool_visibility_impl.h"
c6ecfc
c6ecfc
static int slbt_get_mkvars_var(
c6ecfc
	const struct slbt_driver_ctx *  dctx,
c6ecfc
	const struct slbt_txtfile_ctx * tctx,
c6ecfc
	const char *                    var,
c6ecfc
	const char                      space,
c6ecfc
	char                            (*val)[PATH_MAX])
c6ecfc
{
c6ecfc
	const char **   pline;
c6ecfc
	const char *    mark;
c6ecfc
	const char *    match;
c6ecfc
	ssize_t         len;
c6ecfc
	int             cint;
c6ecfc
c6ecfc
	/* init */
c6ecfc
	match = 0;
c6ecfc
	len   = strlen(var);
c6ecfc
c6ecfc
	/* search for ^var= */
c6ecfc
	for (pline=tctx->txtlinev; !match && *pline; pline++) {
c6ecfc
		if (!strncmp(*pline,var,len)) {
c6ecfc
			if (isspace((*pline)[len]) || ((*pline)[len] == '=')) {
c6ecfc
				mark = &(*pline)[len];
c6ecfc
c6ecfc
				for (; isspace(cint = *mark); )
c6ecfc
					mark++;
c6ecfc
c6ecfc
				if (mark[0] != '=')
c6ecfc
					return SLBT_CUSTOM_ERROR(
c6ecfc
						dctx,
c6ecfc
						SLBT_ERR_MKVARS_PARSE);
c6ecfc
c6ecfc
				mark++;
c6ecfc
c6ecfc
				for (; isspace(cint = *mark); )
c6ecfc
					mark++;
c6ecfc
c6ecfc
				match = mark;
c6ecfc
			}
c6ecfc
		}
c6ecfc
	}
c6ecfc
c6ecfc
	/* not found? */
c6ecfc
	if (!match) {
c6ecfc
		(*val)[0] = '\0';
c6ecfc
		return 0;
c6ecfc
	}
c6ecfc
c6ecfc
	/* validate */
c6ecfc
	for (mark=match; *mark; mark++) {
c6ecfc
		if ((*mark >= 'a') && (*mark <= 'z'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark >= 'A') && (*mark <= 'Z'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark >= '0') && (*mark <= '9'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark == '+') || (*mark == '-'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark == '/') || (*mark == '@'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark == '.') || (*mark == '_'))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else if ((*mark == ':') || (*mark == space))
c6ecfc
			(void)0;
c6ecfc
c6ecfc
		else
c6ecfc
			return SLBT_CUSTOM_ERROR(
c6ecfc
				dctx,
c6ecfc
				SLBT_ERR_MKVARS_PARSE);
c6ecfc
	}
c6ecfc
c6ecfc
	/* all done */
c6ecfc
	strcpy(*val,match);
c6ecfc
c6ecfc
	return 0;
c6ecfc
}
c6ecfc
c6ecfc
slbt_hidden int slbt_get_mkvars_flags(
c6ecfc
	struct slbt_driver_ctx *	dctx,
c6ecfc
	const char *			mkvars,
c6ecfc
	uint64_t *			flags)
c6ecfc
{
c6ecfc
	struct slbt_driver_ctx_impl *   ctx;
c6ecfc
	struct slbt_txtfile_ctx *       confctx;
c6ecfc
	char *                          dash;
c6ecfc
	uint64_t			optshared;
c6ecfc
	uint64_t			optstatic;
c6ecfc
	char                            val[PATH_MAX];
c6ecfc
c6ecfc
	/* driver context (ar, ranlib, cc) */
c6ecfc
	ctx = slbt_get_driver_ictx(dctx);
c6ecfc
c6ecfc
	/* cache the makefile in library friendly form) */
c6ecfc
	if (slbt_lib_get_txtfile_ctx(dctx,mkvars,&ctx->mkvarsctx) < 0)
c6ecfc
		return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
	confctx = ctx->mkvarsctx;
c6ecfc
c6ecfc
	/* scan */
c6ecfc
	optshared = 0;
c6ecfc
	optstatic = 0;
c6ecfc
c6ecfc
	/* slibtool */
c6ecfc
	if (slbt_get_mkvars_var(dctx,confctx,"SLIBTOOL",0,&val) < 0)
c6ecfc
		return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
	if ((dash = strrchr(val,'-'))) {
c6ecfc
		if (!strcmp(dash,"-shared")) {
c6ecfc
			optshared = SLBT_DRIVER_SHARED;
c6ecfc
			optstatic = SLBT_DRIVER_DISABLE_STATIC;
c6ecfc
c6ecfc
		} else if (!strcmp(dash,"-static")) {
c6ecfc
			optshared = SLBT_DRIVER_DISABLE_SHARED;
c6ecfc
			optstatic = SLBT_DRIVER_STATIC;
c6ecfc
		} else {
c6ecfc
			return SLBT_CUSTOM_ERROR(
c6ecfc
				dctx,
c6ecfc
				SLBT_ERR_MKVARS_PARSE);
c6ecfc
		}
c6ecfc
	} else {
c6ecfc
		optshared = SLBT_DRIVER_SHARED;
c6ecfc
		optstatic = SLBT_DRIVER_STATIC;
c6ecfc
	}
c6ecfc
c6ecfc
	*flags = optshared | optstatic;
c6ecfc
c6ecfc
	/* host */
c6ecfc
	if (!ctx->cctx.host.host) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"host",0,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.host = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
		ctx->cctx.host.host = ctx->host.host;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* ar tool */
c6ecfc
	if (!ctx->cctx.host.ar) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"AR",0x20,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.ar = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
		ctx->cctx.host.ar = ctx->host.ar;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* nm tool */
c6ecfc
	if (!ctx->cctx.host.nm) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"NM",0x20,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.nm = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
		ctx->cctx.host.nm = ctx->host.nm;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* ranlib tool */
c6ecfc
	if (!ctx->cctx.host.ranlib) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"RANLIB",0x20,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.ranlib = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
		ctx->cctx.host.ranlib = ctx->host.ranlib;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* as tool (optional) */
c6ecfc
	if (!ctx->cctx.host.as) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"AS",0x20,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.as = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
c6ecfc
		ctx->cctx.host.as = ctx->host.as;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* dlltool tool (optional) */
c6ecfc
	if (!ctx->cctx.host.dlltool) {
c6ecfc
		if (slbt_get_mkvars_var(dctx,confctx,"DLLTOOL",0x20,&val) < 0)
c6ecfc
			return SLBT_NESTED_ERROR(dctx);
c6ecfc
c6ecfc
		if (val[0] && !(ctx->host.dlltool = strdup(val)))
c6ecfc
			return SLBT_SYSTEM_ERROR(dctx,0);
c6ecfc
c6ecfc
		ctx->cctx.host.dlltool = ctx->host.dlltool;
c6ecfc
	}
c6ecfc
c6ecfc
c6ecfc
	/* all done */
c6ecfc
	return 0;
c6ecfc
}