-
Volodymyr Medvid authored
Prevent symbol lookup error in commands linked to lib66.so: 66-tree: symbol lookup error: /usr/x86_64-pc-linux-gnu/lib/lib66.so.0.2: undefined symbol: MAXDEPTH
Volodymyr Medvid authoredPrevent symbol lookup error in commands linked to lib66.so: 66-tree: symbol lookup error: /usr/x86_64-pc-linux-gnu/lib/lib66.so.0.2: undefined symbol: MAXDEPTH
ss_info_utils.c 6.72 KiB
/*
* ss_info_utils.c
*
* Copyright (c) 2018-2020 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
* */
#include <66/info.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h> //ssize_t
#include <oblibs/sastr.h>
#include <oblibs/log.h>
#include <skalibs/buffer.h>
#include <skalibs/lolstdio.h>
#include <s6/s6-supervise.h>
#include <66/resolve.h>
unsigned int MAXDEPTH = 1 ;
ss_resolve_graph_style graph_utf8 = {
UTF_VR UTF_H,
UTF_UR UTF_H,
UTF_V " ",
2
} ;
ss_resolve_graph_style graph_default = {
"|-",
"`-",
"|",
2
} ;
int info_getcols_fd(int fd)
{
int width = -1;
if(!isatty(fd)) return 0;
#if defined(TIOCGSIZE)
struct ttysize win;
if(ioctl(fd, TIOCGSIZE, &win) == 0)
width = win.ts_cols;
#elif defined(TIOCGWINSZ)
struct winsize win;
if(ioctl(fd, TIOCGWINSZ, &win) == 0)
width = win.ws_col;
#endif
// return abitrary value
if(width <= 0) return 100 ;
return width;
}
void info_field_align (char buf[][INFO_FIELD_MAXLEN],char fields[][INFO_FIELD_MAXLEN],wchar_t const field_suffix[],size_t buflen)
{
unsigned int i ;
size_t maxlen = 0 ;
int maxcol = 0 ;
static wchar_t wbuf[][INFO_FIELD_MAXLEN+nb_el(field_suffix)] = {{ 0 }} ;
size_t wlen[buflen] ;
int wcol[buflen] ;
for(i = 0; i < buflen; i++)
{
wlen[i] = mbstowcs(wbuf[i], buf[i], strlen(buf[i]) + 1) ;
wcol[i] = wcswidth(wbuf[i], wlen[i]) ;
if(wcol[i] > maxcol) {
maxcol = wcol[i] ;
}
if(wlen[i] > maxlen) {
maxlen = wlen[i] ;
}
}
for(i = 0; i < buflen; i++)
{
size_t padlen = maxcol - wcol[i] ;
wmemset(wbuf[i] + wlen[i], L' ', padlen) ;
wmemcpy(wbuf[i] + wlen[i] + padlen, field_suffix, nb_el(field_suffix)) ;
wcstombs(fields[i], wbuf[i], sizeof(wbuf[i])) ;
}
}
size_t info_length_from_wchar(char const *str)
{
ssize_t len ;
wchar_t *wcstr ;
if(!str || !str[0]) return 0 ;
len = strlen(str) + 1 ;
wcstr = calloc(len, sizeof(wchar_t)) ;
len = mbstowcs(wcstr, str, len) ;
len = wcswidth(wcstr, len) ;
free(wcstr) ;
return len == -1 ? 0 : (size_t)len ;
}
size_t info_display_field_name(char const *field)
{
size_t len = 0 ;
if(field)
{
len = info_length_from_wchar(field) + 1 ;
if (!bprintf(buffer_1,"%s%s%s ", log_color->info, field, log_color->off)) log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
return len ;
}
void info_display_list(char const *field, stralloc *list)
{
size_t a = 0 , b, cols, padding = 0, slen = 0 ;
unsigned short maxcols = info_getcols_fd(1) ;
padding = info_length_from_wchar(field) + 1 ;
cols = padding ;
for (; a < list->len ; a += strlen(list->s + a) + 1)
{
char const *str = list->s + a ;
slen = info_length_from_wchar(str) ;
if((maxcols > padding) && (cols + slen + 2 >= maxcols))
{
cols = padding ;
if (buffer_puts(buffer_1,"\n") == -1) goto err ;
for(b = 1 ; b <= padding ; b++)
if (buffer_puts(buffer_1," ") == -1) goto err ;
}
else if (cols != padding)
{
if (buffer_puts(buffer_1," ") == -1) goto err ;
cols += 2 ;
}
if (!bprintf(buffer_1,"%s",str)) goto err ;
cols += slen ;
}
if (buffer_puts(buffer_1,"\n") == -1) goto err ;
return ;
err:
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
void info_display_nline(char const *field,char const *str)
{
size_t pos = 0, padding = info_length_from_wchar(field) + 1 ;
stralloc tmp = STRALLOC_ZERO ;
stralloc cp = STRALLOC_ZERO ;
if (!stralloc_cats(&tmp,str) ||
!stralloc_0(&tmp)) log_die_nomem("stralloc") ;
if (!sastr_split_string_in_nline(&tmp)) log_dieu(LOG_EXIT_SYS,"split string in nline") ;
for (;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1)
{
cp.len = 0 ;
if (!stralloc_cats(&cp,tmp.s + pos) ||
!stralloc_0(&cp)) log_die_nomem("stralloc") ;
if (field)
{
if (pos)
{
if (!bprintf(buffer_1,"%*s",padding,""))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
}
info_display_list(field,&cp) ;
}
stralloc_free(&tmp) ;
stralloc_free(&cp) ;
}
void info_graph_display(ss_resolve_t *res, depth_t *depth, int last, int padding, ss_resolve_graph_style *style)
{
s6_svstatus_t status = S6_SVSTATUS_ZERO ;
char *name = res->sa.s + res->name ;
if (res->type == CLASSIC || res->type == LONGRUN)
{
s6_svstatus_read(res->sa.s + res->runat ,&status) ;
}
else status.pid = 0 ;
const char *tip = "" ;
int level = 1 ;
tip = last ? style->last : style->tip ;
while(depth->prev)
depth = depth->prev ;
while(depth->next)
{
if (!bprintf(buffer_1,"%*s%-*s",style->indent * (depth->level - level) + (level == 1 ? padding : 0), "", style->indent, style->limb)) return ;
level = depth->level + 1 ;
depth = depth->next ;
}
if (!bprintf(buffer_1,"%*s%*s%s(%s%i%s,%s%s%s,%s) %s",level == 1 ? padding : 0,"", style->indent * (depth->level - level), "", tip, status.pid ? log_color->valid : log_color->off,status.pid ? status.pid : 0,log_color->off, res->disen ? log_color->off : log_color->error, res->disen ? "Enabled" : "Disabled",log_color->off,get_keybyid(res->type), name)) return ;
if (buffer_putsflush(buffer_1,"\n") < 0) return ;
}
int info_walk(ss_resolve_t *res,char const *src,int reverse, depth_t *depth, int padding, ss_resolve_graph_style *style)
{
size_t pos = 0, idx = 0 ;
stralloc sadeps = STRALLOC_ZERO ;
ss_resolve_t dres = RESOLVE_ZERO ;
if((!res->ndeps) || (depth->level > MAXDEPTH))
goto freed ;
if (!sastr_clean_string(&sadeps,res->sa.s + res->deps)) goto err ;
if (reverse) sastr_reverse(&sadeps) ;
for(; pos < sadeps.len ; pos += strlen(sadeps.s + pos) + 1,idx++ )
{
int last = idx + 1 < res->ndeps ? 0 : 1 ;
char *name = sadeps.s + pos ;
if (!ss_resolve_check(src,name)) goto err ;
if (!ss_resolve_read(&dres,src,name)) goto err ;
info_graph_display(&dres, depth, last,padding,style) ;
if (dres.ndeps)
{
depth_t d =
{
depth,
NULL,
depth->level + 1
} ;
depth->next = &d;
if(last)
{
if(depth->prev)
{
depth->prev->next = &d;
d.prev = depth->prev;
depth = &d;
}
else
d.prev = NULL;
}
if (!info_walk(&dres, src, reverse, &d, padding, style)) goto err;
depth->next = NULL;
}
}
freed:
ss_resolve_free(&dres) ;
stralloc_free(&sadeps) ;
return 1 ;
err:
ss_resolve_free(&dres) ;
stralloc_free(&sadeps) ;
return 0 ;
}
int info_graph_init (ss_resolve_t *res,char const *src,unsigned int reverse, int padding, ss_resolve_graph_style *style)
{
depth_t d = {
NULL,
NULL,
1
} ;
if(!info_walk(res,src,reverse,&d,padding,style)) return 0 ;
return 1 ;
}