~replatformtech/+junk/gnucobol3

« back to all changes in this revision

Viewing changes to libcob/termio.c

  • Committer: Jim Popovitch
  • Date: 2024-11-29 15:39:36 UTC
  • Revision ID: jim.popovitch@replatformtech.com-20241129153936-wnjndpxl8m8k1mhe
Upstream changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#define SIGINT 2
41
41
#endif
42
42
 
43
 
/* Force symbol exports */
 
43
/* include internal and external libcob definitions, forcing exports */
44
44
#define COB_LIB_EXPIMP
45
 
#include "common.h"
46
45
#include "coblocal.h"
47
46
 
48
47
/* Local variables */
64
63
static void
65
64
display_numeric (cob_field *f, FILE *fp)
66
65
{
67
 
        int             i;
 
66
        const unsigned short    digits = COB_FIELD_DIGITS (f);
 
67
        const signed short      scale = COB_FIELD_SCALE (f);
 
68
        const int               has_sign = COB_FIELD_HAVE_SIGN (f) ? 1 : 0;
 
69
        const int               size
 
70
                = digits
 
71
                + ((scale < 0) ? scale : 0)     /* subtract scale when negative */
 
72
                + has_sign;
 
73
 
 
74
        /* minimal validation */
 
75
        if (size >= COB_MEDIUM_MAX) {
 
76
                fputs (_("(Not representable)"), fp);
 
77
                return;
 
78
        }
 
79
 
 
80
        /* conversion to internal USAGE DISPLAY with SIGN SEPERATE */
 
81
        {
 
82
                cob_field       field;
 
83
                cob_field_attr  attr;
 
84
                COB_ATTR_INIT (COB_TYPE_NUMERIC_DISPLAY, digits, COB_FIELD_SCALE (f), 0, NULL);
 
85
                if (has_sign) {
 
86
                        attr.flags = COB_FLAG_HAVE_SIGN | COB_FLAG_SIGN_SEPARATE;
 
87
                        if (COB_FIELD_SIGN_LEADING (f) ||
 
88
                                COB_FIELD_TYPE (f) != COB_TYPE_NUMERIC_DISPLAY) {
 
89
                                attr.flags |= COB_FLAG_SIGN_LEADING;
 
90
                        }
 
91
                }
 
92
                COB_FIELD_INIT (size, COB_TERM_BUFF, &attr);
 
93
 
 
94
                cob_move (f, &field);
 
95
        }
 
96
 
 
97
        /* output of data to viewport */
 
98
        {
 
99
                register unsigned char *q = COB_TERM_BUFF;
 
100
                const unsigned char *end = q + size;
 
101
                for ( ; q < end; ++q) {
 
102
                        if (putc (*q, fp) != *q) {
 
103
                                break;
 
104
                        }
 
105
                }
 
106
        }
 
107
}
 
108
 
 
109
static void
 
110
pretty_display_numeric (cob_field *f, FILE *fp)
 
111
{
68
112
        unsigned short  digits;
69
 
        signed short    scale;
 
113
        const signed short      scale = COB_FIELD_SCALE (f);
 
114
        const int               has_sign = COB_FIELD_HAVE_SIGN (f) ? 1 : 0;
70
115
        int             size;
71
 
        cob_field_attr  attr;
72
 
        cob_field       temp;
73
 
 
74
 
        digits = COB_FIELD_DIGITS (f);
75
 
        scale = COB_FIELD_SCALE (f);
76
 
        size = digits + (COB_FIELD_HAVE_SIGN (f) ? 1 : 0);
77
 
        if (size >= COB_MEDIUM_MAX) {
78
 
                fputs (_("(Not representable)"), fp);
79
 
                return;
80
 
        }
81
 
        COB_ATTR_INIT (COB_TYPE_NUMERIC_DISPLAY, digits, scale, 0, NULL);
82
 
        temp.size = size;
83
 
        temp.data = COB_TERM_BUFF;
84
 
        temp.attr = &attr;
85
 
        if (COB_FIELD_HAVE_SIGN (f)) {
86
 
                attr.flags = COB_FLAG_HAVE_SIGN | COB_FLAG_SIGN_SEPARATE;
87
 
                if (COB_FIELD_SIGN_LEADING (f) ||
88
 
                    COB_FIELD_TYPE (f) != COB_TYPE_NUMERIC_DISPLAY) {
89
 
                        attr.flags |= COB_FLAG_SIGN_LEADING;
90
 
                }
91
 
        }
92
 
 
93
 
        cob_move (f, &temp);
94
 
        for (i = 0; i < size; ++i) {
95
 
                unsigned char chr = temp.data[i];
96
 
                if (putc (chr, fp) != chr) {
97
 
                        break;
98
 
                }
99
 
        }
100
 
}
101
 
 
102
 
