open.c

来自「gcc-fortran,linux使用fortran的编译软件。很好用的。」· C语言 代码 · 共 624 行 · 第 1/2 页

C
624
字号
      goto fail;    }  switch (flags->status)    {    case STATUS_SCRATCH:      if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) == 0)	{	  opp->file = NULL;	  break;	}      generate_error (&opp->common, ERROR_BAD_OPTION,		      "FILE parameter must not be present in OPEN statement");      goto fail;    case STATUS_OLD:    case STATUS_NEW:    case STATUS_REPLACE:    case STATUS_UNKNOWN:      if ((opp->common.flags & IOPARM_OPEN_HAS_FILE))	break;      opp->file = tmpname;      opp->file_len = sprintf(opp->file, "fort.%d", opp->common.unit);      break;    default:      internal_error (&opp->common, "new_unit(): Bad status");    }  /* Make sure the file isn't already open someplace else.     Do not error if opening file preconnected to stdin, stdout, stderr.  */  u2 = NULL;  if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) != 0)    u2 = find_file (opp->file, opp->file_len);  if (u2 != NULL      && (options.stdin_unit < 0 || u2->unit_number != options.stdin_unit)      && (options.stdout_unit < 0 || u2->unit_number != options.stdout_unit)      && (options.stderr_unit < 0 || u2->unit_number != options.stderr_unit))    {      unlock_unit (u2);      generate_error (&opp->common, ERROR_ALREADY_OPEN, NULL);      goto cleanup;    }  if (u2 != NULL)    unlock_unit (u2);  /* Open file.  */  s = open_external (opp, flags);  if (s == NULL)    {      generate_error (&opp->common, ERROR_OS, NULL);      goto cleanup;    }  if (flags->status == STATUS_NEW || flags->status == STATUS_REPLACE)    flags->status = STATUS_OLD;  /* Create the unit structure.  */  u->file = get_mem (opp->file_len);  if (u->unit_number != opp->common.unit)    internal_error (&opp->common, "Unit number changed");  u->s = s;  u->flags = *flags;  u->read_bad = 0;  u->endfile = NO_ENDFILE;  u->last_record = 0;  u->current_record = 0;  u->mode = READING;  u->maxrec = 0;  u->bytes_left = 0;  if (flags->position == POSITION_APPEND)    {      if (sseek (u->s, file_length (u->s)) == FAILURE)	generate_error (&opp->common, ERROR_OS, NULL);      u->endfile = AT_ENDFILE;    }  /* Unspecified recl ends up with a processor dependent value.  */  if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN))    u->recl = opp->recl_in;  else    u->recl = max_offset;  /* If the file is direct access, calculate the maximum record number     via a division now instead of letting the multiplication overflow     later.  */  if (flags->access == ACCESS_DIRECT)    u->maxrec = max_offset / u->recl;  memmove (u->file, opp->file, opp->file_len);  u->file_len = opp->file_len;  /* Curiously, the standard requires that the     position specifier be ignored for new files so a newly connected     file starts out that the initial point.  We still need to figure     out if the file is at the end or not.  */  test_endfile (u);  if (flags->status == STATUS_SCRATCH && opp->file != NULL)    free_mem (opp->file);  return u; cleanup:  /* Free memory associated with a temporary filename.  */  if (flags->status == STATUS_SCRATCH && opp->file != NULL)    free_mem (opp->file); fail:  close_unit (u);  return NULL;}/* Open a unit which is already open.  This involves changing the   modes or closing what is there now and opening the new file.  */static voidalready_open (st_parameter_open *opp, gfc_unit * u, unit_flags * flags){  if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) == 0)    {      edit_modes (opp, u, flags);      return;    }  /* If the file is connected to something else, close it and open a     new unit.  */  if (!compare_file_filename (u, opp->file, opp->file_len))    {#if !HAVE_UNLINK_OPEN_FILE      char *path = NULL;      if (u->file && u->flags.status == STATUS_SCRATCH)	{	  path = (char *) gfc_alloca (u->file_len + 1);	  unpack_filename (path, u->file, u->file_len);	}#endif      if (sclose (u->s) == FAILURE)	{	  unlock_unit (u);	  generate_error (&opp->common, ERROR_OS,			  "Error closing file in OPEN statement");	  return;	}      u->s = NULL;      if (u->file)	free_mem (u->file);      u->file = NULL;      u->file_len = 0;#if !HAVE_UNLINK_OPEN_FILE      if (path != NULL)	unlink (path);#endif      u = new_unit (opp, u, flags);      if (u != NULL)	unlock_unit (u);      return;    }  edit_modes (opp, u, flags);}/* Open file.  */extern void st_open (st_parameter_open *opp);export_proto(st_open);voidst_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.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 == 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 l8_to_l4_offset, which is 0 on little-endian machines     and 1 on big-endian machines.  */  switch (conv)    {    case CONVERT_NATIVE:    case CONVERT_SWAP:      break;          case CONVERT_BIG:      conv = l8_to_l4_offset ? CONVERT_NATIVE : CONVERT_SWAP;      break;          case CONVERT_LITTLE:      conv = l8_to_l4_offset ? CONVERT_SWAP : CONVERT_NATIVE;      break;          default:      internal_error (&opp->common, "Illegal value for CONVERT");      break;    }  flags.convert = conv;  if (opp->common.unit < 0)    generate_error (&opp->common, ERROR_BAD_OPTION,		    "Bad unit number in OPEN statement");  if (flags.position != POSITION_UNSPECIFIED      && flags.access == ACCESS_DIRECT)    generate_error (&opp->common, ERROR_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, ERROR_BAD_OPTION,			"Conflicting ACCESS and POSITION flags in"			" OPEN statement");      notify_std (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)    {      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);    }  library_end ();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?