summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-09-15 13:36:43 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-09-15 13:36:43 -0700
commitab9826be651451405d88e79bbdf5872046684ee5 (patch)
tree9d4a8334367c7680aecd611cc76d5d9e8c1b5b98
parent09680830758c7a0ab147ae96d8ca37291fe9d1bf (diff)
downloadman-ab9826be651451405d88e79bbdf5872046684ee5.tar.gz
man-ab9826be651451405d88e79bbdf5872046684ee5.tar.bz2
man-ab9826be651451405d88e79bbdf5872046684ee5.zip
Fix \n interpolation; implement while.
The \n interpolation was not working: not substituting the result. When this logic was added, then this was happening even during expression evaluation. The right fix seems to be that scan_expression function needs to suppress output! Implemented the .while operator. str_to_code needed to be fixed so it only bangs together up to four characters, so that we can recognize "while" as "whil". Hack hack! Introduced the V4 macro for four character codes.
-rw-r--r--man2html/defs.h1
-rw-r--r--man2html/man2html.c49
2 files changed, 46 insertions, 4 deletions
diff --git a/man2html/defs.h b/man2html/defs.h
index f3e75ef..bfd56a4 100644
--- a/man2html/defs.h
+++ b/man2html/defs.h
@@ -20,6 +20,7 @@ extern STRDEF *chardef, *strdef, *defdef;
extern INTDEF *intdef;
#define V(A,B) ((A)*256+(B))
+#define V4(A,B,C,D) ((((((((A)*256)+(B))*256)+(C))*256)+(D)))
#include <sys/types.h>
extern void stdinit(void);
diff --git a/man2html/man2html.c b/man2html/man2html.c
index 12326c1..115d314 100644
--- a/man2html/man2html.c
+++ b/man2html/man2html.c
@@ -103,14 +103,21 @@ expand_string(int nr)
return NULL;
}
+static char *
+expand_int(int nr)
+{
+ char *num = xmalloc(31);
+ sprintf(num, "%d", nr);
+ return num;
+}
+
static int str_to_code(char *str)
{
- int code = 0, count = 0;
+ int code, count;
- while (*str && !isspace(*str)) {
+ for (count = 0, code = 0; count < 4 && *str && !isspace(*str); count++) {
code *= 256;
code += *str++;
- count++;
}
if (count == 1) {
@@ -665,6 +672,8 @@ scan_escape(char *c) {
c++;
i=V(c[0],c[1]);
c=c+1;
+ } else if (*c=='[') {
+ abort();
} else {
i=V(c[0],' ');
}
@@ -680,7 +689,7 @@ scan_escape(char *c) {
default: intresult=0; break;
}
}
- h="";
+ h=expand_int(intresult);
break;
case 'w':
c++;
@@ -1187,6 +1196,9 @@ scan_table(char *c) {
char *scan_expression(char *c, int *result) {
int value=0,value2,sign=1,opex=0;
char oper='c';
+ int exoutputp = output_possible;
+
+ output_possible = 0;
if (*c=='!') {
c=scan_expression(c+1, &value);
@@ -1318,6 +1330,9 @@ char *scan_expression(char *c, int *result) {
if (*c==')') c++;
}
*result=value;
+
+ output_possible = exoutputp;
+
return c;
}
@@ -1824,6 +1839,32 @@ scan_request(char *c) {
} else
c=skip_till_newline(c);
break;
+ case V4('w','h','i','l'):
+ /* groff extension
+ * .while c anything
+ * .while !c anything
+ * .while N anything
+ * .while !N anything
+ * .while 'string1'string2' anything
+ * .while !'string1'string2' anything
+ */
+ {
+ char *saved_c = c;
+
+ for (;;) {
+ c=saved_c+j;
+ c=scan_expression(c, &i);
+ ifelseval=!i;
+ if (i) {
+ c++;
+ (void) scan_troff(c,1,NULL);
+ } else {
+ c=skip_till_newline(c);
+ break;
+ }
+ }
+ }
+ break;
case V('i','g'): /* .ig: ignore until .. */
{
char *endwith="..\n";