~ubuntu-branches/debian/sid/bc/sid

« back to all changes in this revision

Viewing changes to dc/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Dirk Eddelbuettel
  • Date: 2002-04-13 11:33:49 UTC
  • Revision ID: james.westby@ubuntu.com-20020413113349-hl2r1t730b91ov68
Tags: upstream-1.06
ImportĀ upstreamĀ versionĀ 1.06

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * misc. functions for the "dc" Desk Calculator language.
 
3
 *
 
4
 * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
 
5
 *
 
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)
 
9
 * any later version.
 
10
 *
 
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.
 
15
 *
 
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
 
22
 */
 
23
 
 
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.
 
28
 */
 
29
 
 
30
#include "config.h"
 
31
 
 
32
#include <stdio.h>
 
33
#ifdef HAVE_STDLIB_H
 
34
# include <stdlib.h>
 
35
#endif
 
36
#ifdef HAVE_STRING_H
 
37
# include <string.h>
 
38
#else
 
39
# ifdef HAVE_STRINGS_H
 
40
#  include <strings.h>
 
41
# endif
 
42
#endif
 
43
#include <ctype.h>
 
44
#ifndef isgraph
 
45
# ifndef HAVE_ISGRAPH
 
46
#  define isgraph isprint
 
47
# endif
 
48
#endif
 
49
#include <getopt.h>
 
50
#include "dc.h"
 
51
#include "dc-proto.h"
 
52
 
 
53
#ifndef EXIT_FAILURE    /* C89 <stdlib.h> */
 
54
# define EXIT_FAILURE   1
 
55
#endif
 
56
 
 
57
 
 
58
/* print an "out of memory" diagnostic and exit program */
 
59
void
 
60
dc_memfail DC_DECLVOID()
 
61
{
 
62
        fprintf(stderr, "%s: out of memory\n", progname);
 
63
        exit(EXIT_FAILURE);
 
64
}
 
65
 
 
66
/* malloc or die */
 
67
void *
 
68
dc_malloc DC_DECLARG((len))
 
69
        size_t len DC_DECLEND
 
70
{
 
71
        void *result = malloc(len);
 
72
 
 
73
        if (!result)
 
74
                dc_memfail();
 
75
        return result;
 
76
}
 
77
 
 
78
 
 
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
 
83
 */
 
84
void
 
85
dc_show_id DC_DECLARG((fp, id, suffix))
 
86
        FILE *fp DC_DECLSEP
 
87
        int id DC_DECLSEP
 
88
        const char *suffix DC_DECLEND
 
89
{
 
90
        if (isgraph(id))
 
91
                fprintf(fp, "'%c' (%#o)%s", id, id, suffix);
 
92
        else
 
93
                fprintf(fp, "%#o%s", id, suffix);
 
94
}
 
95
 
 
96
 
 
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,
 
100
 *
 
101
 * will abort() so that a debugger might be used to help find
 
102
 * the bug
 
103
 */
 
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
 
106
 */
 
107
void
 
108
dc_garbage DC_DECLARG((msg, regid))
 
109
        const char *msg DC_DECLSEP
 
110
        int regid DC_DECLEND
 
111
{
 
112
        if (regid < 0) {
 
113
                fprintf(stderr, "%s: garbage %s\n", progname, msg);
 
114
        } else {
 
115
                fprintf(stderr, "%s:%s register ", progname, msg);
 
116
                dc_show_id(stderr, regid, " is garbage\n");
 
117
        }
 
118
        abort();
 
119
}
 
120
 
 
121
 
 
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).
 
127
 */
 
128
const char *
 
129
dc_system DC_DECLARG((s))
 
130
        const char *s DC_DECLEND
 
131
{
 
132
        const char *p;
 
133
        char *tmpstr;
 
134
        size_t len;
 
135
 
 
136
        p = strchr(s, '\n');
 
137
        if (p) {
 
138
                len = p - s;
 
139
                tmpstr = dc_malloc(len + 1);
 
140
                strncpy(tmpstr, s, len);
 
141
                tmpstr[len] = '\0';
 
142
                system(tmpstr);
 
143
                free(tmpstr);
 
144
                return p + 1;
 
145
        }
 
146
        system(s);
 
147
        return s + strlen(s);
 
148
}
 
149
 
 
150
 
 
151
/* print out the indicated value */
 
152
void
 
153
dc_print DC_DECLARG((value, obase, newline_p, discard_p))
 
154
        dc_data value DC_DECLSEP
 
155
        int obase DC_DECLSEP
 
156
        dc_newline newline_p DC_DECLSEP
 
157
        dc_discard discard_p DC_DECLEND
 
158
{
 
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);
 
163
        } else {
 
164
                dc_garbage("in data being printed", -1);
 
165
        }
 
166
}
 
167
 
 
168
/* return a duplicate of the passed value, regardless of type */
 
169
dc_data
 
170
dc_dup DC_DECLARG((value))
 
171
        dc_data value DC_DECLEND
 
172
{
 
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);
 
177
        /*else*/
 
178
        return dc_dup_str(value.v.string);
 
179
}