/* Copyright 2000, 2001, 2002 Laurent Wacrenier This file is part of libhome libhome is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libhome 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libhome; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" static char const rcsid[] UNUSED = "$Id: rewrite.c,v 1.13 2005/06/23 13:02:59 lwa Exp $"; #define passwd system_passwd #include #include #include #include #include #undef passwd #include "hparam.h" #define NMATCH 10 #define TOOLONG "string too long in rewrite" static int rewrite1(char *line, regmatch_t *pmatch, char *action, char *dest) { int len=LINEMAX; while(*action) { switch(*action) { case '$': { int rule; int plen; rule=*++action-'0'; if (rule<0 || rule>9) { home_retry("bad rewrite number %d", rule); return 0; } plen=pmatch[rule].rm_eo-pmatch[rule].rm_so; action++; if ((len-=plen)<0) { home_error(TOOLONG); return 0; } memcpy(dest, line+pmatch[rule].rm_so, plen); dest+=plen; } break; case '\\': if ((len-=2)<0) { home_error(TOOLONG); return 0; } if (*++action) *dest++=*action++; else return 1; break; default: if (--len<0) { home_error(TOOLONG); return 0 ; } *dest++=*action++; } } *dest=0; return 0; } /* * options: * HREW_FREE libère l'ancienne valeur si elle a changé * HREW_NONULL renvoi NULL si une valeur réécrite est vide * HREW_FIRST arrête à la première occurence * HREW_MUST toutes les lignes doivent matcher */ char *hrewrite(struct regexp_list *rl, char *line, const int options) { char *line_bak=NULL; char xline1[LINEMAX]; char xline2[LINEMAX]; if (line==NULL) return NULL; if (options & HREW_FREE) line_bak=line; while(rl) { regmatch_t pmatch[NMATCH]; int ret; ret=regexec(rl->preg, line, NMATCH, pmatch, 0); if (ret!=0) { if (options & HREW_MUST) { home_error("unmatched '%s'", line); line=NULL; break; } } else { char *dest = (line == xline1 ? xline2 : xline1); if (rewrite1(line, pmatch, rl->action, dest)) { line=NULL; break; } if (*dest==0 && options & HREW_NONULL) { home_error("refused '%s'", line); line=NULL; break; } line=dest; if (options & HREW_FIRST) break; } rl=rl->next; } if (options&HREW_FREE) { if (line != line_bak) free(line_bak); else return line; } if (line && (line=strdup(line))==NULL) return hmalloc_error("rewrite", NULL); return line; } unsigned long home_calc(unsigned long n, char **formula) { if (formula) { while(*formula) { char *op = *formula; switch(*op) { case '+': n += strtol(op +1, NULL, 10); break; case '-': n -= strtol(op + 1, NULL, 10); break; } formula++; } } return n; } unsigned long home_uncalc(unsigned long n, char **formula) { if (formula) { char **f = formula; int len = -1; while(*f++) len ++; while(len>=0) { char *op = formula[len]; switch(*op) { case '+': n -= strtol(op +1, NULL, 10); break; case '-': n += strtol(op + 1, NULL, 10); break; } len --; } } return n; }