void
st_inquire (st_parameter_inquire *iqp)
{
  gfc_unit *u;

  library_start (&iqp->common);

  if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
    {
      u = find_unit (iqp->common.unit);
      inquire_via_unit (iqp, u);
    }
  else
    {
      u = find_file (iqp->file, iqp->file_len);
      if (u == NULL)
	inquire_via_filename (iqp);
      else
	inquire_via_unit (iqp, u);
    }
  if (u != NULL)
    unlock_unit (u);

  library_end ();
}
void
st_close (st_parameter_close *clp)
{
  close_status status;
  gfc_unit *u;
#if !HAVE_UNLINK_OPEN_FILE
  char * path;

  path = NULL;
#endif

  library_start (&clp->common);

  status = !(clp->common.flags & IOPARM_CLOSE_HAS_STATUS) ? CLOSE_UNSPECIFIED :
    find_option (&clp->common, clp->status, clp->status_len,
		 status_opt, "Bad STATUS parameter in CLOSE statement");

  if ((clp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
  {
    library_end ();
    return;
  }

  u = find_unit (clp->common.unit);
  if (u != NULL)
    {
      if (u->flags.status == STATUS_SCRATCH)
	{
	  if (status == CLOSE_KEEP)
	    generate_error (&clp->common, LIBERROR_BAD_OPTION,
			    "Can't KEEP a scratch file on CLOSE");
#if !HAVE_UNLINK_OPEN_FILE
	  path = (char *) gfc_alloca (u->file_len + 1);
          unpack_filename (path, u->file, u->file_len);
#endif
	}
      else
	{
	  if (status == CLOSE_DELETE)
            {
#if HAVE_UNLINK_OPEN_FILE
	      delete_file (u);
#else
	      path = (char *) gfc_alloca (u->file_len + 1);
              unpack_filename (path, u->file, u->file_len);
#endif
            }
	}

      close_unit (u);

#if !HAVE_UNLINK_OPEN_FILE
      if (path != NULL)
        unlink (path);
#endif
    }

  /* CLOSE on unconnected unit is legal and a no-op: F95 std., 9.3.5. */ 
  library_end ();
}
void
st_rewind (st_parameter_filepos *fpp)
{
  gfc_unit *u;

  library_start (&fpp->common);

  u = find_unit (fpp->common.unit);
  if (u != NULL)
    {
      if (u->flags.access == ACCESS_DIRECT)
	generate_error (&fpp->common, LIBERROR_BAD_OPTION,
			"Cannot REWIND a file opened for DIRECT access");
      else
	{
	  /* If there are previously written bytes from a write with ADVANCE="no",
	     add a record marker before performing the ENDFILE.  */

	  if (u->previous_nonadvancing_write)
	    finish_last_advance_record (u);

	  u->previous_nonadvancing_write = 0;

	  fbuf_reset (u);

	  u->last_record = 0;

	  if (sseek (u->s, 0, SEEK_SET) < 0)
	    generate_error (&fpp->common, LIBERROR_OS, NULL);

	  /* Handle special files like /dev/null differently.  */
	  if (!is_special (u->s))
	    {
	      /* We are rewinding so we are not at the end.  */
	      u->endfile = NO_ENDFILE;
	    }
	  else
	    {
	      /* Set this for compatibilty with g77 for /dev/null.  */
	      if (file_length (u->s) == 0  && stell (u->s) == 0)
		u->endfile = AT_ENDFILE;
	      /* Future refinements on special files can go here.  */
	    }

	  u->current_record = 0;
	  u->strm_pos = 1;
	  u->read_bad = 0;
	}
      /* Update position for INQUIRE.  */
      u->flags.position = POSITION_REWIND;
      unlock_unit (u);
    }

  library_end ();
}
void
st_endfile (st_parameter_filepos *fpp)
{
  gfc_unit *u;

  library_start (&fpp->common);

  u = find_unit (fpp->common.unit);
  if (u != NULL)
    {
      if (u->flags.access == ACCESS_DIRECT)
	{
	  generate_error (&fpp->common, LIBERROR_OPTION_CONFLICT,
			  "Cannot perform ENDFILE on a file opened"
			  " for DIRECT access");
	  goto done;
	}

      /* If there are previously written bytes from a write with ADVANCE="no",
	 add a record marker before performing the ENDFILE.  */

      if (u->previous_nonadvancing_write)
	finish_last_advance_record (u);

      u->previous_nonadvancing_write = 0;

      if (u->current_record)
	{
	  st_parameter_dt dtp;
	  dtp.common = fpp->common;
	  memset (&dtp.u.p, 0, sizeof (dtp.u.p));
	  dtp.u.p.current_unit = u;
	  next_record (&dtp, 1);
	}

      unit_truncate (u, stell (u->s), &fpp->common);
      u->endfile = AFTER_ENDFILE;
      if (0 == stell (u->s))
        u->flags.position = POSITION_REWIND;
    done:
      unlock_unit (u);
    }

  library_end ();
}
void
st_endfile (void)
{
  gfc_unit *u;

  library_start ();

  u = get_unit (0);
  if (u != NULL)
    {
      current_unit = u;		/* next_record() needs this set */
      if (u->current_record)
	next_record (1);

      flush(u->s);
      struncate (u->s);
      u->endfile = AFTER_ENDFILE;
    }

  library_end ();
}
void
st_flush (st_parameter_filepos *fpp)
{
  gfc_unit *u;

  library_start (&fpp->common);

  u = find_unit (fpp->common.unit);
  if (u != NULL)
    {
      /* Make sure format buffer is flushed.  */
      if (u->flags.form == FORM_FORMATTED)
        fbuf_flush (u, u->mode);

      sflush (u->s);
      unlock_unit (u);
    }
  else
    /* FLUSH on unconnected unit is illegal: F95 std., 9.3.5. */ 
    generate_error (&fpp->common, LIBERROR_BAD_OPTION,
			"Specified UNIT in FLUSH is not connected");

  library_end ();
}
void
st_open (void)
{
  unit_flags flags;
  gfc_unit *u = NULL;
 
  library_start ();

  /* Decode options.  */

  flags.access = (ioparm.access == NULL) ? ACCESS_UNSPECIFIED :
    find_option (ioparm.access, ioparm.access_len, access_opt,
		 "Bad ACCESS parameter in OPEN statement");

  flags.action = (ioparm.action == NULL) ? ACTION_UNSPECIFIED :
    find_option (ioparm.action, ioparm.action_len, action_opt,
		 "Bad ACTION parameter in OPEN statement");

  flags.blank = (ioparm.blank == NULL) ? BLANK_UNSPECIFIED :
    find_option (ioparm.blank, ioparm.blank_len, blank_opt,
		 "Bad BLANK parameter in OPEN statement");

  flags.delim = (ioparm.delim == NULL) ? DELIM_UNSPECIFIED :
    find_option (ioparm.delim, ioparm.delim_len, delim_opt,
		 "Bad DELIM parameter in OPEN statement");

  flags.pad = (ioparm.pad == NULL) ? PAD_UNSPECIFIED :
    find_option (ioparm.pad, ioparm.pad_len, pad_opt,
		 "Bad PAD parameter in OPEN statement");

  flags.form = (ioparm.form == NULL) ? FORM_UNSPECIFIED :
    find_option (ioparm.form, ioparm.form_len, form_opt,
		 "Bad FORM parameter in OPEN statement");

  flags.position = (ioparm.position == NULL) ? POSITION_UNSPECIFIED :
    find_option (ioparm.position, ioparm.position_len, position_opt,
		 "Bad POSITION parameter in OPEN statement");

  flags.status = (ioparm.status == NULL) ? STATUS_UNSPECIFIED :
    find_option (ioparm.status, ioparm.status_len, status_opt,
		 "Bad STATUS parameter in OPEN statement");

  if (ioparm.unit < 0)
    generate_error (ERROR_BAD_OPTION, "Bad unit number in OPEN statement");

  if (flags.position != POSITION_UNSPECIFIED
      && flags.access == ACCESS_DIRECT)
    generate_error (ERROR_BAD_OPTION,
		    "Cannot use POSITION with direct access files");

  if (flags.position == POSITION_UNSPECIFIED)
    flags.position = POSITION_ASIS;

  if (ioparm.library_return != LIBRARY_OK)
  {
    library_end ();
    return;
  }

  u = find_unit (ioparm.unit);

  if (u == NULL)
    new_unit (&flags);
  else
    already_open (u, &flags);

  library_end ();
}
示例#8
0
文件: open.c 项目: delkon/gcc
void
st_open (st_parameter_open *opp)
{
  unit_flags flags;
  gfc_unit *u = NULL;
  GFC_INTEGER_4 cf = opp->common.flags;
  unit_convert conv;
 
  library_start (&opp->common);

  /* Decode options.  */

  flags.access = !(cf & IOPARM_OPEN_HAS_ACCESS) ? ACCESS_UNSPECIFIED :
    find_option (&opp->common, opp->access, opp->access_len,
		 access_opt, "Bad ACCESS parameter in OPEN statement");

  flags.action = !(cf & IOPARM_OPEN_HAS_ACTION) ? ACTION_UNSPECIFIED :
    find_option (&opp->common, opp->action, opp->action_len,
		 action_opt, "Bad ACTION parameter in OPEN statement");

  flags.blank = !(cf & IOPARM_OPEN_HAS_BLANK) ? BLANK_UNSPECIFIED :
    find_option (&opp->common, opp->blank, opp->blank_len,
		 blank_opt, "Bad BLANK parameter in OPEN statement");

  flags.delim = !(cf & IOPARM_OPEN_HAS_DELIM) ? DELIM_UNSPECIFIED :
    find_option (&opp->common, opp->delim, opp->delim_len,
		 delim_opt, "Bad DELIM parameter in OPEN statement");

  flags.pad = !(cf & IOPARM_OPEN_HAS_PAD) ? PAD_UNSPECIFIED :
    find_option (&opp->common, opp->pad, opp->pad_len,
		 pad_opt, "Bad PAD parameter in OPEN statement");

  flags.decimal = !(cf & IOPARM_OPEN_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
    find_option (&opp->common, opp->decimal, opp->decimal_len,
		 decimal_opt, "Bad DECIMAL parameter in OPEN statement");

  flags.encoding = !(cf & IOPARM_OPEN_HAS_ENCODING) ? ENCODING_UNSPECIFIED :
    find_option (&opp->common, opp->encoding, opp->encoding_len,
		 encoding_opt, "Bad ENCODING parameter in OPEN statement");

  flags.async = !(cf & IOPARM_OPEN_HAS_ASYNCHRONOUS) ? ASYNC_UNSPECIFIED :
    find_option (&opp->common, opp->asynchronous, opp->asynchronous_len,
		 async_opt, "Bad ASYNCHRONOUS parameter in OPEN statement");

  flags.round = !(cf & IOPARM_OPEN_HAS_ROUND) ? ROUND_UNSPECIFIED :
    find_option (&opp->common, opp->round, opp->round_len,
		 round_opt, "Bad ROUND parameter in OPEN statement");

  flags.sign = !(cf & IOPARM_OPEN_HAS_SIGN) ? SIGN_UNSPECIFIED :
    find_option (&opp->common, opp->sign, opp->sign_len,
		 sign_opt, "Bad SIGN parameter in OPEN statement");

  flags.form = !(cf & IOPARM_OPEN_HAS_FORM) ? FORM_UNSPECIFIED :
    find_option (&opp->common, opp->form, opp->form_len,
		 form_opt, "Bad FORM parameter in OPEN statement");

  flags.position = !(cf & IOPARM_OPEN_HAS_POSITION) ? POSITION_UNSPECIFIED :
    find_option (&opp->common, opp->position, opp->position_len,
		 position_opt, "Bad POSITION parameter in OPEN statement");

  flags.status = !(cf & IOPARM_OPEN_HAS_STATUS) ? STATUS_UNSPECIFIED :
    find_option (&opp->common, opp->status, opp->status_len,
		 status_opt, "Bad STATUS parameter in OPEN statement");

  /* First, we check wether the convert flag has been set via environment
     variable.  This overrides the convert tag in the open statement.  */

  conv = get_unformatted_convert (opp->common.unit);

  if (conv == GFC_CONVERT_NONE)
    {
      /* Nothing has been set by environment variable, check the convert tag.  */
      if (cf & IOPARM_OPEN_HAS_CONVERT)
	conv = find_option (&opp->common, opp->convert, opp->convert_len,
			    convert_opt,
			    "Bad CONVERT parameter in OPEN statement");
      else
	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;
      
    case GFC_CONVERT_BIG:
      conv = big_endian ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
      break;
      
    case GFC_CONVERT_LITTLE:
      conv = big_endian ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
      break;
      
    default:
      internal_error (&opp->common, "Illegal value for CONVERT");
      break;
    }

  flags.convert = conv;

  if (flags.position != POSITION_UNSPECIFIED
      && flags.access == ACCESS_DIRECT)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot use POSITION with direct access files");

  if (flags.access == ACCESS_APPEND)
    {
      if (flags.position != POSITION_UNSPECIFIED
	  && flags.position != POSITION_APPEND)
	generate_error (&opp->common, LIBERROR_BAD_OPTION,
			"Conflicting ACCESS and POSITION flags in"
			" OPEN statement");

      notify_std (&opp->common, GFC_STD_GNU,
		  "Extension: APPEND as a value for ACCESS in OPEN statement");
      flags.access = ACCESS_SEQUENTIAL;
      flags.position = POSITION_APPEND;
    }

  if (flags.position == POSITION_UNSPECIFIED)
    flags.position = POSITION_ASIS;

  if ((opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
    {
      if ((opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT))
	opp->common.unit = get_unique_unit_number(opp);
      else if (opp->common.unit < 0)
	{
	  u = find_unit (opp->common.unit);
	  if (u == NULL) /* Negative unit and no NEWUNIT-created unit found.  */
	    generate_error (&opp->common, LIBERROR_BAD_OPTION,
			    "Bad unit number in OPEN statement");
	}

      if (u == NULL)
	u = find_or_create_unit (opp->common.unit);
      if (u->s == NULL)
	{
	  u = new_unit (opp, u, &flags);
	  if (u != NULL)
	    unlock_unit (u);
	}
      else
	already_open (opp, u, &flags);
    }
    
  if ((opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT)
      && (opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
    *opp->newunit = opp->common.unit;
  
  library_end ();
}
示例#9
0
文件: close.c 项目: kraj/gcc
void
st_close (st_parameter_close *clp)
{
  close_status status;
  gfc_unit *u;
#if !HAVE_UNLINK_OPEN_FILE
  char * path;

  path = NULL;
#endif

  library_start (&clp->common);

  status = !(clp->common.flags & IOPARM_CLOSE_HAS_STATUS) ? CLOSE_UNSPECIFIED :
    find_option (&clp->common, clp->status, clp->status_len,
		 status_opt, "Bad STATUS parameter in CLOSE statement");

  if ((clp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
  {
    library_end ();
    return;
  }

  u = find_unit (clp->common.unit);
  if (u != NULL)
    {
      if (close_share (u) < 0)
	generate_error (&clp->common, LIBERROR_OS, "Problem in CLOSE");
      if (u->flags.status == STATUS_SCRATCH)
	{
	  if (status == CLOSE_KEEP)
	    generate_error (&clp->common, LIBERROR_BAD_OPTION,
			    "Can't KEEP a scratch file on CLOSE");
#if !HAVE_UNLINK_OPEN_FILE
	  path = strdup (u->filename);
#endif
	}
      else
	{
	  if (status == CLOSE_DELETE)
	    {
	      if (u->flags.readonly)
		generate_warning (&clp->common, "STATUS set to DELETE on CLOSE"
				  " but file protected by READONLY specifier");
	      else
		{
#if HAVE_UNLINK_OPEN_FILE
		  remove (u->filename);
#else
		  path = strdup (u->filename);
#endif
		}
	    }
	}

      close_unit (u);

#if !HAVE_UNLINK_OPEN_FILE
      if (path != NULL)
	{
	  remove (path);
	  free (path);
	}
#endif
    }

  /* CLOSE on unconnected unit is legal and a no-op: F95 std., 9.3.5. */ 
  library_end ();
}
void
st_backspace (st_parameter_filepos *fpp)
{
  gfc_unit *u;

  library_start (&fpp->common);

  u = find_unit (fpp->common.unit);
  if (u == NULL)
    {
      generate_error (&fpp->common, LIBERROR_BAD_UNIT, NULL);
      goto done;
    }

  /* Direct access is prohibited, and so is unformatted stream access.  */


  if (u->flags.access == ACCESS_DIRECT)
    {
      generate_error (&fpp->common, LIBERROR_OPTION_CONFLICT,
		      "Cannot BACKSPACE a file opened for DIRECT access");
      goto done;
    }

  if (u->flags.access == ACCESS_STREAM && u->flags.form == FORM_UNFORMATTED)
    {
      generate_error (&fpp->common, LIBERROR_OPTION_CONFLICT,
                      "Cannot BACKSPACE an unformatted stream file");
      goto done;
    }

  /* Make sure format buffer is flushed and reset.  */
  if (u->flags.form == FORM_FORMATTED)
    {
      int pos = fbuf_reset (u);
      if (pos != 0)
        sseek (u->s, pos, SEEK_CUR);
    }

  
  /* Check for special cases involving the ENDFILE record first.  */

  if (u->endfile == AFTER_ENDFILE)
    {
      u->endfile = AT_ENDFILE;
      u->flags.position = POSITION_APPEND;
      sflush (u->s);
    }
  else
    {
      if (stell (u->s) == 0)
	{
	  u->flags.position = POSITION_REWIND;
	  goto done;		/* Common special case */
	}

      if (u->mode == WRITING)
	{
	  /* If there are previously written bytes from a write with
	     ADVANCE="no", add a record marker before performing the
	     BACKSPACE.  */

	  if (u->previous_nonadvancing_write)
	    finish_last_advance_record (u);

	  u->previous_nonadvancing_write = 0;

	  unit_truncate (u, stell (u->s), &fpp->common);
	  u->mode = READING;
        }

      if (u->flags.form == FORM_FORMATTED)
	formatted_backspace (fpp, u);
      else
	unformatted_backspace (fpp, u);

      u->flags.position = POSITION_UNSPECIFIED;
      u->endfile = NO_ENDFILE;
      u->current_record = 0;
      u->bytes_left = 0;
    }

 done:
  if (u != NULL)
    unlock_unit (u);

  library_end ();
}
示例#11
0
文件: file_pos.c 项目: abumaryam/gcc
void
st_endfile (st_parameter_filepos *fpp)
{
  gfc_unit *u;

  library_start (&fpp->common);

  u = find_unit (fpp->common.unit);
  if (u != NULL)
    {
      if (u->flags.access == ACCESS_DIRECT)
	{
	  generate_error (&fpp->common, LIBERROR_OPTION_CONFLICT,
			  "Cannot perform ENDFILE on a file opened "
			  "for DIRECT access");
	  goto done;
	}

      if (u->flags.access == ACCESS_SEQUENTIAL
      	  && u->endfile == AFTER_ENDFILE)
	{
	  generate_error (&fpp->common, LIBERROR_OPTION_CONFLICT,
			  "Cannot perform ENDFILE on a file already "
			  "positioned after the EOF marker");
	  goto done;
	}

      /* If there are previously written bytes from a write with ADVANCE="no",
	 add a record marker before performing the ENDFILE.  */

      if (u->previous_nonadvancing_write)
	finish_last_advance_record (u);

      u->previous_nonadvancing_write = 0;

      if (u->current_record)
	{
	  st_parameter_dt dtp;
	  dtp.common = fpp->common;
	  memset (&dtp.u.p, 0, sizeof (dtp.u.p));
	  dtp.u.p.current_unit = u;
	  next_record (&dtp, 1);
	}

      unit_truncate (u, stell (u->s), &fpp->common);
      u->endfile = AFTER_ENDFILE;
      if (0 == stell (u->s))
        u->flags.position = POSITION_REWIND;
    }
  else
    {
      if (fpp->common.unit < 0)
	{
	  generate_error (&fpp->common, LIBERROR_BAD_OPTION,
			  "Bad unit number in statement");
	  return;
	}

      u = find_or_create_unit (fpp->common.unit);
      if (u->s == NULL)
	{
	  /* Open the unit with some default flags.  */
	  st_parameter_open opp;
	  unit_flags u_flags;

	  memset (&u_flags, '\0', sizeof (u_flags));
	  u_flags.access = ACCESS_SEQUENTIAL;
	  u_flags.action = ACTION_READWRITE;

	  /* Is it unformatted?  */
	  if (!(fpp->common.flags & (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;
	  u_flags.convert = GFC_CONVERT_NATIVE;

	  opp.common = fpp->common;
	  opp.common.flags &= IOPARM_COMMON_MASK;
	  u = new_unit (&opp, u, &u_flags);
	  if (u == NULL)
	    return;
	  u->endfile = AFTER_ENDFILE;
	}
    }

  done:
    unlock_unit (u);

  library_end ();
}