diff options
Diffstat (limited to 'src/output/slbt_output_config.c')
-rw-r--r-- | src/output/slbt_output_config.c | 216 |
1 files changed, 146 insertions, 70 deletions
diff --git a/src/output/slbt_output_config.c b/src/output/slbt_output_config.c index 181aa84..0442884 100644 --- a/src/output/slbt_output_config.c +++ b/src/output/slbt_output_config.c @@ -1,6 +1,6 @@ /*******************************************************************/ -/* slibtool: a skinny libtool implementation, written in C */ -/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ @@ -13,102 +13,178 @@ #include "slibtool_dprintf_impl.h" #include "slibtool_errinfo_impl.h" -#ifndef SLBT_TAB_WIDTH -#define SLBT_TAB_WIDTH 8 -#endif +static const char enable[] = "yes"; +static const char disable[] = "no"; -#ifndef SLBT_KEY_WIDTH -#define SLBT_KEY_WIDTH 16 -#endif +static const char lconf_begin[] = "# ### BEGIN LIBTOOL CONFIG\n"; +static const char lconf_end [] = "# ### END LIBTOOL CONFIG\n"; +static const char lconf_guard[] = "# ### ##################\n"; -static bool slbt_output_config_line( - int fd, - const char * key, - const char * value, - const char * annotation, - int midwidth) +static int slbt_output_config_lconf( + const struct slbt_driver_ctx * dctx, + const struct slbt_map_info * lconf) { - return (slbt_dprintf(fd,"%-*s%-*s%s\n", - SLBT_KEY_WIDTH, key, - midwidth, value ? value : "", - annotation ? annotation : "") < 0) - ? true : false; + const char * ch; + const char * cfg_begin; + const char * cfg_end; + const char * map_cap; + size_t cmp_len; + size_t end_len; + size_t min_len; + size_t nbytes; + ssize_t written; + int fdout; + + cmp_len = strlen(lconf_begin); + end_len = strlen(lconf_end); + min_len = cmp_len + end_len; + + if (lconf->size < min_len) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + map_cap = lconf->addr; + map_cap += lconf->size; + map_cap -= strlen(lconf_end); + map_cap -= strlen(lconf_begin); + + cfg_begin = cfg_end = 0; + + for (ch=lconf->addr; !cfg_begin && (ch < map_cap); ch++) + if (!strncmp(ch,lconf_begin,cmp_len)) + cfg_begin = ch; + + if (!cfg_begin) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + for (++ch; !cfg_end && (ch < map_cap); ch++) + if (!strncmp(ch,lconf_end,end_len)) + cfg_end = ch; + + if (!cfg_end) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + fdout = slbt_driver_fdout(dctx); + nbytes = cfg_end - cfg_begin - cmp_len; + + for (ch=&cfg_begin[cmp_len]; nbytes; ) { + written = write(fdout,ch,nbytes); + + while ((written < 0) && (errno == EINTR)) + written = write(fdout,ch,nbytes); + + if (written < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + + nbytes -= written; + ch += written; + } + + return 0; } -int slbt_output_config(const struct slbt_driver_ctx * dctx) +static int slbt_output_config_mkvars(const struct slbt_driver_ctx * dctx) { - const struct slbt_common_ctx * cctx; - const char * compiler; - const char * target; - int len; - int midwidth; - int fdout; - - cctx = dctx->cctx; - compiler = cctx->cargv[0] ? cctx->cargv[0] : ""; - target = cctx->target ? cctx->target : ""; - midwidth = strlen(compiler); - fdout = slbt_driver_fdout(dctx); - - if ((len = strlen(target)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.host)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.flavor)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.ar)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.ranlib)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.windres)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.dlltool)) > midwidth) - midwidth = len; - - if ((len = strlen(cctx->host.mdso)) > midwidth) - midwidth = len; - - midwidth += SLBT_TAB_WIDTH; - midwidth &= (~(SLBT_TAB_WIDTH-1)); + int fdout; + const char * shared_option; + const char * static_option; + const struct slbt_source_version * verinfo; + const struct slbt_common_ctx * cctx; + + /* init */ + fdout = slbt_driver_fdout(dctx); + + shared_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_SHARED) + ? disable : enable; + + static_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_STATIC) + ? disable : enable; + + cctx = dctx->cctx; + + /* header */ + verinfo = slbt_api_source_version(); + + if (slbt_dprintf( + fdout, + "%s\n\n" + "%s\n" + "# %s\n" + "# Generated by %s (slibtool %d.%d.%d)\n" + "# [commit reference: %s]\n\n", + "#!/dev/null", + lconf_begin, + "Backward compatible build configuration", + dctx->program, + verinfo->major,verinfo->minor,verinfo->revision, + verinfo->commit) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"key","value","annotation",midwidth)) + /* shared & static build options */ + if (slbt_dprintf(fdout,"# shared libraries?\n" "build_libtool_libs=%s\n\n",shared_option) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"---","-----","----------",midwidth)) + if (slbt_dprintf(fdout,"# static libraries?\n" "build_old_libs=%s\n\n",static_option) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"compiler",cctx->cargv[0],"",midwidth)) + if (slbt_dprintf(fdout,"# host identification\n" "host=%s\n\n",cctx->host.host) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"target",cctx->target,"",midwidth)) + if (slbt_dprintf(fdout,"# archiver\n" "AR=\"%s\"\n\n",cctx->host.ar) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"host",cctx->host.host,cctx->cfgmeta.host,midwidth)) + if (slbt_dprintf(fdout,"# name mangler\n" "NM=\"%s\"\n\n",cctx->host.nm) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"flavor",cctx->host.flavor,cctx->cfgmeta.flavor,midwidth)) + if (slbt_dprintf(fdout,"# archive librarian\n" "RANLIB=\"%s\"\n\n",cctx->host.ranlib) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"ar",cctx->host.ar,cctx->cfgmeta.ar,midwidth)) + if (slbt_dprintf(fdout,"# assembler\n" "AS=\"%s\"\n\n",cctx->host.as) < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"ranlib",cctx->host.ranlib,cctx->cfgmeta.ranlib,midwidth)) + if (slbt_dprintf(fdout,"# PE targets: modern import library compiler\n" "MDSO=%s%s%s\n\n", + cctx->host.mdso[0] ? "\"" : "", + cctx->host.mdso[0] ? cctx->host.mdso : "", + cctx->host.mdso[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"windres",cctx->host.windres,cctx->cfgmeta.windres,midwidth)) + if (slbt_dprintf(fdout,"# PE targets: coff import library compiler\n" "DLLTOOL=%s%s%s\n\n", + cctx->host.dlltool[0] ? "\"" : "", + cctx->host.dlltool[0] ? cctx->host.dlltool : "", + cctx->host.dlltool[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"dlltool",cctx->host.dlltool,cctx->cfgmeta.dlltool,midwidth)) + if (slbt_dprintf(fdout,"# PE targets: resource compiler\n" "WINDRES=%s%s%s\n\n", + cctx->host.windres[0] ? "\"" : "", + cctx->host.windres[0] ? cctx->host.windres : "", + cctx->host.windres[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); - if (slbt_output_config_line(fdout,"mdso",cctx->host.mdso,cctx->cfgmeta.mdso,midwidth)) + if (slbt_dprintf(fdout,"%s%s%s\n",lconf_end,lconf_guard,lconf_guard) < 0) return SLBT_SYSTEM_ERROR(dctx,0); return 0; } + +int slbt_output_config(const struct slbt_driver_ctx * dctx) +{ + struct slbt_driver_ctx_impl * ictx; + const struct slbt_map_info * lconf; + + ictx = slbt_get_driver_ictx(dctx); + lconf = &ictx->lconf; + + if (lconf->addr) + return slbt_output_config_lconf( + dctx,lconf); + + if (ictx->mkvarsctx || true) + return slbt_output_config_mkvars(dctx); + + return 0; +} |