## [Unreleased (4.0.1)]
+### Fixed
+
+- **Breaking**: The 4.0.0 change replacing the `Agiodisc_t` struct member
+ `putstr` by `printf` has been reverted
+
## [4.0.0] – 2022-05-29
### Changed
return (int)fread(buf, 1, (size_t)bufsize, chan);
}
+static int ioputstr(void *chan, const char *str)
+{
+ return fputs(str, chan);
+}
+
static int ioflush(void *chan)
{
return fflush(chan);
}
-typedef int (*printfn)(void *chan, const char *format, ...);
-
-static Agiodisc_t gprIoDisc = { iofread, (printfn)fprintf, ioflush };
+static Agiodisc_t gprIoDisc = { iofread, ioputstr, ioflush };
static Agdisc_t gprDisc = { &AgMemDisc, &AgIdDisc, &gprIoDisc };
.P0
struct Agiodisc_s {
int (*fread)(void *chan, char *buf, int bufsize);
- int (*printf)(void *chan, const char *format, ...);
+ int (*putstr)(void *chan, char *str);
int (*flush)(void *chan); /* sync */
} ;
.P1
Normally, the \fBFILE\fP structure and its related functions are used for I/O. At times, though,
an application may need to use a totally different type of character source. The associated
state or stream information is provided by the \fIchan\fP argument to \fBagread\fP or \fBagwrite\fP.
-The discipline function \fIfread\fP and \fIprintf\fP provide the corresponding functions for
+The discipline function \fIfread\fP and \fIputstr\fP provide the corresponding functions for
read and writing.
.SH "MEMORY DISCIPLINE"
struct Agiodisc_s {
int (*afread) (void *chan, char *buf, int bufsize);
- int (*printf)(void *chan, const char *format, ...);
+ int (*putstr) (void *chan, const char *str);
int (*flush) (void *chan); /* sync */
/* error messages? */
};
}
/* default IO methods */
+static int ioputstr(void *chan, const char *str)
+{
+ return fputs(str, chan);
+}
static int ioflush(void *chan)
{
return fflush(chan);
}
-typedef int (*printfn)(void *chan, const char *format, ...);
-
-Agiodisc_t AgIoDisc = { iofread, (printfn)fprintf, ioflush };
+Agiodisc_t AgIoDisc = { iofread, ioputstr, ioflush };
typedef struct {
const char *data;
rdr_t rdr;
Agdisc_t disc;
- memIoDisc.printf = AgIoDisc.printf;
+ memIoDisc.putstr = AgIoDisc.putstr;
memIoDisc.flush = AgIoDisc.flush;
rdr.data = cp;
rdr.len = strlen(cp);
static int ioput(Agraph_t * g, iochan_t * ofile, char *str)
{
- return AGDISC(g, io)->printf(ofile, "%s", str);
+ return AGDISC(g, io)->putstr(ofile, str);
}
return YDIR(y);
}
-static int (*print)(void *chan, const char *format, ...);
+static int (*putstr) (void *chan, const char *str);
static void agputs (const char* s, FILE* fp)
{
- print(fp, "%s", s);
+ putstr ((void*)fp, s);
}
static void agputc (int c, FILE* fp)
{
- print(fp, "%c", (char)c);
+ static char buf[2] = {'\0','\0'};
+ buf[0] = c;
+ putstr ((void*)fp, buf);
}
char *lbl;
char* fillcolor;
- print = g->clos->disc.io->printf;
+ putstr = g->clos->disc.io->putstr;
// setup_graph(job, g);
setYInvert(g);
pt = GD_bb(g).UR;
return (int)read(sffileno(chan), buf, bufsize);
}
+static int ioputstr(void *chan, const char *str)
+{
+ return sfputr(chan, str, -1);
+}
+
static int ioflush(void *chan)
{
return sfsync(chan);
}
-typedef int (*printfn)(void *chan, const char *format, ...);
-
-static Agiodisc_t gprIoDisc = { iofread, (printfn)sfprintf, ioflush };
+static Agiodisc_t gprIoDisc = { iofread, ioputstr, ioflush };
#ifdef GVDLL
static Agdisc_t gprDisc = { 0, 0, &gprIoDisc };
textflags[EMIT_GLABEL] = 0;
}
-typedef int (*printfn)(void *chan, const char *format, ...);
+typedef int (*putstrfn) (void *chan, const char *str);
typedef int (*flushfn) (void *chan);
static void dot_end_graph(GVJ_t *job)
{
if (io.afread == NULL) {
io.afread = AgIoDisc.afread;
- io.printf = (printfn)gvprintf;
+ io.putstr = (putstrfn)gvputs;
io.flush = (flushfn)gvflush;
}
gvputs(job, "}");
}
-typedef int (*printfn)(void *chan, const char *format, ...);
+typedef int (*putstrfn) (void *chan, const char *str);
typedef int (*flushfn) (void *chan);
static void json_end_graph(GVJ_t *job)
if (io.afread == NULL) {
io.afread = AgIoDisc.afread;
- io.printf = (printfn)gvprintf;
+ io.putstr = (putstrfn)gvputs;
io.flush = (flushfn)gvflush;
}
/* build disciplines dynamically so we can selectively replace functions */
ictx->myioDisc.afread = NULL; /* set in dotread() or dotstring() according to need */
- ictx->myioDisc.printf = AgIoDisc.printf; /* no change */
+ ictx->myioDisc.putstr = AgIoDisc.putstr; /* no change */
ictx->myioDisc.flush = AgIoDisc.flush; /* no change */
ictx->mydisc.mem = &AgMemDisc; /* no change */