source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Major roff_getname() cleanup.
@ 2014-06-29 22:14 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2014-06-29 22:14 UTC (permalink / raw)
  To: source

Log Message:
-----------
Major roff_getname() cleanup.
* Return the name even if it is terminated by an escape sequence, not a blank.
* Skip the full escape sequence using mandoc_escape(), not just the first byte.
* Make it non-destructive, return the length instead of writing a '\0'.
* Let .ds and .as cope with the above changes to the internal interface.       
* Fix .rm and .rr to accept an escape sequence as the end of a name.
* Fix .nr and .rr to not set/delete a register with an empty name.

Modified Files:
--------------
    mdocml:
        roff.c

Revision Data
-------------
Index: roff.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v
retrieving revision 1.211
retrieving revision 1.212
diff -Lroff.c -Lroff.c -u -p -r1.211 -r1.212
--- roff.c
+++ roff.c
@@ -187,7 +187,7 @@ static	int		 roff_evalstrcond(const char
 static	void		 roff_free1(struct roff *);
 static	void		 roff_freereg(struct roffreg *);
 static	void		 roff_freestr(struct roffkv *);
-static	char		*roff_getname(struct roff *, char **, int, int);
+static	size_t		 roff_getname(struct roff *, char **, int, int);
 static	int		 roff_getnum(const char *, int *, int *);
 static	int		 roff_getop(const char *, int *, char *);
 static	int		 roff_getregn(const struct roff *,
@@ -1318,29 +1318,31 @@ out:
 static enum rofferr
 roff_ds(ROFF_ARGS)
 {
-	char		*name, *string;
+	char		*string;
+	const char	*name;
+	size_t		 namesz;
 
 	/*
-	 * A symbol is named by the first word following the macro
-	 * invocation up to a space.  Its value is anything after the
-	 * name's trailing whitespace and optional double-quote.  Thus,
-	 *
-	 *  [.ds foo "bar  "     ]
-	 *
-	 * will have `bar  "     ' as its value.
+	 * The first word is the name of the string.
+	 * If it is empty or terminated by an escape sequence,
+	 * abort the `ds' request without defining anything.
 	 */
 
-	string = *bufp + pos;
-	name = roff_getname(r, &string, ln, pos);
+	name = string = *bufp + pos;
 	if ('\0' == *name)
 		return(ROFF_IGN);
 
-	/* Read past initial double-quote. */
+	namesz = roff_getname(r, &string, ln, pos);
+	if ('\\' == name[namesz])
+		return(ROFF_IGN);
+
+	/* Read past the initial double-quote, if any. */
 	if ('"' == *string)
 		string++;
 
 	/* The rest is the value. */
-	roff_setstr(r, name, string, ROFF_as == tok);
+	roff_setstrn(&r->strtab, name, namesz, string, strlen(string),
+	    ROFF_as == tok);
 	return(ROFF_IGN);
 }
 
@@ -1654,13 +1656,19 @@ roff_freereg(struct roffreg *reg)
 static enum rofferr
 roff_nr(ROFF_ARGS)
 {
-	const char	*key;
-	char		*val;
+	char		*key, *val;
+	size_t		 keysz;
 	int		 iv;
 	char		 sign;
 
-	val = *bufp + pos;
-	key = roff_getname(r, &val, ln, pos);
+	key = val = *bufp + pos;
+	if ('\0' == *key)
+		return(ROFF_IGN);
+
+	keysz = roff_getname(r, &val, ln, pos);
+	if ('\\' == key[keysz])
+		return(ROFF_IGN);
+	key[keysz] = '\0';
 
 	sign = *val;
 	if ('+' == sign || '-' == sign)
@@ -1676,11 +1684,14 @@ static enum rofferr
 roff_rr(ROFF_ARGS)
 {
 	struct roffreg	*reg, **prev;
-	const char	*name;
-	char		*cp;
+	char		*name, *cp;
+	size_t		 namesz;
 
-	cp = *bufp + pos;
-	name = roff_getname(r, &cp, ln, pos);
+	name = cp = *bufp + pos;
+	if ('\0' == *name)
+		return(ROFF_IGN);
+	namesz = roff_getname(r, &cp, ln, pos);
+	name[namesz] = '\0';
 
 	prev = &r->regtab;
 	while (1) {
@@ -1702,12 +1713,15 @@ roff_rm(ROFF_ARGS)
 {
 	const char	 *name;
 	char		 *cp;
+	size_t		  namesz;
 
 	cp = *bufp + pos;
 	while ('\0' != *cp) {
-		name = roff_getname(r, &cp, ln, (int)(cp - *bufp));
-		if ('\0' != *name)
-			roff_setstr(r, name, NULL, 0);
+		name = cp;
+		namesz = roff_getname(r, &cp, ln, (int)(cp - *bufp));
+		roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0);
+		if ('\\' == name[namesz])
+			break;
 	}
 	return(ROFF_IGN);
 }
@@ -2007,37 +2021,39 @@ roff_userdef(ROFF_ARGS)
 	   ROFF_REPARSE : ROFF_APPEND);
 }
 
-static char *
+static size_t
 roff_getname(struct roff *r, char **cpp, int ln, int pos)
 {
 	char	 *name, *cp;
+	size_t	  namesz;
 
 	name = *cpp;
 	if ('\0' == *name)
-		return(name);
+		return(0);
 
-	/* Read until end of name. */
-	for (cp = name; '\0' != *cp && ' ' != *cp; cp++) {
+	/* Read until end of name and terminate it with NUL. */
+	for (cp = name; 1; cp++) {
+		if ('\0' == *cp || ' ' == *cp) {
+			namesz = cp - name;
+			break;
+		}
 		if ('\\' != *cp)
 			continue;
 		cp++;
 		if ('\\' == *cp)
 			continue;
+		namesz = cp - name - 1;
 		mandoc_msg(MANDOCERR_NAMESC, r->parse, ln, pos, NULL);
-		*cp = '\0';
-		name = cp;
+		mandoc_escape((const char **)&cp, NULL, NULL);
+		break;
 	}
 
-	/* Nil-terminate name. */
-	if ('\0' != *cp)
-		*(cp++) = '\0';
-
 	/* Read past spaces. */
 	while (' ' == *cp)
 		cp++;
 
 	*cpp = cp;
-	return(name);
+	return(namesz);
 }
 
 /*
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-06-29 22:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-29 22:14 mdocml: Major roff_getname() cleanup schwarze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).