summaryrefslogtreecommitdiff
path: root/libps
diff options
context:
space:
mode:
Diffstat (limited to 'libps')
-rw-r--r--libps/write.c141
1 files changed, 87 insertions, 54 deletions
diff --git a/libps/write.c b/libps/write.c
index 486352d2..66fa6f54 100644
--- a/libps/write.c
+++ b/libps/write.c
@@ -1,4 +1,4 @@
-/* Some helper functions for writing output fields.
+/* Ps stream output
Copyright (C) 1995 Free Software Foundation, Inc.
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include <errno.h>
#include "ps.h"
@@ -29,11 +30,9 @@
/* Write at most MAX_LEN characters of STRING to STREAM (if MAX_LEN > the
length of STRING, then write all of it; if MAX_LEN == -1, then write all
- of STRING regardless). If COUNT is non-NULL, the number of characters
- written is added to the integer it points to. If an error occurs, the
- error code is returned, otherwise 0. */
+ of STRING regardless). */
error_t
-ps_write_string(char *string, int max_len, FILE *stream, unsigned *count)
+ps_stream_write (ps_stream_t stream, char *string, int max_len)
{
int len = strlen(string);
@@ -42,92 +41,126 @@ ps_write_string(char *string, int max_len, FILE *stream, unsigned *count)
if (len > 0)
{
- int output = fwrite(string, 1, len, stream);
+ int output;
+ int spaces_needed = stream->spaces;
+
+ stream->spaces = 0;
+ while (spaces_needed > 0)
+ {
+ static char spaces[] = " ";
+#define spaces_len (sizeof(spaces) - 1)
+ int chunk = spaces_needed > spaces_len ? spaces_len : spaces_needed;
+ error_t err =
+ ps_stream_write (stream, spaces + spaces_len - chunk, chunk);
+ if (err)
+ return err;
+ spaces_needed -= chunk;
+ }
+ stream->spaces = spaces_needed;
+
+ output = fwrite (string, 1, len, stream->stream);
if (output == 0)
return errno;
- if (count)
- *count += output;
+
+ stream->pos += len;
}
return 0;
}
-
-/* Write NUM spaces to STREAM. If COUNT is non-NULL, the number of spaces
- written is added to the integer it points to. If an error occurs, the
- error code is returned, otherwise 0. */
+
+/* Write NUM spaces to STREAM. NUM may be negative, in which case the same
+ number of adjacent spaces (written by other calls to ps_stream_space) are
+ consumed if possible. If an error occurs, the error code is returned,
+ otherwise 0. */
error_t
-ps_write_spaces(int num, FILE *stream, unsigned *count)
+ps_stream_space (ps_stream_t stream, int num)
{
- static char spaces[] = " ";
-#define spaces_len (sizeof(spaces) - 1)
-
- while (num > spaces_len)
- {
- error_t err = ps_write_string(spaces, spaces_len, stream, count);
- if (err)
- return err;
- num -= spaces_len;
- }
-
- if (num > 0)
- return ps_write_string(spaces, num, stream, count);
- else
- return 0;
+ stream->spaces += num;
+ return 0;
}
/* Write as many spaces to STREAM as required to make a field of width SOFAR
be at least WIDTH characters wide (the absolute value of WIDTH is used).
- If COUNT is non-NULL, the number of spaces written is added to the integer
- it points to. If an error occurs, the error code is returned, otherwise
- 0. */
+ If an error occurs, the error code is returned, otherwise 0. */
error_t
-ps_write_padding(int sofar, int width, FILE *stream, unsigned *count)
+ps_stream_pad (ps_stream_t stream, int sofar, int width)
{
- width = ABS(width);
- if (sofar < width)
- return ps_write_spaces(width - sofar, stream, count);
- else
- return 0;
+ return ps_stream_space (stream, ABS (width) - sofar);
}
+/* Write a newline to STREAM, resetting its position to zero. */
+error_t
+ps_stream_newline (ps_stream_t stream)
+{
+ putc ('\n', stream->stream);
+ stream->spaces = 0;
+ stream->pos = 0;
+ return 0;
+}
+
/* Write the string BUF to STREAM, padded on one side with spaces to be at
least the absolute value of WIDTH long: if WIDTH >= 0, then on the left
- side, otherwise on the right side. If COUNT is non-NULL, the number of
- characters written is added to the integer it points to. If an error
- occurs, the error code is returned, otherwise 0. */
+ side, otherwise on the right side. If an error occurs, the error code is
+ returned, otherwise 0. */
error_t
-ps_write_field(char *buf, int width, FILE *stream, unsigned *count)
+ps_stream_write_field (ps_stream_t stream, char *buf, int width)
{
+ int len;
error_t err;
- int len = strlen(buf);
- if (width > len)
+ while (isspace (*buf))
+ buf++;
+
+ len = strlen(buf);
+ while (isspace (buf[len - 1]))
+ len--;
+
+ if (width > 0)
{
- err = ps_write_string(buf, -1, stream, count);
+ err = ps_stream_write (stream, buf, len);
if (!err)
- err = ps_write_spaces(width - len, stream, count);
+ err = ps_stream_space (stream, width - len);
}
- else if (-width > len)
+ else if (width < 0)
{
- err = ps_write_spaces(-width - len, stream, count);
+ err = ps_stream_space (stream, -width - len);
if (!err)
- err = ps_write_string(buf, -1, stream, count);
+ err = ps_stream_write (stream, buf, len);
}
else
- err = ps_write_string(buf, -1, stream, count);
+ err = ps_stream_write (stream, buf, len);
return err;
}
/* Write the decimal representation of VALUE to STREAM, padded on one side
with spaces to be at least the absolute value of WIDTH long: if WIDTH >=
- 0, then on the left side, otherwise on the right side. If COUNT is
- non-NULL, the number of characters written is added to the integer it
- points to. If an error occurs, the error code is returned, otherwise 0. */
+ 0, then on the left side, otherwise on the right side. If an error
+ occurs, the error code is returned, otherwise 0. */
error_t
-ps_write_int_field(int value, int width, FILE *stream, unsigned *count)
+ps_stream_write_int_field (ps_stream_t stream, int value, int width)
{
char buf[20];
sprintf(buf, "%d", value);
- return ps_write_field(buf, width, stream, count);
+ return ps_stream_write_field (stream, buf, width);
+}
+
+/* Create a stream outputing to DEST, and return it in STREAM, or an error. */
+error_t
+ps_stream_create (FILE *dest, ps_stream_t *stream)
+{
+ *stream = malloc (sizeof (struct ps_stream));
+ if (! *stream)
+ return ENOMEM;
+ (*stream)->stream = dest;
+ (*stream)->spaces = 0;
+ (*stream)->pos = 0;
+ return 0;
+}
+
+/* Frees STREAM. The destination file is *not* closed. */
+void
+ps_stream_free (ps_stream_t stream)
+{
+ free (stream);
}