mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-18 02:55:12 +00:00
outsource the whole template object machinery
This commit is contained in:
parent
c91957e83a
commit
ff199355f6
@ -171,6 +171,8 @@ conky_SOURCES = \
|
|||||||
$(weather) \
|
$(weather) \
|
||||||
$(lua) \
|
$(lua) \
|
||||||
$(solaris) \
|
$(solaris) \
|
||||||
|
template.c \
|
||||||
|
template.h \
|
||||||
timed_thread.c \
|
timed_thread.c \
|
||||||
timed_thread.h \
|
timed_thread.h \
|
||||||
mboxscan.c \
|
mboxscan.c \
|
||||||
@ -239,6 +241,8 @@ EXTRA_DIST = \
|
|||||||
specials.h \
|
specials.h \
|
||||||
tailhead.c \
|
tailhead.c \
|
||||||
tailhead.h \
|
tailhead.h \
|
||||||
|
template.c \
|
||||||
|
template.h \
|
||||||
top.h \
|
top.h \
|
||||||
diskio.h \
|
diskio.h \
|
||||||
x11.c \
|
x11.c \
|
||||||
|
30
src/conky.c
30
src/conky.c
@ -87,6 +87,7 @@
|
|||||||
#include "mboxscan.h"
|
#include "mboxscan.h"
|
||||||
#include "specials.h"
|
#include "specials.h"
|
||||||
#include "temphelper.h"
|
#include "temphelper.h"
|
||||||
|
#include "template.h"
|
||||||
#include "tailhead.h"
|
#include "tailhead.h"
|
||||||
#include "top.h"
|
#include "top.h"
|
||||||
|
|
||||||
@ -381,13 +382,6 @@ static int sensor_device;
|
|||||||
long color0, color1, color2, color3, color4, color5, color6, color7, color8,
|
long color0, color1, color2, color3, color4, color5, color6, color7, color8,
|
||||||
color9;
|
color9;
|
||||||
|
|
||||||
static char *template[MAX_TEMPLATES];
|
|
||||||
|
|
||||||
char **get_templates(void)
|
|
||||||
{
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* maximum size of config TEXT buffer, i.e. below TEXT line. */
|
/* maximum size of config TEXT buffer, i.e. below TEXT line. */
|
||||||
unsigned int max_user_text;
|
unsigned int max_user_text;
|
||||||
|
|
||||||
@ -4886,12 +4880,7 @@ void clean_up(void *memtofree1, void* memtofree2)
|
|||||||
|
|
||||||
#endif /* X11 */
|
#endif /* X11 */
|
||||||
|
|
||||||
for (i = 0; i < MAX_TEMPLATES; i++) {
|
free_templates();
|
||||||
if (template[i]) {
|
|
||||||
free(template[i]);
|
|
||||||
template[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free_text_objects(&global_root_object, 0);
|
free_text_objects(&global_root_object, 0);
|
||||||
if (tmpstring1) {
|
if (tmpstring1) {
|
||||||
@ -5035,7 +5024,6 @@ static void set_default_configurations_for_x(void)
|
|||||||
|
|
||||||
static void set_default_configurations(void)
|
static void set_default_configurations(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
#ifdef MPD
|
#ifdef MPD
|
||||||
char *mpd_env_host;
|
char *mpd_env_host;
|
||||||
char *mpd_env_port;
|
char *mpd_env_port;
|
||||||
@ -5141,11 +5129,7 @@ static void set_default_configurations(void)
|
|||||||
info.x11.desktop.name = NULL;
|
info.x11.desktop.name = NULL;
|
||||||
#endif /* X11 */
|
#endif /* X11 */
|
||||||
|
|
||||||
for (i = 0; i < MAX_TEMPLATES; i++) {
|
free_templates();
|
||||||
if (template[i])
|
|
||||||
free(template[i]);
|
|
||||||
template[i] = strdup("");
|
|
||||||
}
|
|
||||||
|
|
||||||
free(current_mail_spool);
|
free(current_mail_spool);
|
||||||
{
|
{
|
||||||
@ -5463,12 +5447,8 @@ char load_config_file(const char *f)
|
|||||||
#endif /* X11 */
|
#endif /* X11 */
|
||||||
#define TEMPLATE_CONF(n) \
|
#define TEMPLATE_CONF(n) \
|
||||||
CONF("template"#n) { \
|
CONF("template"#n) { \
|
||||||
if (value) { \
|
if (set_template(n, value)) \
|
||||||
free(template[n]); \
|
|
||||||
template[n] = strdup(value); \
|
|
||||||
} else { \
|
|
||||||
CONF_ERR; \
|
CONF_ERR; \
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
TEMPLATE_CONF(0)
|
TEMPLATE_CONF(0)
|
||||||
TEMPLATE_CONF(1)
|
TEMPLATE_CONF(1)
|
||||||
@ -6604,7 +6584,7 @@ int main(int argc, char **argv)
|
|||||||
max_user_text = MAX_USER_TEXT_DEFAULT;
|
max_user_text = MAX_USER_TEXT_DEFAULT;
|
||||||
current_config = 0;
|
current_config = 0;
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
memset(template, 0, sizeof(template));
|
free_templates();
|
||||||
clear_net_stats();
|
clear_net_stats();
|
||||||
|
|
||||||
#ifdef TCP_PORT_MONITOR
|
#ifdef TCP_PORT_MONITOR
|
||||||
|
192
src/core.c
192
src/core.c
@ -46,6 +46,7 @@
|
|||||||
#include "mboxscan.h"
|
#include "mboxscan.h"
|
||||||
#include "specials.h"
|
#include "specials.h"
|
||||||
#include "temphelper.h"
|
#include "temphelper.h"
|
||||||
|
#include "template.h"
|
||||||
#include "tailhead.h"
|
#include "tailhead.h"
|
||||||
#include "top.h"
|
#include "top.h"
|
||||||
|
|
||||||
@ -2173,197 +2174,6 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* backslash_escape - do the actual substitution task for template objects
|
|
||||||
*
|
|
||||||
* The field templates is used for substituting the \N occurences. Set it to
|
|
||||||
* NULL to leave them as they are.
|
|
||||||
*/
|
|
||||||
static char *backslash_escape(const char *src, char **templates, unsigned int template_count)
|
|
||||||
{
|
|
||||||
char *src_dup;
|
|
||||||
const char *p;
|
|
||||||
unsigned int dup_idx = 0, dup_len;
|
|
||||||
|
|
||||||
dup_len = strlen(src) + 1;
|
|
||||||
src_dup = malloc(dup_len * sizeof(char));
|
|
||||||
|
|
||||||
p = src;
|
|
||||||
while (*p) {
|
|
||||||
switch (*p) {
|
|
||||||
case '\\':
|
|
||||||
if (!*(p + 1))
|
|
||||||
break;
|
|
||||||
if (*(p + 1) == '\\') {
|
|
||||||
src_dup[dup_idx++] = '\\';
|
|
||||||
p++;
|
|
||||||
} else if (*(p + 1) == ' ') {
|
|
||||||
src_dup[dup_idx++] = ' ';
|
|
||||||
p++;
|
|
||||||
} else if (*(p + 1) == 'n') {
|
|
||||||
src_dup[dup_idx++] = '\n';
|
|
||||||
p++;
|
|
||||||
} else if (templates) {
|
|
||||||
unsigned int tmpl_num;
|
|
||||||
int digits;
|
|
||||||
if ((sscanf(p + 1, "%u%n", &tmpl_num, &digits) <= 0) ||
|
|
||||||
(tmpl_num > template_count))
|
|
||||||
break;
|
|
||||||
dup_len += strlen(templates[tmpl_num - 1]);
|
|
||||||
src_dup = realloc(src_dup, dup_len * sizeof(char));
|
|
||||||
sprintf(src_dup + dup_idx, "%s", templates[tmpl_num - 1]);
|
|
||||||
dup_idx += strlen(templates[tmpl_num - 1]);
|
|
||||||
p += digits;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
src_dup[dup_idx++] = *p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
src_dup[dup_idx] = '\0';
|
|
||||||
src_dup = realloc(src_dup, (strlen(src_dup) + 1) * sizeof(char));
|
|
||||||
return src_dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle_template_object - core logic of the template object
|
|
||||||
*
|
|
||||||
* use config variables like this:
|
|
||||||
* template1 = "$\1\2"
|
|
||||||
* template2 = "\1: ${fs_bar 4,100 \2} ${fs_used \2} / ${fs_size \2}"
|
|
||||||
*
|
|
||||||
* and use them like this:
|
|
||||||
* ${template1 node name}
|
|
||||||
* ${template2 root /}
|
|
||||||
* ${template2 cdrom /mnt/cdrom}
|
|
||||||
*/
|
|
||||||
static char *handle_template(const char *tmpl, const char *args)
|
|
||||||
{
|
|
||||||
char *args_dup = NULL;
|
|
||||||
char *p, *p_old;
|
|
||||||
char **argsp = NULL;
|
|
||||||
unsigned int argcnt = 0, template_idx, i;
|
|
||||||
char *eval_text;
|
|
||||||
|
|
||||||
if ((sscanf(tmpl, "template%u", &template_idx) != 1) ||
|
|
||||||
(template_idx >= MAX_TEMPLATES))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(args) {
|
|
||||||
args_dup = strdup(args);
|
|
||||||
p = args_dup;
|
|
||||||
while (*p) {
|
|
||||||
while (*p && (*p == ' ' && (p == args_dup || *(p - 1) != '\\')))
|
|
||||||
p++;
|
|
||||||
if (p > args_dup && *(p - 1) == '\\')
|
|
||||||
p--;
|
|
||||||
p_old = p;
|
|
||||||
while (*p && (*p != ' ' || (p > args_dup && *(p - 1) == '\\')))
|
|
||||||
p++;
|
|
||||||
if (*p) {
|
|
||||||
(*p) = '\0';
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
argsp = realloc(argsp, ++argcnt * sizeof(char *));
|
|
||||||
argsp[argcnt - 1] = p_old;
|
|
||||||
}
|
|
||||||
for (i = 0; i < argcnt; i++) {
|
|
||||||
char *tmp;
|
|
||||||
tmp = backslash_escape(argsp[i], NULL, 0);
|
|
||||||
DBGP2("%s: substituted arg '%s' to '%s'", tmpl, argsp[i], tmp);
|
|
||||||
argsp[i] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_text = backslash_escape(get_templates()[template_idx], argsp, argcnt);
|
|
||||||
DBGP("substituted %s, output is '%s'", tmpl, eval_text);
|
|
||||||
free(args_dup);
|
|
||||||
for (i = 0; i < argcnt; i++)
|
|
||||||
free(argsp[i]);
|
|
||||||
free(argsp);
|
|
||||||
return eval_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *find_and_replace_templates(const char *inbuf)
|
|
||||||
{
|
|
||||||
char *outbuf, *indup, *p, *o, *templ, *args, *tmpl_out;
|
|
||||||
int stack, outlen;
|
|
||||||
|
|
||||||
outlen = strlen(inbuf) + 1;
|
|
||||||
o = outbuf = calloc(outlen, sizeof(char));
|
|
||||||
memset(outbuf, 0, outlen * sizeof(char));
|
|
||||||
|
|
||||||
p = indup = strdup(inbuf);
|
|
||||||
while (*p) {
|
|
||||||
while (*p && *p != '$')
|
|
||||||
*(o++) = *(p++);
|
|
||||||
|
|
||||||
if (!(*p))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (strncmp(p, "$template", 9) && strncmp(p, "${template", 10)) {
|
|
||||||
*(o++) = *(p++);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(p + 1) == '{') {
|
|
||||||
p += 2;
|
|
||||||
templ = p;
|
|
||||||
while (*p && !isspace(*p) && *p != '{' && *p != '}')
|
|
||||||
p++;
|
|
||||||
if (*p == '}')
|
|
||||||
args = NULL;
|
|
||||||
else
|
|
||||||
args = p;
|
|
||||||
|
|
||||||
stack = 1;
|
|
||||||
while (*p && stack > 0) {
|
|
||||||
if (*p == '{')
|
|
||||||
stack++;
|
|
||||||
else if (*p == '}')
|
|
||||||
stack--;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (stack == 0) {
|
|
||||||
// stack is empty. that means the previous char was }, so we zero it
|
|
||||||
*(p - 1) = '\0';
|
|
||||||
} else {
|
|
||||||
// we ran into the end of string without finding a closing }, bark
|
|
||||||
CRIT_ERR(NULL, NULL, "cannot find a closing '}' in template expansion");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
templ = p + 1;
|
|
||||||
while (*p && !isspace(*p))
|
|
||||||
p++;
|
|
||||||
args = NULL;
|
|
||||||
}
|
|
||||||
tmpl_out = handle_template(templ, args);
|
|
||||||
if (tmpl_out) {
|
|
||||||
outlen += strlen(tmpl_out);
|
|
||||||
*o = '\0';
|
|
||||||
outbuf = realloc(outbuf, outlen * sizeof(char));
|
|
||||||
strcat (outbuf, tmpl_out);
|
|
||||||
free(tmpl_out);
|
|
||||||
o = outbuf + strlen(outbuf);
|
|
||||||
} else {
|
|
||||||
NORM_ERR("failed to handle template '%s' with args '%s'", templ, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*o = '\0';
|
|
||||||
outbuf = realloc(outbuf, (strlen(outbuf) + 1) * sizeof(char));
|
|
||||||
free(indup);
|
|
||||||
return outbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int text_contains_templates(const char *text)
|
|
||||||
{
|
|
||||||
if (strcasestr(text, "${template") != NULL)
|
|
||||||
return 1;
|
|
||||||
if (strcasestr(text, "$template") != NULL)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* - assumes that *string is '#'
|
* - assumes that *string is '#'
|
||||||
* - removes the part from '#' to the end of line ('\n' or '\0')
|
* - removes the part from '#' to the end of line ('\n' or '\0')
|
||||||
|
270
src/template.c
Normal file
270
src/template.c
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
||||||
|
*
|
||||||
|
* Conky, a system monitor, based on torsmo
|
||||||
|
*
|
||||||
|
* Any original torsmo code is licensed under the BSD license
|
||||||
|
*
|
||||||
|
* All code written since the fork of torsmo is licensed under the GPL
|
||||||
|
*
|
||||||
|
* Please see COPYING for details
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
|
||||||
|
* Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
|
||||||
|
* (see AUTHORS)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* vim: ts=4 sw=4 noet ai cindent syntax=c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "conky.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
/* The templates defined by the user.
|
||||||
|
*
|
||||||
|
* This is a 1 to 1 mapping from templateN config option to template[N] field. */
|
||||||
|
static char *template[MAX_TEMPLATES];
|
||||||
|
|
||||||
|
/* free all templates
|
||||||
|
*
|
||||||
|
* On first invocation, just memset all pointers to zero, so this function can
|
||||||
|
* be used when initialising data upon startup. */
|
||||||
|
void free_templates(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int initialised = 0;
|
||||||
|
|
||||||
|
if (!initialised) {
|
||||||
|
memset(template, 0, MAX_TEMPLATES * sizeof(char *));
|
||||||
|
initialised = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEMPLATES; i++) {
|
||||||
|
if (template[i]) {
|
||||||
|
free(template[i]);
|
||||||
|
template[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the value of template at index n
|
||||||
|
*
|
||||||
|
* Returns non-zero on illegal arguments passed, zero otherwise. */
|
||||||
|
int set_template(int n, const char *val)
|
||||||
|
{
|
||||||
|
if (n < 0 || n >= MAX_TEMPLATES || !val)
|
||||||
|
return 1;
|
||||||
|
if (template[n])
|
||||||
|
free(template[n]);
|
||||||
|
template[n] = strdup(val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* backslash_escape - do the actual substitution task for template objects
|
||||||
|
*
|
||||||
|
* The field templates is used for substituting the \N occurences. Set it to
|
||||||
|
* NULL to leave them as they are.
|
||||||
|
*/
|
||||||
|
static char *backslash_escape(const char *src, char **templates, unsigned int template_count)
|
||||||
|
{
|
||||||
|
char *src_dup;
|
||||||
|
const char *p;
|
||||||
|
unsigned int dup_idx = 0, dup_len;
|
||||||
|
|
||||||
|
dup_len = strlen(src) + 1;
|
||||||
|
src_dup = malloc(dup_len * sizeof(char));
|
||||||
|
|
||||||
|
p = src;
|
||||||
|
while (*p) {
|
||||||
|
switch (*p) {
|
||||||
|
case '\\':
|
||||||
|
if (!*(p + 1))
|
||||||
|
break;
|
||||||
|
if (*(p + 1) == '\\') {
|
||||||
|
src_dup[dup_idx++] = '\\';
|
||||||
|
p++;
|
||||||
|
} else if (*(p + 1) == ' ') {
|
||||||
|
src_dup[dup_idx++] = ' ';
|
||||||
|
p++;
|
||||||
|
} else if (*(p + 1) == 'n') {
|
||||||
|
src_dup[dup_idx++] = '\n';
|
||||||
|
p++;
|
||||||
|
} else if (templates) {
|
||||||
|
unsigned int tmpl_num;
|
||||||
|
int digits;
|
||||||
|
if ((sscanf(p + 1, "%u%n", &tmpl_num, &digits) <= 0) ||
|
||||||
|
(tmpl_num > template_count))
|
||||||
|
break;
|
||||||
|
dup_len += strlen(templates[tmpl_num - 1]);
|
||||||
|
src_dup = realloc(src_dup, dup_len * sizeof(char));
|
||||||
|
sprintf(src_dup + dup_idx, "%s", templates[tmpl_num - 1]);
|
||||||
|
dup_idx += strlen(templates[tmpl_num - 1]);
|
||||||
|
p += digits;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
src_dup[dup_idx++] = *p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
src_dup[dup_idx] = '\0';
|
||||||
|
src_dup = realloc(src_dup, (strlen(src_dup) + 1) * sizeof(char));
|
||||||
|
return src_dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle_template_object - core logic of the template object
|
||||||
|
*
|
||||||
|
* use config variables like this:
|
||||||
|
* template1 = "$\1\2"
|
||||||
|
* template2 = "\1: ${fs_bar 4,100 \2} ${fs_used \2} / ${fs_size \2}"
|
||||||
|
*
|
||||||
|
* and use them like this:
|
||||||
|
* ${template1 node name}
|
||||||
|
* ${template2 root /}
|
||||||
|
* ${template2 cdrom /mnt/cdrom}
|
||||||
|
*/
|
||||||
|
static char *handle_template(const char *tmpl, const char *args)
|
||||||
|
{
|
||||||
|
char *args_dup = NULL;
|
||||||
|
char *p, *p_old;
|
||||||
|
char **argsp = NULL;
|
||||||
|
unsigned int argcnt = 0, template_idx, i;
|
||||||
|
char *eval_text;
|
||||||
|
|
||||||
|
if ((sscanf(tmpl, "template%u", &template_idx) != 1) ||
|
||||||
|
(template_idx >= MAX_TEMPLATES))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(args) {
|
||||||
|
args_dup = strdup(args);
|
||||||
|
p = args_dup;
|
||||||
|
while (*p) {
|
||||||
|
while (*p && (*p == ' ' && (p == args_dup || *(p - 1) != '\\')))
|
||||||
|
p++;
|
||||||
|
if (p > args_dup && *(p - 1) == '\\')
|
||||||
|
p--;
|
||||||
|
p_old = p;
|
||||||
|
while (*p && (*p != ' ' || (p > args_dup && *(p - 1) == '\\')))
|
||||||
|
p++;
|
||||||
|
if (*p) {
|
||||||
|
(*p) = '\0';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
argsp = realloc(argsp, ++argcnt * sizeof(char *));
|
||||||
|
argsp[argcnt - 1] = p_old;
|
||||||
|
}
|
||||||
|
for (i = 0; i < argcnt; i++) {
|
||||||
|
char *tmp;
|
||||||
|
tmp = backslash_escape(argsp[i], NULL, 0);
|
||||||
|
DBGP2("%s: substituted arg '%s' to '%s'", tmpl, argsp[i], tmp);
|
||||||
|
argsp[i] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_text = backslash_escape(template[template_idx], argsp, argcnt);
|
||||||
|
DBGP("substituted %s, output is '%s'", tmpl, eval_text);
|
||||||
|
free(args_dup);
|
||||||
|
for (i = 0; i < argcnt; i++)
|
||||||
|
free(argsp[i]);
|
||||||
|
free(argsp);
|
||||||
|
return eval_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search inbuf and replace all found template object references
|
||||||
|
* with the substituted value. */
|
||||||
|
char *find_and_replace_templates(const char *inbuf)
|
||||||
|
{
|
||||||
|
char *outbuf, *indup, *p, *o, *templ, *args, *tmpl_out;
|
||||||
|
int stack, outlen;
|
||||||
|
|
||||||
|
outlen = strlen(inbuf) + 1;
|
||||||
|
o = outbuf = calloc(outlen, sizeof(char));
|
||||||
|
memset(outbuf, 0, outlen * sizeof(char));
|
||||||
|
|
||||||
|
p = indup = strdup(inbuf);
|
||||||
|
while (*p) {
|
||||||
|
while (*p && *p != '$')
|
||||||
|
*(o++) = *(p++);
|
||||||
|
|
||||||
|
if (!(*p))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strncmp(p, "$template", 9) && strncmp(p, "${template", 10)) {
|
||||||
|
*(o++) = *(p++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*(p + 1) == '{') {
|
||||||
|
p += 2;
|
||||||
|
templ = p;
|
||||||
|
while (*p && !isspace(*p) && *p != '{' && *p != '}')
|
||||||
|
p++;
|
||||||
|
if (*p == '}')
|
||||||
|
args = NULL;
|
||||||
|
else
|
||||||
|
args = p;
|
||||||
|
|
||||||
|
stack = 1;
|
||||||
|
while (*p && stack > 0) {
|
||||||
|
if (*p == '{')
|
||||||
|
stack++;
|
||||||
|
else if (*p == '}')
|
||||||
|
stack--;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (stack == 0) {
|
||||||
|
// stack is empty. that means the previous char was }, so we zero it
|
||||||
|
*(p - 1) = '\0';
|
||||||
|
} else {
|
||||||
|
// we ran into the end of string without finding a closing }, bark
|
||||||
|
CRIT_ERR(NULL, NULL, "cannot find a closing '}' in template expansion");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templ = p + 1;
|
||||||
|
while (*p && !isspace(*p))
|
||||||
|
p++;
|
||||||
|
args = NULL;
|
||||||
|
}
|
||||||
|
tmpl_out = handle_template(templ, args);
|
||||||
|
if (tmpl_out) {
|
||||||
|
outlen += strlen(tmpl_out);
|
||||||
|
*o = '\0';
|
||||||
|
outbuf = realloc(outbuf, outlen * sizeof(char));
|
||||||
|
strcat (outbuf, tmpl_out);
|
||||||
|
free(tmpl_out);
|
||||||
|
o = outbuf + strlen(outbuf);
|
||||||
|
} else {
|
||||||
|
NORM_ERR("failed to handle template '%s' with args '%s'", templ, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*o = '\0';
|
||||||
|
outbuf = realloc(outbuf, (strlen(outbuf) + 1) * sizeof(char));
|
||||||
|
free(indup);
|
||||||
|
return outbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check text for any template object references */
|
||||||
|
int text_contains_templates(const char *text)
|
||||||
|
{
|
||||||
|
if (strcasestr(text, "${template") != NULL)
|
||||||
|
return 1;
|
||||||
|
if (strcasestr(text, "$template") != NULL)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
41
src/template.h
Normal file
41
src/template.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
||||||
|
*
|
||||||
|
* Conky, a system monitor, based on torsmo
|
||||||
|
*
|
||||||
|
* Any original torsmo code is licensed under the BSD license
|
||||||
|
*
|
||||||
|
* All code written since the fork of torsmo is licensed under the GPL
|
||||||
|
*
|
||||||
|
* Please see COPYING for details
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
|
||||||
|
* Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
|
||||||
|
* (see AUTHORS)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* vim: ts=4 sw=4 noet ai cindent syntax=c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TEMPLATE_H
|
||||||
|
#define _TEMPLATE_H
|
||||||
|
|
||||||
|
void free_templates(void);
|
||||||
|
int set_template(int, const char *);
|
||||||
|
|
||||||
|
char *find_and_replace_templates(const char *);
|
||||||
|
int text_contains_templates(const char *);
|
||||||
|
|
||||||
|
#endif /* _TEMPLATE_H */
|
Loading…
Reference in New Issue
Block a user