1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
28 * keyword printf support
44 Sf_key_lookup_t lookup
;
45 Sf_key_convert_t convert
;
72 #define initfield(f,s) ((f)->first = (f)->delimiter = *((f)->next = (s)))
75 getfield(register Field_t
* f
, int restore
)
100 else if (c
== CC_esc
|| c
== '\\')
111 if (c
== '(' && restore
)
117 else if (c
== '[' && restore
)
123 else if (c
== f
->delimiter
)
125 *(f
->next
= --s
) = 0;
134 * sfio %! extension function
138 getfmt(Sfio_t
* sp
, void* vp
, Sffmt_t
* dp
)
140 register Fmt_t
* fp
= (Fmt_t
*)dp
;
141 Value_t
* value
= (Value_t
*)vp
;
153 regmatch_t match
[10];
156 if (fp
->fmt
.t_str
&& fp
->fmt
.n_str
> 0 && (v
= fmtbuf(fp
->fmt
.n_str
+ 1)))
158 memcpy(v
, fp
->fmt
.t_str
, fp
->fmt
.n_str
);
159 v
[fp
->fmt
.n_str
] = 0;
188 if (i
== ':' && fp
->fmt
.fmt
== 's' && strlen(a
) > 4 && !isalnum(*(a
+ 4)))
192 if (streq(a
, "case"))
194 else if (streq(a
, "edit"))
206 h
= (*fp
->lookup
)(fp
->handle
, &fp
->fmt
, a
, &s
, &n
);
213 h
= (*fp
->lookup
)(fp
->handle
, &fp
->fmt
, a
, &s
, &n
);
216 fp
->fmt
.flags
|= SFFMT_VALUE
;
220 value
->c
= s
? *s
: n
;
224 fp
->fmt
.size
= sizeof(Sflong_t
);
225 value
->q
= (Sflong_t
)(s
? strtoll(s
, NiL
, 0) : n
);
230 fp
->fmt
.size
= sizeof(Sflong_t
);
231 value
->q
= s
? (Sflong_t
)strtoull(s
, NiL
, 0) : n
;
235 n
= strtoll(s
, NiL
, 0);
236 value
->p
= pointerof(n
);
242 value
->s
= fmtquote(s
, "$'", "'", strlen(s
), 0);
251 if (!s
&& (!h
|| !fp
->tmp
[1] && !(fp
->tmp
[1] = sfstropen()) || sfprintf(fp
->tmp
[1], "%I*d", sizeof(n
), n
) <= 0 || !(s
= sfstruse(fp
->tmp
[1]))))
256 d
= initfield(&f
, v
+ 4);
260 while ((a
= getfield(&f
, 1)) && (v
= getfield(&f
, 0)))
268 for (h
= 0; h
< elementsof(fmt
.tmp
); h
++)
270 if (!fp
->tmp
[0] && !(fp
->tmp
[0] = sfstropen()) || sfprintf(fp
->tmp
[0], "%!", &fmt
) <= 0 || !(s
= sfstruse(fp
->tmp
[0])))
275 for (h
= 0; h
< elementsof(fmt
.tmp
); h
++)
285 for (x
= 0; *f
.next
; x
^= 1)
290 fp
->re
[x
] = &fp
->red
[x
];
291 if (regcomp(fp
->re
[x
], f
.next
, REG_DELIMITED
|REG_NULL
))
293 f
.next
+= fp
->re
[x
]->re_npat
;
294 if (regsubcomp(fp
->re
[x
], f
.next
, NiL
, 0, 0))
296 f
.next
+= fp
->re
[x
]->re_npat
;
297 if (!regexec(fp
->re
[x
], s
, elementsof(match
), match
, 0) && !regsubexec(fp
->re
[x
], s
, elementsof(match
), match
))
299 s
= fp
->re
[x
]->re_sub
->re_buf
;
300 if (fp
->re
[x
]->re_sub
->re_flags
& REG_SUB_STOP
)
312 while ((s
= strchr(s
, CC_esc
)) && *(s
+ 1) == '[')
313 do fp
->invisible
++; while (*s
&& !islower(*s
++));
326 if ((!fp
->convert
|| !(value
->s
= (*fp
->convert
)(fp
->handle
, &fp
->fmt
, a
, s
, n
))) && (!fp
->tmp
[0] && !(fp
->tmp
[0] = sfstropen()) || sfprintf(fp
->tmp
[0], "%%%c", fp
->fmt
.fmt
) <= 0 || !(value
->s
= sfstruse(fp
->tmp
[0]))))
335 * this is the 20000308 interface with Sffmt_t* callback args
339 sfkeyprintf(Sfio_t
* sp
, void* handle
, const char* format
, Sf_key_lookup_t lookup
, Sf_key_convert_t convert
)
345 memset(&fmt
, 0, sizeof(fmt
));
346 fmt
.version
= 20030909;
347 fmt
.fmt
.version
= SFIO_VERSION
;
348 fmt
.fmt
.form
= (char*)format
;
349 fmt
.fmt
.extf
= getfmt
;
352 fmt
.convert
= convert
;
353 r
= sfprintf(sp
, "%!", &fmt
) - fmt
.invisible
;
354 for (i
= 0; i
< elementsof(fmt
.tmp
); i
++)
361 * this is the original interface
367 sfkeyprintf(Sfio_t
* sp
, void* handle
, const char* format
, Sf_key_lookup_t lookup
, Sf_key_convert_t convert
)
373 memset(&fmt
, 0, sizeof(fmt
));
374 fmt
.fmt
.version
= SFIO_VERSION
;
375 fmt
.fmt
.form
= (char*)format
;
376 fmt
.fmt
.extf
= getfmt
;
379 fmt
.convert
= convert
;
380 r
= sfprintf(sp
, "%!", &fmt
) - fmt
.invisible
;
381 for (i
= 0; i
< elementsof(fmt
.tmp
); i
++)
384 for (i
= 0; i
< elementsof(fmt
.re
); i
++)