|
|
b1be90 |
/*******************************************************************/
|
|
|
b1be90 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
b1be90 |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
b1be90 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
b1be90 |
/*******************************************************************/
|
|
|
b1be90 |
|
|
|
b1be90 |
#include <ctype.h>
|
|
|
b1be90 |
#include <stdint.h>
|
|
|
b1be90 |
#include <stddef.h>
|
|
|
b1be90 |
#include <stdlib.h>
|
|
|
b1be90 |
#include <string.h>
|
|
|
b1be90 |
#include <sys/mman.h>
|
|
|
b1be90 |
|
|
|
b1be90 |
#include <slibtool/slibtool.h>
|
|
|
b1be90 |
#include "slibtool_driver_impl.h"
|
|
|
b1be90 |
#include "slibtool_errinfo_impl.h"
|
|
|
3d2f83 |
#include "slibtool_visibility_impl.h"
|
|
|
b1be90 |
|
|
|
b1be90 |
/********************************************************/
|
|
|
b1be90 |
/* Read a text file, and create an in-memory vecotr of */
|
|
|
b1be90 |
/* normalized text lines, stripped of both leading and */
|
|
|
b1be90 |
/* trailing white space. */
|
|
|
b1be90 |
/********************************************************/
|
|
|
b1be90 |
|
|
|
b1be90 |
static int slbt_lib_free_txtfile_ctx_impl(
|
|
|
b1be90 |
struct slbt_txtfile_ctx_impl * ctx,
|
|
|
b1be90 |
struct slbt_input * mapinfo,
|
|
|
b1be90 |
int ret)
|
|
|
b1be90 |
{
|
|
|
b1be90 |
if (mapinfo)
|
|
|
b1be90 |
slbt_fs_unmap_input(mapinfo);
|
|
|
b1be90 |
|
|
|
b1be90 |
if (ctx) {
|
|
|
b1be90 |
if (ctx->pathbuf)
|
|
|
b1be90 |
free(ctx->pathbuf);
|
|
|
b1be90 |
|
|
|
b1be90 |
if (ctx->txtlines)
|
|
|
b1be90 |
free(ctx->txtlines);
|
|
|
b1be90 |
|
|
|
b1be90 |
if (ctx->txtlinev)
|
|
|
b1be90 |
free(ctx->txtlinev);
|
|
|
b1be90 |
|
|
|
b1be90 |
free(ctx);
|
|
|
b1be90 |
}
|
|
|
b1be90 |
|
|
|
b1be90 |
return ret;
|
|
|
b1be90 |
}
|
|
|
b1be90 |
|
|
|
3d2f83 |
static int slbt_lib_get_txtfile_ctx_impl(
|
|
|
b1be90 |
const struct slbt_driver_ctx * dctx,
|
|
|
b1be90 |
const char * path,
|
|
|
3d2f83 |
int fdsrc,
|
|
|
b1be90 |
struct slbt_txtfile_ctx ** pctx)
|
|
|
b1be90 |
{
|
|
|
b1be90 |
struct slbt_txtfile_ctx_impl * ctx;
|
|
|
b1be90 |
struct slbt_input mapinfo;
|
|
|
b1be90 |
size_t nlines;
|
|
|
b1be90 |
char * ch;
|
|
|
b1be90 |
char * cap;
|
|
|
b1be90 |
char * src;
|
|
|
b1be90 |
char * mark;
|
|
|
b1be90 |
const char ** pline;
|
|
|
b1be90 |
char dummy;
|
|
|
b1be90 |
int cint;
|
|
|
b1be90 |
|
|
|
b1be90 |
/* map txtfile file temporarily */
|
|
|
3d2f83 |
if (slbt_fs_map_input(dctx,fdsrc,path,PROT_READ,&mapinfo) < 0)
|
|
|
b1be90 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
b1be90 |
|
|
|
b1be90 |
/* alloc context */
|
|
|
b1be90 |
if (!(ctx = calloc(1,sizeof(*ctx))))
|
|
|
b1be90 |
return slbt_lib_free_txtfile_ctx_impl(
|
|
|
b1be90 |
ctx,&mapinfo,
|
|
|
b1be90 |
SLBT_BUFFER_ERROR(dctx));
|
|
|
b1be90 |
|
|
|
b1be90 |
/* count lines */
|
|
|
b1be90 |
src = mapinfo.size ? mapinfo.addr : &dummy;
|
|
|
b1be90 |
cap = &src[mapinfo.size];
|
|
|
b1be90 |
|
|
|
b1be90 |
for (; (src
|
|
|
b1be90 |
src++;
|
|
|
b1be90 |
|
|
|
b1be90 |
for (ch=src,nlines=0; ch
|
|
|
b1be90 |
nlines += (*ch == '\n');
|
|
|
b1be90 |
|
|
|
b1be90 |
nlines += (ch[-1] != '\n');
|
|
|
b1be90 |
|
|
|
b1be90 |
/* clone path, alloc string buffer and line vector */
|
|
|
b1be90 |
if (!(ctx->pathbuf = strdup(path)))
|
|
|
b1be90 |
return slbt_lib_free_txtfile_ctx_impl(
|
|
|
b1be90 |
ctx,&mapinfo,
|
|
|
b1be90 |
SLBT_SYSTEM_ERROR(dctx,0));
|
|
|
b1be90 |
|
|
|
b1be90 |
if (!(ctx->txtlines = calloc(mapinfo.size+1,1)))
|
|
|
b1be90 |
return slbt_lib_free_txtfile_ctx_impl(
|
|
|
b1be90 |
ctx,&mapinfo,
|
|
|
b1be90 |
SLBT_SYSTEM_ERROR(dctx,0));
|
|
|
b1be90 |
|
|
|
b1be90 |
if (!(ctx->txtlinev = calloc(nlines+1,sizeof(char *))))
|
|
|
b1be90 |
return slbt_lib_free_txtfile_ctx_impl(
|
|
|
b1be90 |
ctx,&mapinfo,
|
|
|
b1be90 |
SLBT_SYSTEM_ERROR(dctx,0));
|
|
|
b1be90 |
|
|
|
b1be90 |
/* copy the source to the allocated string buffer */
|
|
|
b1be90 |
memcpy(ctx->txtlines,mapinfo.addr,mapinfo.size);
|
|
|
b1be90 |
slbt_fs_unmap_input(&mapinfo);
|
|
|
b1be90 |
|
|
|
b1be90 |
/* populate the line vector, handle whitespace */
|
|
|
b1be90 |
src = ctx->txtlines;
|
|
|
b1be90 |
cap = &src[mapinfo.size];
|
|
|
b1be90 |
|
|
|
b1be90 |
for (; (src
|
|
|
b1be90 |
*src++ = '\0';
|
|
|
b1be90 |
|
|
|
b1be90 |
for (ch=src,pline=ctx->txtlinev; ch
|
|
|
b1be90 |
for (; (ch
|
|
|
b1be90 |
ch++;
|
|
|
b1be90 |
|
|
|
b1be90 |
if (ch < cap)
|
|
|
b1be90 |
*pline = ch;
|
|
|
b1be90 |
|
|
|
b1be90 |
for (; (ch
|
|
|
b1be90 |
ch++;
|
|
|
b1be90 |
|
|
|
b1be90 |
mark = ch;
|
|
|
b1be90 |
|
|
|
b1be90 |
for (--ch; (ch > *pline) && isspace((cint = *ch)); ch--)
|
|
|
b1be90 |
*ch = '\0';
|
|
|
b1be90 |
|
|
|
b1be90 |
if ((ch = mark) < cap)
|
|
|
b1be90 |
*ch++ = '\0';
|
|
|
b1be90 |
}
|
|
|
b1be90 |
|
|
|
b1be90 |
/* all done */
|
|
|
b1be90 |
ctx->dctx = dctx;
|
|
|
b1be90 |
ctx->path = ctx->pathbuf;
|
|
|
b1be90 |
ctx->tctx.path = &ctx->path;
|
|
|
b1be90 |
ctx->tctx.txtlinev = ctx->txtlinev;
|
|
|
b1be90 |
|
|
|
b1be90 |
*pctx = &ctx->tctx;
|
|
|
b1be90 |
|
|
|
b1be90 |
return 0;
|
|
|
b1be90 |
}
|
|
|
b1be90 |
|
|
|
3d2f83 |
slbt_hidden int slbt_impl_get_txtfile_ctx(
|
|
|
3d2f83 |
const struct slbt_driver_ctx * dctx,
|
|
|
3d2f83 |
const char * path,
|
|
|
3d2f83 |
int fdsrc,
|
|
|
3d2f83 |
struct slbt_txtfile_ctx ** pctx)
|
|
|
3d2f83 |
{
|
|
|
3d2f83 |
return slbt_lib_get_txtfile_ctx_impl(dctx,path,fdsrc,pctx);
|
|
|
3d2f83 |
}
|
|
|
3d2f83 |
|
|
|
3d2f83 |
int slbt_lib_get_txtfile_ctx(
|
|
|
3d2f83 |
const struct slbt_driver_ctx * dctx,
|
|
|
3d2f83 |
const char * path,
|
|
|
3d2f83 |
struct slbt_txtfile_ctx ** pctx)
|
|
|
3d2f83 |
{
|
|
|
3d2f83 |
return slbt_lib_get_txtfile_ctx_impl(dctx,path,(-1),pctx);
|
|
|
3d2f83 |
}
|
|
|
3d2f83 |
|
|
|
b1be90 |
void slbt_lib_free_txtfile_ctx(struct slbt_txtfile_ctx * ctx)
|
|
|
b1be90 |
{
|
|
|
b1be90 |
struct slbt_txtfile_ctx_impl * ictx;
|
|
|
b1be90 |
uintptr_t addr;
|
|
|
b1be90 |
|
|
|
b1be90 |
if (ctx) {
|
|
|
b1be90 |
addr = (uintptr_t)ctx - offsetof(struct slbt_txtfile_ctx_impl,tctx);
|
|
|
b1be90 |
ictx = (struct slbt_txtfile_ctx_impl *)addr;
|
|
|
b1be90 |
slbt_lib_free_txtfile_ctx_impl(ictx,0,0);
|
|
|
b1be90 |
}
|
|
|
b1be90 |
}
|