2 * misc. functions for the "dc" Desk Calculator language.
4 * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can either send email to this
18 * program's author (see below) or write to:
19 * The Free Software Foundation, Inc.
20 * 59 Temple Place, Suite 330
21 * Boston, MA 02111 USA
24 /* This module contains miscelaneous functions that have no
25 * special knowledge of any private data structures.
26 * They could all be moved to their own separate modules, but
27 * are agglomerated here for convenience.
39 # ifdef HAVE_STRINGS_H
46 # define isgraph isprint
53 #ifndef EXIT_FAILURE /* C89 <stdlib.h> */
54 # define EXIT_FAILURE 1
58 /* print an "out of memory" diagnostic and exit program */
60 dc_memfail
DC_DECLVOID()
62 fprintf(stderr
, "%s: out of memory\n", progname
);
68 dc_malloc
DC_DECLARG((len
))
71 void *result
= malloc(len
);
79 /* print the id in a human-understandable form
80 * fp is the output stream to place the output on
81 * id is the name of the register (or command) to be printed
82 * suffix is a modifier (such as "stack") to be printed
85 dc_show_id
DC_DECLARG((fp
, id
, suffix
))
88 const char *suffix DC_DECLEND
91 fprintf(fp
, "'%c' (%#o)%s", id
, id
, suffix
);
93 fprintf(fp
, "%#o%s", id
, suffix
);
97 /* report that corrupt data has been detected;
98 * use the msg and regid (if nonnegative) to give information
99 * about where the garbage was found,
101 * will abort() so that a debugger might be used to help find
104 /* If this routine is called, then there is a bug in the code;
105 * i.e. it is _not_ a data or user error
108 dc_garbage
DC_DECLARG((msg
, regid
))
109 const char *msg DC_DECLSEP
113 fprintf(stderr
, "%s: garbage %s\n", progname
, msg
);
115 fprintf(stderr
, "%s:%s register ", progname
, msg
);
116 dc_show_id(stderr
, regid
, " is garbage\n");
122 /* call system() with the passed string;
123 * if the string contains a newline, terminate the string
124 * there before calling system.
125 * Return a pointer to the first unused character in the string
126 * (i.e. past the '\n' if there was one, to the '\0' otherwise).
129 dc_system
DC_DECLARG((s
))
130 const char *s DC_DECLEND
139 tmpstr
= dc_malloc(len
+ 1);
140 strncpy(tmpstr
, s
, len
);
147 return s
+ strlen(s
);
151 /* print out the indicated value */
153 dc_print
DC_DECLARG((value
, obase
, newline_p
, discard_p
))
154 dc_data value DC_DECLSEP
156 dc_newline newline_p DC_DECLSEP
157 dc_discard discard_p DC_DECLEND
159 if (value
.dc_type
== DC_NUMBER
) {
160 dc_out_num(value
.v
.number
, obase
, newline_p
, discard_p
);
161 } else if (value
.dc_type
== DC_STRING
) {
162 dc_out_str(value
.v
.string
, newline_p
, discard_p
);
164 dc_garbage("in data being printed", -1);
168 /* return a duplicate of the passed value, regardless of type */
170 dc_dup
DC_DECLARG((value
))
171 dc_data value DC_DECLEND
173 if (value
.dc_type
!=DC_NUMBER
&& value
.dc_type
!=DC_STRING
)
174 dc_garbage("in value being duplicated", -1);
175 if (value
.dc_type
== DC_NUMBER
)
176 return dc_dup_num(value
.v
.number
);
178 return dc_dup_str(value
.v
.string
);