firasuke / cross / slibtool

Forked from cross/slibtool 3 months ago
Clone

Blame src/output/slbt_output_config.c

97bc5c
/*******************************************************************/
eac61a
/*  slibtool: a strong libtool implementation, written in C        */
97bc5c
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
97bc5c
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
97bc5c
/*******************************************************************/
97bc5c
97bc5c
#include <stdio.h>
97bc5c
#include <string.h>
97bc5c
#include <stdbool.h>
97bc5c
97bc5c
#include <slibtool/slibtool.h>
97bc5c
#include "slibtool_driver_impl.h"
97bc5c
#include "slibtool_dprintf_impl.h"
97bc5c
#include "slibtool_errinfo_impl.h"
97bc5c
1b1261
static const char enable[]  = "yes";
1b1261
static const char disable[] = "no";
1b1261
97bc5c
static const char lconf_begin[] = "# ### BEGIN LIBTOOL CONFIG\n";
97bc5c
static const char lconf_end  [] = "# ### END LIBTOOL CONFIG\n";
1b1261
static const char lconf_guard[] = "# ### ##################\n";
97bc5c
97bc5c
static int slbt_output_config_lconf(
97bc5c
	const struct slbt_driver_ctx * dctx,
97bc5c
	const struct slbt_map_info *   lconf)
97bc5c
{
97bc5c
	const char *    ch;
97bc5c
	const char *    cfg_begin;
97bc5c
	const char *    cfg_end;
97bc5c
	const char *    map_cap;
97bc5c
	size_t          cmp_len;
97bc5c
	size_t          end_len;
97bc5c
	size_t          min_len;
97bc5c
	size_t          nbytes;
97bc5c
	ssize_t         written;
97bc5c
	int             fdout;
97bc5c
97bc5c
	cmp_len = strlen(lconf_begin);
97bc5c
	end_len = strlen(lconf_end);
97bc5c
	min_len = cmp_len + end_len;
97bc5c
97bc5c
	if (lconf->size < min_len)
97bc5c
		return SLBT_CUSTOM_ERROR(
97bc5c
			dctx,
97bc5c
			SLBT_ERR_FLOW_ERROR);
97bc5c
97bc5c
	map_cap  = lconf->addr;
97bc5c
	map_cap += lconf->size;
97bc5c
	map_cap -= strlen(lconf_end);
97bc5c
	map_cap -= strlen(lconf_begin);
97bc5c
97bc5c
	cfg_begin = cfg_end = 0;
97bc5c
97bc5c
	for (ch=lconf->addr; !cfg_begin && (ch < map_cap); ch++)
97bc5c
		if (!strncmp(ch,lconf_begin,cmp_len))
97bc5c
			cfg_begin = ch;
97bc5c
97bc5c
	if (!cfg_begin)
97bc5c
		return SLBT_CUSTOM_ERROR(
97bc5c
			dctx,
97bc5c
			SLBT_ERR_FLOW_ERROR);
97bc5c
97bc5c
	for (++ch; !cfg_end && (ch < map_cap); ch++)
97bc5c
		if (!strncmp(ch,lconf_end,end_len))
97bc5c
			cfg_end = ch;
97bc5c
97bc5c
	if (!cfg_end)
97bc5c
		return SLBT_CUSTOM_ERROR(
97bc5c
			dctx,
97bc5c
			SLBT_ERR_FLOW_ERROR);
97bc5c
97bc5c
	fdout  = slbt_driver_fdout(dctx);
97bc5c
	nbytes = cfg_end - cfg_begin - cmp_len;
97bc5c
97bc5c
	for (ch=&cfg_begin[cmp_len]; nbytes; ) {
97bc5c
		written = write(fdout,ch,nbytes);
97bc5c
97bc5c
		while ((written < 0) && (errno == EINTR))
97bc5c
			written = write(fdout,ch,nbytes);
97bc5c
97bc5c
		if (written < 0)
97bc5c
			return SLBT_SYSTEM_ERROR(dctx,0);
97bc5c
97bc5c
		nbytes -= written;
97bc5c
		ch     += written;
97bc5c
	}
97bc5c
97bc5c
	return 0;
97bc5c
}
97bc5c
1b1261
static int slbt_output_config_mkvars(const struct slbt_driver_ctx * dctx)
1b1261
{
1b1261
	int                                 fdout;
1b1261
	const char *                        shared_option;
1b1261
	const char *                        static_option;
1b1261
	const struct slbt_source_version *  verinfo;
1b1261
	const struct slbt_common_ctx *      cctx;
1b1261
1b1261
	/* init */
1b1261
	fdout = slbt_driver_fdout(dctx);
1b1261
1b1261
	shared_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_SHARED)
