2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: seq.c,v 8.14 1993/11/18 08:17:20 bostic Exp $ (Berkeley) $Date: 1993/11/18 08:17:20 $";
12 #include <sys/types.h>
24 * Internal version to enter a sequence.
27 seq_set(sp
, name
, input
, output
, stype
, userdef
)
29 char *name
, *input
, *output
;
37 #if defined(DEBUG) && 0
38 TRACE(sp
, "seq_set: name {%s} input {%s} output {%s}\n",
39 name
? name
: "", input
, output
);
42 * Find any previous occurrence, and replace the output field.
43 * Q's are sorted by character and length within that character.
46 for (lastqp
= NULL
, qp
= sp
->gp
->seqq
.lh_first
;
47 qp
!= NULL
; lastqp
= qp
, qp
= qp
->q
.le_next
) {
48 if (qp
->input
[0] < input
[0])
50 if (qp
->input
[0] > input
[0] || qp
->ilen
> ilen
)
52 if (qp
->ilen
== ilen
&&
53 stype
== qp
->stype
&& !strcmp(qp
->input
, input
)) {
54 if ((p
= strdup(output
)) == NULL
)
56 FREE(qp
->output
, qp
->olen
);
57 qp
->olen
= strlen(output
);
63 /* Allocate and initialize space. */
64 if ((qp
= malloc(sizeof(SEQ
))) == NULL
)
68 else if ((qp
->name
= strdup(name
)) == NULL
)
70 if ((qp
->input
= strdup(input
)) == NULL
)
72 if ((qp
->output
= strdup(output
)) == NULL
) {
73 FREE(qp
->input
, ilen
);
74 mem3
: if (qp
->name
!= NULL
)
75 FREE(qp
->name
, strlen(qp
->name
) + 1);
76 mem2
: FREE(qp
, sizeof(SEQ
));
77 mem1
: msgq(sp
, M_SYSERR
, NULL
);
83 qp
->olen
= strlen(output
);
84 qp
->flags
= userdef
? S_USERDEF
: 0;
86 /* Link into the chain. */
88 LIST_INSERT_HEAD(&sp
->gp
->seqq
, qp
, q
);
90 LIST_INSERT_AFTER(lastqp
, qp
, q
);
93 /* Set the fast lookup bit. */
94 bit_set(sp
->gp
->seqb
, qp
->input
[0]);
104 seq_delete(sp
, input
, stype
)
111 if ((qp
= seq_find(sp
, input
, strlen(input
), stype
, NULL
)) == NULL
)
115 if (qp
->name
!= NULL
)
116 FREE(qp
->name
, strlen(qp
->name
) + 1);
117 FREE(qp
->input
, qp
->ilen
);
118 FREE(qp
->output
, qp
->olen
);
119 FREE(qp
, sizeof(SEQ
));
125 * Search the sequence list for a match to a buffer, if ispartial
126 * isn't NULL, partial matches count.
129 seq_find(sp
, input
, ilen
, stype
, ispartialp
)
142 for (qp
= sp
->gp
->seqq
.lh_first
;
143 qp
!= NULL
; qp
= qp
->q
.le_next
) {
144 if (qp
->input
[0] < input
[0])
146 if (qp
->input
[0] > input
[0])
148 if (stype
!= qp
->stype
)
151 * If sequence is shorter or the same length as the
152 * input, can only find an exact match. If input is
153 * shorter than the sequence, can only find a partial.
155 if (qp
->ilen
<= ilen
) {
156 if (!strncmp(qp
->input
, input
, qp
->ilen
))
159 if (!strncmp(qp
->input
, input
, ilen
))
164 for (qp
= sp
->gp
->seqq
.lh_first
;
165 qp
!= NULL
; qp
= qp
->q
.le_next
) {
166 if (qp
->input
[0] < input
[0])
168 if (qp
->input
[0] > input
[0] || qp
->ilen
> ilen
)
170 if (stype
== qp
->stype
&& qp
->ilen
== ilen
&&
171 !strncmp(qp
->input
, input
, ilen
))
179 * Display the sequence entries of a specified type.
182 seq_dump(sp
, stype
, isname
)
189 int ch
, cnt
, len
, tablen
;
194 tablen
= O_VAL(sp
, O_TABSTOP
);
195 for (qp
= sp
->gp
->seqq
.lh_first
; qp
!= NULL
; qp
= qp
->q
.le_next
) {
196 if (stype
!= qp
->stype
)
199 for (p
= qp
->input
, len
= 0; (ch
= *p
); ++p
, ++len
)
200 (void)ex_printf(EXCOOKIE
, "%s", cname
[ch
].name
);
201 for (len
= tablen
- len
% tablen
; len
; --len
)
202 (void)ex_printf(EXCOOKIE
, " ");
204 for (p
= qp
->output
; (ch
= *p
); ++p
)
205 (void)ex_printf(EXCOOKIE
, "%s", cname
[ch
].name
);
207 if (isname
&& qp
->name
) {
208 for (len
= tablen
- len
% tablen
; len
; --len
)
209 (void)ex_printf(EXCOOKIE
, " ");
210 for (p
= qp
->name
, len
= 0; (ch
= *p
); ++p
, ++len
)
211 (void)ex_printf(EXCOOKIE
, "%s", cname
[ch
].name
);
213 (void)ex_printf(EXCOOKIE
, "\n");
220 * Save the sequence entries to a file.
223 seq_save(sp
, fp
, prefix
, stype
)
233 esc
= sp
->gp
->original_termios
.c_cc
[VLNEXT
];
235 /* Write a sequence command for all keys the user defined. */
236 for (qp
= sp
->gp
->seqq
.lh_first
; qp
!= NULL
; qp
= qp
->q
.le_next
) {
237 if (!F_ISSET(qp
, S_USERDEF
))
239 if (stype
!= qp
->stype
)
242 (void)fprintf(fp
, "%s", prefix
);
243 for (p
= qp
->input
; (ch
= *p
) != '\0'; ++p
) {
244 if (ch
== esc
|| ch
== '|' || isblank(ch
) ||
245 sp
->special
[ch
] == K_NL
)
250 for (p
= qp
->output
; (ch
= *p
) != '\0'; ++p
) {
251 if (ch
== esc
|| ch
== '|' || sp
->special
[ch
] == K_NL
)
255 (void)putc('\n', fp
);