*** typeck.c Tue May 2 18:46:14 2006 --- typeck.c.warn Tue May 2 18:42:58 2006 *************** *** 2402,2407 **** --- 2402,2410 ---- /* MOVE statement */ if (flag) { cb_warning_x (loc, msg); + if( flag == cb_warn_constant + 100 ) { + warning_destination (src); + } warning_destination (dst); } } *************** *** 2409,2414 **** --- 2412,2434 ---- return 0; } + /* count the number of free places in an alphanumeric edited field */ + static int + count_pic_alphanumeric_edited(struct cb_field *field) + { + int count; + char *p; + unsigned char c; + + count = 0; + for (p = field->pic->str; *p; p += 2) { + if (c == '9' || c == 'A' || c == 'X') { + count += p[1]; + } + } + return( count ); + } + int validate_move (cb_tree src, cb_tree dst, int is_value) { *************** *** 2559,2570 **** case CB_TAG_REFERENCE: { /* non-elementary move */ ! if (cb_field (src)->children || cb_field (dst)->children) break; /* elementary move */ switch (CB_TREE_CATEGORY (src)) { case CB_CATEGORY_ALPHANUMERIC: break; case CB_CATEGORY_ALPHABETIC: case CB_CATEGORY_ALPHANUMERIC_EDITED: --- 2579,2612 ---- case CB_TAG_REFERENCE: { /* non-elementary move */ ! if (cb_field (src)->children || cb_field (dst)->children) { ! if( cb_field(src)->size > cb_field(dst)->size ) { ! goto size_overflow_1; ! } break; + } /* elementary move */ switch (CB_TREE_CATEGORY (src)) { case CB_CATEGORY_ALPHANUMERIC: + switch (CB_TREE_CATEGORY (dst)) { + case CB_CATEGORY_NUMERIC: + case CB_CATEGORY_NUMERIC_EDITED: + if( cb_field(src)->size > cb_field(dst)->pic->digits ) { + goto size_overflow_2; + } + break; + case CB_CATEGORY_ALPHANUMERIC_EDITED: + if( cb_field(src)->size > count_pic_alphanumeric_edited( cb_field(dst) ) ) { + goto size_overflow_1; + } + break; + default: + if( cb_field(src)->size > cb_field(dst)->size ) { + goto size_overflow_1; + } + break; + } break; case CB_CATEGORY_ALPHABETIC: case CB_CATEGORY_ALPHANUMERIC_EDITED: *************** *** 2572,2588 **** case CB_CATEGORY_NUMERIC: case CB_CATEGORY_NUMERIC_EDITED: goto invalid; default: break; } break; case CB_CATEGORY_NUMERIC: case CB_CATEGORY_NUMERIC_EDITED: switch (CB_TREE_CATEGORY (dst)) { case CB_CATEGORY_ALPHABETIC: goto invalid; - case CB_CATEGORY_ALPHANUMERIC: case CB_CATEGORY_ALPHANUMERIC_EDITED: if (CB_TREE_CATEGORY (src) == CB_CATEGORY_NUMERIC && cb_field (src)->pic->scale > 0) { if (cb_move_noninteger_to_alphanumeric == CB_ERROR) --- 2614,2642 ---- case CB_CATEGORY_NUMERIC: case CB_CATEGORY_NUMERIC_EDITED: goto invalid; + case CB_CATEGORY_ALPHANUMERIC_EDITED: + if( cb_field(src)->size > count_pic_alphanumeric_edited( cb_field(dst) ) ) { + goto size_overflow_1; + } + break; default: + if( cb_field(src)->size > cb_field(dst)->size ) { + goto size_overflow_1; + } break; } break; case CB_CATEGORY_NUMERIC: case CB_CATEGORY_NUMERIC_EDITED: switch (CB_TREE_CATEGORY (dst)) { + int src_scale_mod, dst_scale_mod, dst_size_mod; case CB_CATEGORY_ALPHABETIC: goto invalid; case CB_CATEGORY_ALPHANUMERIC_EDITED: + case CB_CATEGORY_ALPHANUMERIC: + dst_size_mod = + CB_TREE_CATEGORY (dst) == CB_CATEGORY_ALPHANUMERIC_EDITED ? + count_pic_alphanumeric_edited( cb_field(dst) ) : cb_field(dst)->size; if (CB_TREE_CATEGORY (src) == CB_CATEGORY_NUMERIC && cb_field (src)->pic->scale > 0) { if (cb_move_noninteger_to_alphanumeric == CB_ERROR) *************** *** 2590,2596 **** --- 2644,2668 ---- cb_warning_x (loc, _("move non-integer to alphanumeric")); break; } + if (CB_TREE_CATEGORY (src) == CB_CATEGORY_NUMERIC + && cb_field(src)->pic->digits > dst_size_mod ) { + goto size_overflow_2; + } + if (CB_TREE_CATEGORY (src) == CB_CATEGORY_NUMERIC_EDITED + && cb_field(src)->size > dst_size_mod ) { + goto size_overflow_1; + } + break; default: + src_scale_mod = cb_field(src)->pic->scale < 0 ? + 0 : cb_field(src)->pic->scale; + dst_scale_mod = cb_field(dst)->pic->scale < 0 ? + 0 : cb_field(dst)->pic->scale; + if( cb_field(src)->pic->digits - src_scale_mod > + cb_field(dst)->pic->digits - dst_scale_mod || + src_scale_mod > dst_scale_mod ) { + goto size_overflow_2; + } break; } break; *************** *** 2632,2637 **** --- 2704,2715 ---- size_overflow: return move_error (src, dst, is_value, cb_warn_constant, _("value size exceeds data size")); + + size_overflow_1: + return move_error (src, dst, is_value, cb_warn_constant+100, _("sending field larger than receiving field")); + + size_overflow_2: + return move_error (src, dst, is_value, cb_warn_constant+100, _("some digits may be truncated")); } static cb_tree