/* Without padding, terminate the I/O statement without assigning
the value. With padding, the value still needs to be assigned,
so we can just continue with a short read. */
/* Without padding, terminate the I/O statement without assigning
the value. With padding, the value still needs to be assigned,
so we can just continue with a short read. */
- memset (&dtp->u.p, 0, sizeof (dtp->u.p));
+
+ /* To maintain ABI, &transfer is the start of the private memory area in
+ in st_parameter_dt. Memory from the beginning of the structure to this
+ point is set by the front end and must not be touched. The number of
+ bytes to clear must stay within the sizeof q to avoid over-writing. */
+ memset (&dtp->u.p.transfer, 0, sizeof (dtp->u.q));
+
- if (dtp->common.unit < 0)
- {
- close_unit (dtp->u.p.current_unit);
- dtp->u.p.current_unit = NULL;
- generate_error (&dtp->common, LIBERROR_BAD_OPTION,
- "Bad unit number in OPEN statement");
- return;
- }
- memset (&u_flags, '\0', sizeof (u_flags));
- u_flags.access = ACCESS_SEQUENTIAL;
- u_flags.action = ACTION_READWRITE;
-
- /* Is it unformatted? */
- if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
- | IOPARM_DT_IONML_SET)))
- u_flags.form = FORM_UNFORMATTED;
- else
- u_flags.form = FORM_UNSPECIFIED;
-
- u_flags.delim = DELIM_UNSPECIFIED;
- u_flags.blank = BLANK_UNSPECIFIED;
- u_flags.pad = PAD_UNSPECIFIED;
- u_flags.decimal = DECIMAL_UNSPECIFIED;
- u_flags.encoding = ENCODING_UNSPECIFIED;
- u_flags.async = ASYNC_UNSPECIFIED;
- u_flags.round = ROUND_UNSPECIFIED;
- u_flags.sign = SIGN_UNSPECIFIED;
- u_flags.status = STATUS_UNKNOWN;
-
- conv = get_unformatted_convert (dtp->common.unit);
-
- if (conv == GFC_CONVERT_NONE)
- conv = compile_options.convert;
-
- /* We use big_endian, which is 0 on little-endian machines
- and 1 on big-endian machines. */
- switch (conv)
- {
- case GFC_CONVERT_NATIVE:
- case GFC_CONVERT_SWAP:
- break;
+ if (dtp->common.unit < 0)
+ {
+ close_unit (dtp->u.p.current_unit);
+ dtp->u.p.current_unit = NULL;
+ generate_error (&dtp->common, LIBERROR_BAD_OPTION,
+ "Bad unit number in OPEN statement");
+ return;
+ }
+ memset (&u_flags, '\0', sizeof (u_flags));
+ u_flags.access = ACCESS_SEQUENTIAL;
+ u_flags.action = ACTION_READWRITE;
+
+ /* Is it unformatted? */
+ if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
+ | IOPARM_DT_IONML_SET)))
+ u_flags.form = FORM_UNFORMATTED;
+ else
+ u_flags.form = FORM_UNSPECIFIED;
+
+ u_flags.delim = DELIM_UNSPECIFIED;
+ u_flags.blank = BLANK_UNSPECIFIED;
+ u_flags.pad = PAD_UNSPECIFIED;
+ u_flags.decimal = DECIMAL_UNSPECIFIED;
+ u_flags.encoding = ENCODING_UNSPECIFIED;
+ u_flags.async = ASYNC_UNSPECIFIED;
+ u_flags.round = ROUND_UNSPECIFIED;
+ u_flags.sign = SIGN_UNSPECIFIED;
+
+ u_flags.status = STATUS_UNKNOWN;
+
+ conv = get_unformatted_convert (dtp->common.unit);
+
+ if (conv == GFC_CONVERT_NONE)
+ conv = compile_options.convert;
+
+ /* We use big_endian, which is 0 on little-endian machines
+ and 1 on big-endian machines. */
+ switch (conv)
+ {
+ case GFC_CONVERT_NATIVE:
+ case GFC_CONVERT_SWAP:
+ break;
- /* Check the decimal mode. */
-
- dtp->u.p.decimal_status
- = !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
- find_option (&dtp->common, dtp->decimal, dtp->decimal_len, decimal_opt,
- "Bad DECIMAL parameter in data transfer statement");
+ /* To maintain ABI check these only if we have the F2003 flag set. */
+ if(cf & IOPARM_DT_HAS_F2003)
+ {
+ /* Check the decimal mode. */
+ dtp->u.p.decimal_status
+ = !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
+ find_option (&dtp->common, dtp->u.p.decimal, dtp->u.p.decimal_len,
+ decimal_opt, "Bad DECIMAL parameter in data transfer "
+ "statement");
- /* Check the sign mode. */
- dtp->u.p.sign_status
- = !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
- find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
- "Bad SIGN parameter in data transfer statement");
+ /* Check the sign mode. */
+ dtp->u.p.sign_status
+ = !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
+ find_option (&dtp->common, dtp->u.p.sign, dtp->u.p.sign_len, sign_opt,
+ "Bad SIGN parameter in data transfer statement");
- if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
- dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
-
- /* Check the blank mode. */
- dtp->u.p.blank_status
- = !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
- find_option (&dtp->common, dtp->blank, dtp->blank_len, blank_opt,
- "Bad BLANK parameter in data transfer statement");
+ if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
+ dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
+
+ /* Check the blank mode. */
+ dtp->u.p.blank_status
+ = !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
+ find_option (&dtp->common, dtp->u.p.blank, dtp->u.p.blank_len,
+ blank_opt,
+ "Bad BLANK parameter in data transfer statement");
- /* Check the delim mode. */
- dtp->u.p.delim_status
- = !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
- find_option (&dtp->common, dtp->delim, dtp->delim_len, delim_opt,
- "Bad DELIM parameter in data transfer statement");
+ /* Check the delim mode. */
+ dtp->u.p.delim_status
+ = !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
+ find_option (&dtp->common, dtp->u.p.delim, dtp->u.p.delim_len,
+ delim_opt,
+ "Bad DELIM parameter in data transfer statement");
- if (dtp->u.p.delim_status == DELIM_UNSPECIFIED)
- dtp->u.p.delim_status = dtp->u.p.current_unit->flags.delim;
-
- /* Check the pad mode. */
- dtp->u.p.pad_status
- = !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
- find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
- "Bad PAD parameter in data transfer statement");
+ if (dtp->u.p.delim_status == DELIM_UNSPECIFIED)
+ dtp->u.p.delim_status = dtp->u.p.current_unit->flags.delim;
+
+ /* Check the pad mode. */
+ dtp->u.p.pad_status
+ = !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
+ find_option (&dtp->common, dtp->u.p.pad, dtp->u.p.pad_len, pad_opt,
+ "Bad PAD parameter in data transfer statement");