This commit changes how ack(1) parses backslashes in its descr files. Before this commit, ack set the high bit of each character escaped by a backslash, and later cleared all high bits in command arguments, but this lost the high bits in non-ASCII filenames. After this commit, ack keeps backslashes in strings while processing them. Functions scanvars(), scanexpr(), doassign(), unravel(), addargs() now understand backslashes. I remove from ack_basename() the warning about non-ASCII characters. This commit makes some incompatible changes for backslashes in descr files. None of our descr files uses backslashes, except for those backslashes that continue lines, and there are no changes for those backslashes. The problem with non-ASCII filenames had its cause in a feature that we weren't using. With this commit, ack now understands backslashes after the = sign in both "var NAME=value" and "mapflag -flag NAME=value". Before, ack never scanned backslashes in "var" lines, so "var A=\{B}" failed to prevent expansion of B. Now it does. Before, ack did scan for backslashes in the "-flag NAME=" part of "mapflag" lines. Now it doesn't, so it is no longer possible to map a flag that contains a literal space, tab, or star "*". I removed the expansion of "{{" to "{". One can use "\{" for a literal "{", and "\{" now works in "var" lines. Before and now, ack never expanded "{" in flags for "mapflag", so the correct way to map a literal flag "-{" remains "mapflag -{ ...", not "mapflag -{{ ...". (The other way "mapflag -\{ ..." stops working with this commit.) Backslashes in strange places, like "{NA\ME}", probably have different behavior now. Backslashes in "program" lines now work. Before, ack scanned for backslashes there but forgot to clear the high bits later. Escaping < or > as \< or \> now works, and prevents substitution of the input or output file paths. Before, ack only expanded the first < or > in each argument. Now, it expands every unescaped < or > in an argument, but this is an accident of how I rewrote the code. I don't suggest to put more than one each of < or > in a command. The code no longer optimizes away its recursive calls when the argument is "<". The code continues to set or clear the high bit NO_SCAN on the first characters of flags. This doesn't seem to be a problem, because flags usually begin with an ASCII hyphen '-'.
97 lines
2.9 KiB
C
97 lines
2.9 KiB
C
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
#ifndef NORCSID
|
|
#define RCS_ACK "$Id$"
|
|
#endif
|
|
|
|
#include <stdlib.h> /* size_t, free() */
|
|
|
|
/****************************************************************************/
|
|
/* User settable options */
|
|
/****************************************************************************/
|
|
|
|
#define FRONTENDS "fe" /* The front-end definitions */
|
|
#define TMPNAME "Ack_%x" /* Naming of temp. files */
|
|
|
|
/****************************************************************************/
|
|
/* Internal mnemonics, should not be tinkered with */
|
|
/****************************************************************************/
|
|
|
|
/* The names of some string variables */
|
|
|
|
#define HOME "EM"
|
|
#define RTS "RTS"
|
|
#define HEAD "HEAD"
|
|
#define TAIL "TAIL"
|
|
#define SRC "SOURCE"
|
|
#define LIBVAR "LNAME"
|
|
#define SUFFIX "SUFFIX"
|
|
|
|
/* Intended for flags, possibly in bit fields */
|
|
|
|
#define YES 1
|
|
#define NO 0
|
|
#define MAYBE 2
|
|
|
|
#define EXTERN extern
|
|
|
|
#define SUFCHAR '.' /* Start of SUFFIX in file name */
|
|
#define SPACE ' '
|
|
#define TAB '\t'
|
|
#define EQUAL '='
|
|
#define S_VAR '{' /* Start of variable */
|
|
#define C_VAR '}' /* End of variable */
|
|
#define A_VAR '?' /* Variable alternative */
|
|
#define BSLASH '\\' /* Backslash */
|
|
#define STAR '*' /* STAR */
|
|
#define C_IN '<' /* Token specifying input */
|
|
#define C_OUT '>' /* Token specifying output */
|
|
#define S_EXPR '(' /* Start of expression */
|
|
#define C_EXPR ')' /* End of expression */
|
|
#define M_EXPR ':' /* Middle of two suffix lists */
|
|
#define T_EXPR '=' /* Start of tail */
|
|
|
|
#define NO_SCAN 0200 /* Bit set in character to defeat recogn. */
|
|
|
|
typedef struct {
|
|
char *p_path; /* points to the full pathname */
|
|
int p_keeps:1; /* The string should be thrown when unused */
|
|
int p_keep:1; /* The file should be thrown away after use */
|
|
} path ;
|
|
|
|
#define p_cont(elem) ((path *)l_content(elem))
|
|
|
|
/* Own routines */
|
|
|
|
/* rmach.c */
|
|
void setlist(char *);
|
|
|
|
/* svars.c */
|
|
void setsvar(char *, char *);
|
|
void setpvar(char *, char *(*)(void));
|
|
char *getvar(const char *);
|
|
|
|
/* util.c */
|
|
char *ack_basename(const char *);
|
|
char *skipblank(char *);
|
|
char *firstblank(char *);
|
|
void fatal(const char *, ...);
|
|
void vprint(const char *, ...);
|
|
void fuerror(const char *, ...);
|
|
void werror(const char *, ...);
|
|
void quit(int);
|
|
char *keeps(const char *);
|
|
#define throws(str) free(str)
|
|
void *getcore(size_t);
|
|
void *changecore(void *, size_t);
|
|
#define freecore(area) free(area)
|
|
|
|
#define DEBUG 1 /* Allow debugging of Ack */
|
|
|
|
#ifndef DEBUG
|
|
# define debug 0 /* To surprise all these 'if ( debug ) 's */
|
|
#else
|
|
extern int debug ;
|
|
#endif
|