diff options
author | midipix <writeonce@midipix.org> | 2024-02-13 05:03:08 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2024-02-13 05:03:08 +0000 |
commit | 97bc5cffc0f90991211524321e423a3b0b5e5ea2 (patch) | |
tree | b4e181c465dbac8483ef7ee6c68315911223880d /src | |
parent | 6ab3f1cde643d5e9408bac0b1ad10fb901cf2294 (diff) | |
download | slibtool-97bc5cffc0f90991211524321e423a3b0b5e5ea2.tar.bz2 slibtool-97bc5cffc0f90991211524321e423a3b0b5e5ea2.tar.xz |
output: added slbt_output_config(): print a compatible --config output.
Diffstat (limited to 'src')
-rw-r--r-- | src/output/slbt_output_config.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/output/slbt_output_config.c b/src/output/slbt_output_config.c new file mode 100644 index 0000000..d779c68 --- /dev/null +++ b/src/output/slbt_output_config.c @@ -0,0 +1,100 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdbool.h> + +#include <slibtool/slibtool.h> +#include "slibtool_driver_impl.h" +#include "slibtool_dprintf_impl.h" +#include "slibtool_errinfo_impl.h" + +static const char lconf_begin[] = "# ### BEGIN LIBTOOL CONFIG\n"; +static const char lconf_end [] = "# ### END LIBTOOL CONFIG\n"; + +static int slbt_output_config_lconf( + const struct slbt_driver_ctx * dctx, + const struct slbt_map_info * lconf) +{ + 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) +{ + 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); + + return 0; +} |