1b1261
		? disable : enable;
1b1261
1b1261
	static_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_STATIC)
1b1261
		? disable : enable;
1b1261
1b1261
	cctx = dctx->cctx;
1b1261
1b1261
	/* header */
1b1261
	verinfo = slbt_api_source_version();
1b1261
1b1261
	if (slbt_dprintf(
1b1261
			fdout,
1b1261
			"%s\n\n"
1b1261
			"%s\n"
1b1261
			"# %s\n"
1b1261
			"# Generated by %s (slibtool %d.%d.%d)\n"
1b1261
			"# [commit reference: %s]\n\n",
1b1261
			"#!/dev/null",
1b1261
			lconf_begin,
1b1261
			"Backward compatible build configuration",
1b1261
			dctx->program,
1b1261
			verinfo->major,verinfo->minor,verinfo->revision,
1b1261
			verinfo->commit) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	/* shared & static build options */
1b1261
	if (slbt_dprintf(fdout,"# shared libraries?\n" "build_libtool_libs=%s\n\n",shared_option) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# static libraries?\n" "build_old_libs=%s\n\n",static_option) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# host identification\n" "host=%s\n\n",cctx->host.host) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# archiver\n" "AR=\"%s\"\n\n",cctx->host.ar) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# name mangler\n" "NM=\"%s\"\n\n",cctx->host.nm) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# archive librarian\n" "RANLIB=\"%s\"\n\n",cctx->host.ranlib) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# assembler\n" "AS=\"%s\"\n\n",cctx->host.as) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# PE targets: modern import library compiler\n" "MDSO=%s%s%s\n\n",
1b1261
			cctx->host.mdso[0] ? "\"" : "",
1b1261
			cctx->host.mdso[0] ? cctx->host.mdso : "",
1b1261
			cctx->host.mdso[0] ? "\"" : "") < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# PE targets: coff import library compiler\n" "DLLTOOL=%s%s%s\n\n",
1b1261
			cctx->host.dlltool[0] ? "\"" : "",
1b1261
			cctx->host.dlltool[0] ? cctx->host.dlltool : "",
1b1261
			cctx->host.dlltool[0] ? "\"" : "") < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"# PE targets: resource compiler\n" "WINDRES=%s%s%s\n\n",
1b1261
			cctx->host.windres[0] ? "\"" : "",
1b1261
			cctx->host.windres[0] ? cctx->host.windres : "",
1b1261
			cctx->host.windres[0] ? "\"" : "") < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	if (slbt_dprintf(fdout,"%s%s%s\n",lconf_end,lconf_guard,lconf_guard) < 0)
1b1261
		return SLBT_SYSTEM_ERROR(dctx,0);
1b1261
1b1261
	return 0;
1b1261
}
1b1261
97bc5c
int slbt_output_config(const struct slbt_driver_ctx * dctx)
97bc5c
{
97bc5c
	struct slbt_driver_ctx_impl *   ictx;
97bc5c
	const struct slbt_map_info *    lconf;
97bc5c
97bc5c
	ictx  = slbt_get_driver_ictx(dctx);
97bc5c
	lconf = &ictx->lconf;
97bc5c
97bc5c
	if (lconf->addr)
97bc5c
		return slbt_output_config_lconf(
97bc5c
			dctx,lconf);
97bc5c
1b1261
	if (ictx->mkvarsctx || true)
1b1261
		return slbt_output_config_mkvars(dctx);
1b1261
97bc5c
	return 0;
97bc5c
}