📄 ftvar.c
字号:
/* * Copyright (c) 2001 Mark Fullmer and The Ohio State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: ftvar.c,v 1.3 2003/02/13 02:38:43 maf Exp $ */#include "ftconfig.h"#include "ftlib.h"#include <stdlib.h>#include <stddef.h>#include <ctype.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H #include <string.h>#endif/* * function: ftvar_new() * * Create a new variable set. * * Caller must call ftvar_free() to release memory. * * returns: initialized struct * */int ftvar_new(struct ftvar *ftvar){ bzero(ftvar, sizeof *ftvar); FT_SLIST_INIT(&ftvar->entries); return 0;} /* ftvar_new *//* * function: ftvar_free() * * Free storage created by ftvar_new() and calls to ftvar_set() * */void ftvar_free(struct ftvar *ftvar){ struct ftvar_entry *ftve; while (!FT_SLIST_EMPTY(&ftvar->entries)) { ftve = FT_SLIST_FIRST(&ftvar->entries); if (ftve->name) free(ftve->name); if (ftve->val); free(ftve->val); FT_SLIST_REMOVE_HEAD(&ftvar->entries, chain); free(ftve); }} /* ftvar_free *//* * function: ftvar_pset() * * Parse variable binding in form VAR=VALUE and perform a set * * returns <0 error * >=0 ok */int ftvar_pset(struct ftvar *ftvar, char *bind){ char *sm, *n, *v; int ret; ret = -1; /* preserve source string */ if (!(sm = (char*)malloc(strlen(bind)+1))) { fterr_warnx("malloc(%d)", strlen(bind)+1); return -1; } strcpy(sm, bind); for (v = sm; *v && (*v != '='); ++v); /* end of string reached? */ if (!*v) goto out; /* terminate name */ *v = 0; /* value is rest */ v++; /* name is start */ n = sm; ret = ftvar_set(ftvar, n, v);out: free(sm); return ret;} /* ftvar_pset *//* * function: ftvar_set() * * Add or update variable name with value. * * returns <0 error * >=0 ok */int ftvar_set(struct ftvar *ftvar, char *name, char *val){ struct ftvar_entry *ftve; int new; new = 0; if ((!*name) || (!name[0])) return -1; if ((!*val) || (!val[0])) return -1; /* if the entry exists then this is an update */ if ((ftve = ftvar_find(ftvar, name))) { free(ftve->val); ftve->val = (char*)0L; } else { new = 1; if (!(ftve = (struct ftvar_entry*)malloc(sizeof *ftve))) { fterr_warnx("malloc(ftve)"); return -1; } bzero(ftve, sizeof *ftve); if (!(ftve->name = (char*)malloc(strlen(name)+1))) { fterr_warnx("malloc(ftve->name)"); free(ftve); return -1; } strcpy(ftve->name, name); } /* always allocate the new value */ if (!(ftve->val = (char*)malloc(strlen(val)+1))) { fterr_warnx("malloc(ftve->val)"); free(ftve->name); free(ftve); return -1; } strcpy(ftve->val, val); if (new) FT_SLIST_INSERT_HEAD(&ftvar->entries, ftve, chain); return 0;} /* ftvar_set *//* * function: ftvar_find() * * Find an entry by name * * returns entry or 0L if not found */struct ftvar_entry *ftvar_find(struct ftvar *ftvar, char *name){ struct ftvar_entry *ftve; FT_SLIST_FOREACH(ftve, &ftvar->entries, chain) { if (!strcmp(ftve->name, name)) return ftve; } return (struct ftvar_entry*)0L;} /* ftvar_find *//* * function: ftvar_clear() * * Clear/Remove a variable. Variables which are cleared that do not * exist will not produce an error. * */void ftvar_clear(struct ftvar *ftvar, char *name){ struct ftvar_entry *ftve; if ((ftve = ftvar_find(ftvar, name))) { if (ftve->name) free(ftve->name); if (ftve->val) free(ftve->val); FT_SLIST_REMOVE(&ftvar->entries, ftve, ftvar_entry, chain); free(ftve); }} /* ftvar_clear *//* * function: ftvar_evalstr() * * Perform variable substitution on string. Variables start with * @ and end with a non alphanumeric character, ie @TEST. * * If the variable set contains TEST=foo then the evaluated string * "This is a @TEST." will result in "This is a foo." * */int ftvar_evalstr(struct ftvar *ftvar, char *src, char *dst, int dstlen){ struct ftvar_entry *ftve; char *s, *d, *v, saved, *sm, *tmp; int len, ret, invar; d = dst; len = 0; ret = -1; invar = 0; saved = 0; /* preserve source string */ if (!(sm = (char*)malloc(strlen(src)+1))) { fterr_warnx("malloc(%d)", strlen(src)+1); return -1; } s = sm; strcpy(s, src); while (1) { /* end of source string? */ if (!*s) { ret = 0; goto done; } /* end of dst buf? */ if ((len+1) == dstlen) goto done; /* start of var? */ if (*s == '@') { invar = 1; /* yes, work to do later */ } else { d[len++] = *s++; /* no, copy */ } /* end of dst buf? */ if ((len+1) == dstlen) goto done; /* got a var to process? */ if (invar) { /* variable starts after the @ */ v = ++s; /* find end of variable name */ while (*s && isalpha(*s)) ++s; /* null terminate it, saving potential next char */ saved = *s; *s = 0; /* lookup var */ if ((ftve = ftvar_find(ftvar, v))) tmp = ftve->val; /* found it, copy in the value */ else tmp = --v; /* no, copy in the literal with the @ */ while (*tmp && ((len+1) != dstlen)) d[len++] = *tmp++; /* end of dst buf? */ if ((len+1) == dstlen) goto done; /* restore the character lost due to null terminating var name */ if (saved) *s = saved, saved = 0; else ++s; /* done processing variable */ invar = 0; } } ret = 0;done: dst[len] = 0; free(sm); return ret;} /* ftvar_evalstr */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -