diff options
Diffstat (limited to 'libps')
-rw-r--r-- | libps/write.c | 141 |
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); } |