firasuke / cross / slibtool

Forked from cross/slibtool 3 months ago
Clone

Blame src/internal/slibtool_m4fake_impl.c

ba25fa
/*******************************************************************/
ba25fa
/*  slibtool: a strong libtool implementation, written in C        */
ba25fa
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
ba25fa
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
ba25fa
/*******************************************************************/
ba25fa
ba25fa
#include <string.h>
ba25fa
#include <limits.h>
ba25fa
ba25fa
#include <slibtool/slibtool.h>
ba25fa
#include "slibtool_driver_impl.h"
ba25fa
#include "slibtool_snprintf_impl.h"
ba25fa
#include "slibtool_errinfo_impl.h"
ba25fa
#include "slibtool_visibility_impl.h"
ba25fa
#include "slibtool_m4fake_impl.h"
ba25fa
ba25fa
slbt_hidden int slbt_m4fake_expand_cmdarg(
ba25fa
	struct slbt_driver_ctx *  dctx,
ba25fa
	struct slbt_txtfile_ctx * sctx,
ba25fa
	const char *              cmdname,
ba25fa
	char                      (*argbuf)[PATH_MAX])
ba25fa
{
ba25fa
	const char **             pline;
ba25fa
	size_t                    slen;
ba25fa
	const char *              mark;
ba25fa
	const char *              match;
ba25fa
	const char *              cap;
ba25fa
	int                       fquote;
ba25fa
	char                      varbuf[PATH_MAX];
ba25fa
	char                      strbuf[PATH_MAX];
ba25fa
ba25fa
	memset(*argbuf,0,sizeof(*argbuf));
ba25fa
ba25fa
	slen  = strlen(cmdname);
ba25fa
	pline = sctx->txtlinev;
ba25fa
	match = 0;
ba25fa
ba25fa
	for (; !match && *pline; ) {
ba25fa
		if (!strncmp(*pline,cmdname,slen)) {
ba25fa
			if ((*pline)[slen] == '(') {
ba25fa
				mark  = &(*pline)[slen];
ba25fa
				cap   = ++mark;
ba25fa
ba25fa
				for (fquote=0; !match && *cap; ) {
ba25fa
					if (*cap == '[')
ba25fa
						fquote++;
ba25fa
ba25fa
					else if ((*cap == ']') && fquote)
ba25fa
						fquote--;
ba25fa
ba25fa
					else if ((*cap == ')') && !fquote)
ba25fa
						match = cap;
ba25fa
ba25fa
					if (!match)
ba25fa
						cap++;
ba25fa
				}
ba25fa
ba25fa
				if (!match)
ba25fa
					return SLBT_CUSTOM_ERROR(
ba25fa
						dctx,
ba25fa
						SLBT_ERR_FLOW_ERROR);
ba25fa
			}
ba25fa
		}
ba25fa
ba25fa
		if (!match)
ba25fa
			pline++;
ba25fa
	}
ba25fa
ba25fa
	if (!match)
ba25fa
		return 0;
ba25fa
ba25fa
	strncpy(strbuf,mark,cap-mark);
ba25fa
	strbuf[cap-mark] = '\0';
ba25fa
ba25fa
	mark = strbuf;
ba25fa
	slen = strlen(mark);
ba25fa
ba25fa
	if ((mark[0] == '[') && (mark[--slen] == ']')) {
ba25fa
		strcpy(*argbuf,++mark);
ba25fa
		(*argbuf)[--slen] = '\0';
ba25fa
		return 0;
ba25fa
	}
ba25fa
ba25fa
	if (slbt_snprintf(
ba25fa
			varbuf,sizeof(varbuf),
ba25fa
			"AC_DEFUN([%s],",
ba25fa
			strbuf) < 0)
ba25fa
		return SLBT_BUFFER_ERROR(dctx);
ba25fa
ba25fa
	slen = strlen(varbuf);
ba25fa
ba25fa
	for (--pline; pline >= sctx->txtlinev; pline--) {
ba25fa
		if (!strncmp(*pline,varbuf,slen)) {
ba25fa
			mark  = &(*pline)[slen];
ba25fa
			cap   = mark;
ba25fa
			match = 0;
ba25fa
ba25fa
			for (fquote=0; !match && *cap; ) {
ba25fa
				if (*cap == '[')
ba25fa
					fquote++;
ba25fa
ba25fa
				else if ((*cap == ']') && fquote)
ba25fa
					fquote--;
ba25fa
ba25fa
				else if ((*cap == ')') && !fquote)
ba25fa
					match = cap;
ba25fa
ba25fa
				if (!match)
ba25fa
					cap++;
ba25fa
			}
ba25fa
ba25fa
			if (!match)
ba25fa
				return SLBT_CUSTOM_ERROR(
ba25fa
					dctx,
ba25fa
					SLBT_ERR_FLOW_ERROR);
ba25fa
ba25fa
			strncpy(strbuf,mark,cap-mark);
ba25fa
			strbuf[cap-mark] = '\0';
ba25fa
ba25fa
			mark = strbuf;
ba25fa
			slen = strlen(mark);
ba25fa
ba25fa
			if ((mark[0] == '[') && (mark[--slen] == ']')) {
ba25fa
				strcpy(*argbuf,++mark);
ba25fa
				(*argbuf)[--slen] = '\0';
ba25fa
				return 0;
ba25fa
			}
ba25fa
ba25fa
			if (slbt_snprintf(
ba25fa
					varbuf,sizeof(varbuf),
ba25fa
					"AC_DEFUN([%s],",
ba25fa
					strbuf) < 0)
ba25fa
				return SLBT_BUFFER_ERROR(dctx);
ba25fa
ba25fa
			slen = strlen(varbuf);
ba25fa
		}
ba25fa
	}
ba25fa
ba25fa
	strcpy(*argbuf,strbuf);
ba25fa
ba25fa
	return 0;
ba25fa
}