File: m_emit.c

package info (click to toggle)
plotutils 2.4.1-11
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 11,676 kB
  • ctags: 6,967
  • sloc: ansic: 76,305; sh: 15,172; cpp: 12,403; yacc: 2,604; makefile: 888; lex: 144
file content (193 lines) | stat: -rw-r--r-- 5,327 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* This file contains the internal _m_emit_integer, _m_emit_float,
   _m_emit_op_code, and _m_emit_string routines, which are used by
   MetaPlotters.  They take into account the desired format (binary
   metafile format or ascii [human-readable] metafile format.

   In the unnumbered versions of libplot prior to version 0.0 (which was
   released as part of plotutils-2.0, in 1/98), we assumed that in binary
   metafile format, two bytes sufficed to represent any integer.  This was
   the convention used in traditional plot(5) format, and can be traced to
   the PDP-11.  Unfortunately it confined us to the range -0x10000..0x7fff
   (assuming two's complement).  Actually, the parsing in our `plot'
   utility always treated the arguments to pencolor(), fillcolor(), and
   filltype() specially.  An argument of any of those functions was treated
   as an unsigned integer, so it could be in the range 0..0xffff.

   In version 0.0 of libplot, we switched in binary metafile format to
   representing integers as machine integers.  The parsing of metafiles by
   `plot' now takes this into account.  `plot' has command-line options for
   backward compatibility with plot(5) format.

   Our representation for floating-point numbers in binary metafiles is
   simply the machine representation for single-precision floating point.
   plot(5) format did not support floating point arguments, so there are no
   concerns over backward compatibility. */

#include "sys-defines.h"
#include "extern.h"

/* emit one unsigned character, passed as an int */
void
#ifdef _HAVE_PROTOS
_m_emit_op_code (R___(Plotter *_plotter) int c)
#else
_m_emit_op_code (R___(_plotter) c)
     S___(Plotter *_plotter;) 
     int c;
#endif
{
  if (_plotter->data->outfp)
    putc (c, _plotter->data->outfp);
#ifdef LIBPLOTTER
  else if (_plotter->data->outstream)
    _plotter->data->outstream->put ((unsigned char)c);
#endif
}

void
#ifdef _HAVE_PROTOS
_m_emit_integer (R___(Plotter *_plotter) int x)
#else
_m_emit_integer (R___(_plotter) x)
     S___(Plotter *_plotter;) 
     int x;
#endif
{
  if (_plotter->data->outfp)
    {
      if (_plotter->meta_portable_output)
	fprintf (_plotter->data->outfp, " %d", x);
      else
	fwrite ((voidptr_t) &x, sizeof(int), 1, _plotter->data->outfp);
    }
#ifdef LIBPLOTTER
  else if (_plotter->data->outstream)
    {
      if (_plotter->meta_portable_output)
	(*(_plotter->data->outstream)) << ' ' << x;
      else
	_plotter->data->outstream->write((char *)&x, sizeof(int));
    }
#endif
}

void
#ifdef _HAVE_PROTOS
_m_emit_float (R___(Plotter *_plotter) double x)
#else
_m_emit_float (R___(_plotter) x)
     S___(Plotter *_plotter;) 
     double x;
#endif
{
  if (_plotter->data->outfp)
    {
      if (_plotter->meta_portable_output)
	{
	  /* treat equality with zero specially, since some printf's print
	     negative zero differently from positive zero, and that may
	     prevent regression tests from working properly */
	  fprintf (_plotter->data->outfp, x == 0.0 ? " 0" : " %g", x);
	}
      else
	{
	  float f;
	  
	  f = FROUND(x);
	  fwrite ((voidptr_t) &f, sizeof(float), 1, _plotter->data->outfp);
	}
    }
#ifdef LIBPLOTTER
  else if (_plotter->data->outstream)
    {
      if (_plotter->meta_portable_output)
	(*(_plotter->data->outstream)) << ' ' << x;
      else
	{
	  float f;
	  
	  f = FROUND(x);
	  _plotter->data->outstream->write((char *)&f, sizeof(float));
	}
    }
#endif
}

void
#ifdef _HAVE_PROTOS
_m_emit_string (R___(Plotter *_plotter) const char *s)
#else
_m_emit_string (R___(_plotter) s)
     S___(Plotter *_plotter;) 
     const char *s;
#endif
{
  bool has_newline;
  char *t = NULL;		/* keep compiler happy */
  char *nl;
  const char *u;
  
  /* null pointer handled specially */
  if (s == NULL)
    s = "(null)";
  
  if (strchr (s, '\n'))
    /* don't grok arg strings containing newlines; truncate at first
       newline if any */
    {
      has_newline = true;
      t = (char *)_plot_xmalloc (strlen (s) + 1);      
      strcpy (t, s);
      nl = strchr (t, '\n');
      *nl = '\0';
      u = t;
    }
  else
    {
      has_newline = false;
      u = s;
    }
      
  /* emit string, with appended newline if output format is binary (old
     plot(3) convention, which makes sense only if there can be at most one
     string among the command arguments, and it's positioned last) */
  if (_plotter->data->outfp)
    {
      fputs (u, _plotter->data->outfp);
      if (_plotter->meta_portable_output == false)
	putc ('\n', _plotter->data->outfp); 
    }
#ifdef LIBPLOTTER
  else if (_plotter->data->outstream)
    {
      (*(_plotter->data->outstream)) << u;
      if (_plotter->meta_portable_output == false)
	(*(_plotter->data->outstream)) << '\n';
    }
#endif

  if (has_newline)
    free (t);
}

/* End a directive that was begun by invoking _m_emit_op_code() (q.v.).  In
   portable format, the terminator is a newline; in binary format, there is
   no terminator. */
void
#ifdef _HAVE_PROTOS
_m_emit_terminator (S___(Plotter *_plotter))
#else
_m_emit_terminator (S___(_plotter))
     S___(Plotter *_plotter;) 
#endif
{
  if (_plotter->meta_portable_output)
    {
      if (_plotter->data->outfp)
	putc ('\n', _plotter->data->outfp);
#ifdef LIBPLOTTER
      else if (_plotter->data->outstream)
	(*(_plotter->data->outstream)) << '\n';
#endif
    }
}