diff --git a/project/common.mk b/project/common.mk index a87d577..919d53a 100644 --- a/project/common.mk +++ b/project/common.mk @@ -71,6 +71,7 @@ INTERNAL_SRCS = \ src/internal/$(PACKAGE)_errinfo_impl.c \ src/internal/$(PACKAGE)_lconf_impl.c \ src/internal/$(PACKAGE)_libmeta_impl.c \ + src/internal/$(PACKAGE)_m4fake_impl.c \ src/internal/$(PACKAGE)_mapfile_impl.c \ src/internal/$(PACKAGE)_objlist_impl.c \ src/internal/$(PACKAGE)_objmeta_impl.c \ diff --git a/project/headers.mk b/project/headers.mk index f57eaae..6546375 100644 --- a/project/headers.mk +++ b/project/headers.mk @@ -14,6 +14,7 @@ INTERNAL_HEADERS = \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_install_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_lconf_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_linkcmd_impl.h \ + $(PROJECT_DIR)/src/internal/$(PACKAGE)_m4fake_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_mapfile_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_metafile_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \ diff --git a/src/internal/slibtool_m4fake_impl.c b/src/internal/slibtool_m4fake_impl.c new file mode 100644 index 0000000..4a46978 --- /dev/null +++ b/src/internal/slibtool_m4fake_impl.c @@ -0,0 +1,142 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include +#include + +#include +#include "slibtool_driver_impl.h" +#include "slibtool_snprintf_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_visibility_impl.h" +#include "slibtool_m4fake_impl.h" + +slbt_hidden int slbt_m4fake_expand_cmdarg( + struct slbt_driver_ctx * dctx, + struct slbt_txtfile_ctx * sctx, + const char * cmdname, + char (*argbuf)[PATH_MAX]) +{ + const char ** pline; + size_t slen; + const char * mark; + const char * match; + const char * cap; + int fquote; + char varbuf[PATH_MAX]; + char strbuf[PATH_MAX]; + + memset(*argbuf,0,sizeof(*argbuf)); + + slen = strlen(cmdname); + pline = sctx->txtlinev; + match = 0; + + for (; !match && *pline; ) { + if (!strncmp(*pline,cmdname,slen)) { + if ((*pline)[slen] == '(') { + mark = &(*pline)[slen]; + cap = ++mark; + + for (fquote=0; !match && *cap; ) { + if (*cap == '[') + fquote++; + + else if ((*cap == ']') && fquote) + fquote--; + + else if ((*cap == ')') && !fquote) + match = cap; + + if (!match) + cap++; + } + + if (!match) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + } + } + + if (!match) + pline++; + } + + if (!match) + return 0; + + strncpy(strbuf,mark,cap-mark); + strbuf[cap-mark] = '\0'; + + mark = strbuf; + slen = strlen(mark); + + if ((mark[0] == '[') && (mark[--slen] == ']')) { + strcpy(*argbuf,++mark); + (*argbuf)[--slen] = '\0'; + return 0; + } + + if (slbt_snprintf( + varbuf,sizeof(varbuf), + "AC_DEFUN([%s],", + strbuf) < 0) + return SLBT_BUFFER_ERROR(dctx); + + slen = strlen(varbuf); + + for (--pline; pline >= sctx->txtlinev; pline--) { + if (!strncmp(*pline,varbuf,slen)) { + mark = &(*pline)[slen]; + cap = mark; + match = 0; + + for (fquote=0; !match && *cap; ) { + if (*cap == '[') + fquote++; + + else if ((*cap == ']') && fquote) + fquote--; + + else if ((*cap == ')') && !fquote) + match = cap; + + if (!match) + cap++; + } + + if (!match) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + strncpy(strbuf,mark,cap-mark); + strbuf[cap-mark] = '\0'; + + mark = strbuf; + slen = strlen(mark); + + if ((mark[0] == '[') && (mark[--slen] == ']')) { + strcpy(*argbuf,++mark); + (*argbuf)[--slen] = '\0'; + return 0; + } + + if (slbt_snprintf( + varbuf,sizeof(varbuf), + "AC_DEFUN([%s],", + strbuf) < 0) + return SLBT_BUFFER_ERROR(dctx); + + slen = strlen(varbuf); + } + } + + strcpy(*argbuf,strbuf); + + return 0; +} diff --git a/src/internal/slibtool_m4fake_impl.h b/src/internal/slibtool_m4fake_impl.h new file mode 100644 index 0000000..af0de56 --- /dev/null +++ b/src/internal/slibtool_m4fake_impl.h @@ -0,0 +1,12 @@ +#ifndef SLIBTOOL_M4FAKE_IMPL_H +#define SLIBTOOL_M4FAKE_IMPL_H + +#include + +int slbt_m4fake_expand_cmdarg( + struct slbt_driver_ctx * dctx, + struct slbt_txtfile_ctx * sctx, + const char * cmdname, + char (*argbuf)[PATH_MAX]); + +#endif