summaryrefslogtreecommitdiffstats
path: root/src/cmd/dict/slang.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-25 03:37:45 +0000
committerrsc <devnull@localhost>2003-11-25 03:37:45 +0000
commit08708877939323c1e1cb87210193ec25fc472ff7 (patch)
treebd34e2144a3e9532ab228619d7ae8d4a0078aeeb /src/cmd/dict/slang.c
parent091f74d0a0db5ba1e098a518922525cb032a97b4 (diff)
downloadplan9port-08708877939323c1e1cb87210193ec25fc472ff7.tar.gz
plan9port-08708877939323c1e1cb87210193ec25fc472ff7.zip
add dict
Diffstat (limited to 'src/cmd/dict/slang.c')
-rw-r--r--src/cmd/dict/slang.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/cmd/dict/slang.c b/src/cmd/dict/slang.c
new file mode 100644
index 00000000..bd32b976
--- /dev/null
+++ b/src/cmd/dict/slang.c
@@ -0,0 +1,203 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "dict.h"
+
+/* Possible tags */
+enum {
+ DF, /* definition */
+ DX, /* definition/example */
+ ET, /* etymology */
+ EX, /* example */
+ LA, /* label */
+ ME, /* main entry */
+ NU, /* sense number */
+ PR, /* pronunciation */
+ PS, /* grammar part */
+ XR, /* cross reference */
+ XX, /* cross reference (whole entry) */
+};
+
+/* Assoc tables must be sorted on first field */
+
+static Assoc tagtab[] = {
+ {"df", DF},
+ {"dx", DX},
+ {"et", ET},
+ {"ex", EX},
+ {"la", LA},
+ {"me", ME},
+ {"nu", NU},
+ {"pr", PR},
+ {"ps", PS},
+ {"xr", XR},
+ {"xx", XX},
+};
+static long sget(char *, char *, char **, char **);
+static void soutpiece(char *, char *);
+
+void
+slangprintentry(Entry e, int cmd)
+{
+ char *p, *pe, *vs, *ve;
+ long t;
+
+ p = e.start;
+ pe = e.end;
+ if(cmd == 'h') {
+ t = sget(p, pe, &vs, &ve);
+ if(t == ME)
+ soutpiece(vs, ve);
+ outnl(0);
+ return;
+ }
+ while(p < pe) {
+ switch(sget(p, pe, &vs, &ve)) {
+ case DF:
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case DX:
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case ET:
+ outchars("[");
+ soutpiece(vs, ve);
+ outchars("] ");
+ break;
+ case EX:
+ outchars("E.g., ");
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case LA:
+ outchars("(");
+ soutpiece(vs, ve);
+ outchars(") ");
+ break;
+ case ME:
+ outnl(0);
+ soutpiece(vs, ve);
+ outnl(0);
+ break;
+ case NU:
+ outnl(2);
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case PR:
+ outchars("[");
+ soutpiece(vs, ve);
+ outchars("] ");
+ break;
+ case PS:
+ outnl(1);
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case XR:
+ outchars("See ");
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ case XX:
+ outchars("See ");
+ soutpiece(vs, ve);
+ outchars(". ");
+ break;
+ default:
+ ve = pe; /* will end loop */
+ break;
+ }
+ p = ve;
+ }
+ outnl(0);
+}
+
+long
+slangnextoff(long fromoff)
+{
+ long a;
+ char *p;
+
+ a = Bseek(bdict, fromoff, 0);
+ if(a < 0)
+ return -1;
+ for(;;) {
+ p = Brdline(bdict, '\n');
+ if(!p)
+ break;
+ if(p[0] == 'm' && p[1] == 'e' && p[2] == ' ')
+ return (Boffset(bdict)-Blinelen(bdict));
+ }
+ return -1;
+}
+
+void
+slangprintkey(void)
+{
+ Bprint(bout, "No key\n");
+}
+
+/*
+ * Starting from b, find next line beginning with a tag.
+ * Don't go past e, but assume *e==0.
+ * Return tag value, or -1 if no more tags before e.
+ * Set pvb to beginning of value (after tag).
+ * Set pve to point at newline that ends the value.
+ */
+static long
+sget(char *b, char *e, char **pvb, char **pve)
+{
+ char *p;
+ char buf[3];
+ long t, tans;
+
+ buf[2] = 0;
+ tans = -1;
+ for(p = b;;) {
+ if(p[2] == ' ') {
+ buf[0] = p[0];
+ buf[1] = p[1];
+ t = lookassoc(tagtab, asize(tagtab), buf);
+ if(t < 0) {
+ if(debug)
+ err("tag %s\n", buf);
+ p += 3;
+ } else {
+ if(tans < 0) {
+ p += 3;
+ tans = t;
+ *pvb = p;
+ } else {
+ *pve = p;
+ break;
+ }
+ }
+ }
+ p = strchr(p, '\n');
+ if(!p || ++p >= e) {
+ if(tans >= 0)
+ *pve = e-1;
+ break;
+ }
+ }
+ return tans;
+}
+
+static void
+soutpiece(char *b, char *e)
+{
+ int c, lastc;
+
+ lastc = 0;
+ while(b < e) {
+ c = *b++;
+ if(c == '\n')
+ c = ' ';
+ if(!(c == ' ' && lastc == ' ') && c != '@')
+ outchar(c);
+ lastc = c;
+ }
+}