static void
103
 
pretty_display_numeric (cob_field *f, FILE *fp)
104
 
{
105
 
        unsigned short          digits = COB_FIELD_DIGITS (f);
106
 
        const signed short      scale = COB_FIELD_SCALE (f);
107
 
        int                     size = digits + !!COB_FIELD_HAVE_SIGN (f) + !!scale;
108
116
        /* Note: while we only need one pair, the double one works around a bug in
109
117
                 old GCC versions https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 */
110
118
        cob_pic_symbol  pic[6] = {{ 0 }};
111
 
        cob_pic_symbol  *p;
 
119
        cob_pic_symbol  *p = pic;
 
120
 
 
121
        digits = COB_FIELD_DIGITS (f);
 
122
        if (scale == 0) {               /* PIC 999 */
 
123
                size = digits + has_sign;
 
124
        } else if (scale < 0) { /* PIC P99 */
 
125
                size = digits + has_sign;
 
126
        } else {
 
127
                if (digits < scale) {
 
128
                        digits = scale; /* PIC PP9*/
 
129
                } else {
 
130
                        /* PIC 9v99 */
 
131
                }
 
132
                size = digits + has_sign + 1;
 
133
        }
112
134
 
113
135
        if (size > COB_MEDIUM_MAX) {
114
136
                fputs (_("(Not representable)"), fp);
115
137
                return;
116
138
        }
117
 
        if (scale < 0) {
118
 
                digits -= scale;
119
 
                size = digits + !!COB_FIELD_HAVE_SIGN (f);
120
 
        } else if (digits < scale) {
121
 
                digits = scale;
122
 
                size = digits + !!COB_FIELD_HAVE_SIGN (f) + 1;
123
 
        }
124
 
        p = pic;
125
139
 
126
 
        if (COB_FIELD_HAVE_SIGN (f)) {
 
140
        if (has_sign) {
127
141
                if (COB_FIELD_SIGN_SEPARATE (f)
128
 
                 && !COB_FIELD_SIGN_LEADING(f)) {
 
142
                 && !COB_FIELD_SIGN_LEADING (f)) {
129
143
                        /* done later */
130
144
                } else {
131
145
                        p->symbol = '+';
152
166
                p->times_repeated = digits;
153
167
                ++p;
154
168
        }
155
 
        if (COB_FIELD_HAVE_SIGN (f)) {
 
169
        if (has_sign) {
156
170
                if (COB_FIELD_SIGN_SEPARATE (f)
157
 
                 && !COB_FIELD_SIGN_LEADING(f)) {
 
171
                 && !COB_FIELD_SIGN_LEADING (f)) {
158
172
                        p->symbol = '+';
159
173
                        p->times_repeated = 1;
160
174
                        ++p;
163
177
        p->symbol = '\0';
164
178
 
165
179
        {
166
 
                unsigned char   *q = COB_TERM_BUFF;
167
 
                const unsigned char *end = q + size;
168
 
                cob_field_attr  attr;
169
 
                cob_field       temp;
170
 
                temp.size = size;
171
 
                temp.data = q;
172
 
                temp.attr = &attr;
173
 
                COB_ATTR_INIT (COB_TYPE_NUMERIC_EDITED, digits, scale, 0,
174
 
                        (const cob_pic_symbol*)pic);
175
 
 
176
 
                cob_move (f, &temp);
177
 
                while (q != end) {
178
 
                        const int chr = *q++;
179
 
                        if (chr == 0    /* pretty-display stops here */
180
 
                         || putc (chr, fp) != chr) {
181
 
                                break;
 
180
                /* conversion to internal USAGE DISPLAY EDITED */
 
181
                {
 
182
                        cob_field       field;
 
183
                        cob_field_attr  attr;
 
184
                        COB_FIELD_INIT (size, COB_TERM_BUFF, &attr);
 
185
                        COB_ATTR_INIT (COB_TYPE_NUMERIC_EDITED, digits, scale, 0,
 
186
                                (const cob_pic_symbol*)pic);
 
187
 
 
188
                        cob_move (f, &field);
 
189
                }
 
190
 
 
191
                /* output of data to viewport */
 
192
                {
 
193
                        register unsigned char *q = COB_TERM_BUFF;
 
194
                        const unsigned char *end = q + size;
 
195
                        for ( ; q < end; ++q) {
 
196
                                if (*q == 0     /* pretty-display stops here */
 
197
                                 || putc (*q, fp) != *q) {
 
198
                                        break;
 
199
                                }
182
200
                        }
183
201
                }
184
202
        }
215
233
                return;
216
234
        }
217
235
 
218
 
        if (strcmp(wrk,"-NAN") == 0
219
 
         || strcmp(wrk,"-NaNQ") == 0
220
 
         || strcmp(wrk,"-NaN") == 0
221
 
         || strcmp(wrk,"NAN") == 0
222
 
         || strcmp(wrk,"NaNQ") == 0) {
223
 
                strcpy(wrk,"NaN");
 
236
        if (strcmp (wrk,"-NAN") == 0
 
237
         || strcmp (wrk,"-NaNQ") == 0
 
238
         || strcmp (wrk,"-NaN") == 0
 
239
         || strcmp (wrk,"NAN") == 0
 
240
         || strcmp (wrk,"NaNQ") == 0) {
 
241
                strcpy (wrk,"NaN");
224
242
        }
225
243
}
226
244
 
227
245
void
228
246
cob_display_common (const cob_field *f, FILE *fp)
229
247
{
230
 
 
231
 
 
232
248
        if (f->size == 0) {
233
249
                return;
234
250
        }
282
298
                        fprintf (fp, "%x%x", *p >> 4, *p & 0xF);
283
299
                }
284
300
                return;
285
 
        } else if (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_COMP5) {
286
 
                cob_print_realbin (f, fp, f->attr->digits);
287
 
                return;
288
 
        } else if (COB_FIELD_REAL_BINARY(f)
289
 
                || (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_BINARY
290
 
                 && !COB_MODULE_PTR->flag_pretty_display)) {
291
 
                cob_print_realbin (f, fp, bin_digits[f->size]);
292
 
                return;
293
 
        } else if (COB_FIELD_IS_NUMERIC (f)) {
 
301
        }
 
302
        if (COB_FIELD_IS_NUMERIC (f)) {
 
303
                /* CHECKME: consider to check for pretty-printing first */
 
304
                if (COB_FIELD_TYPE (f) == COB_TYPE_NUMERIC_COMP5) {
 
305
                        cob_print_realbin (f, fp, f->attr->digits);
 
306
                        return;
 
307
                }
 
308
                if ( COB_FIELD_REAL_BINARY (f)
 
309
                 || (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_BINARY
 
310
                   && !COB_MODULE_PTR->flag_pretty_display)) {
 
311
                        cob_print_realbin (f, fp, bin_digits[f->size]);
 
312
                        return;
 
313
                }
294
314
                if (COB_MODULE_PTR->flag_pretty_display) {
295
315
                        pretty_display_numeric ((cob_field *)f, fp);
296
 
                } else {
297
 
                        display_numeric ((cob_field *)f, fp);
 
316
                        return;
298
317
                }
 
318
                display_numeric ((cob_field *)f, fp);
299
319
                return;
300
320
        }
301
321
        display_alnum (f, fp);