/* Handle different target file systems for GDB, the GNU Debugger.

   Copyright (C) 2010-2020 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "filesystem.h"
#include "gdbarch.h"
#include "gdbcmd.h"

const char file_system_kind_auto[] = "auto";
const char file_system_kind_unix[] = "unix";
const char file_system_kind_dos_based[] = "dos-based";
const char *const target_file_system_kinds[] =
{
  file_system_kind_auto,
  file_system_kind_unix,
  file_system_kind_dos_based,
  NULL
};
const char *target_file_system_kind = file_system_kind_auto;

const char *
effective_target_file_system_kind (void)
{
  if (target_file_system_kind == file_system_kind_auto)
    {
      if (gdbarch_has_dos_based_file_system (target_gdbarch ()))
	return file_system_kind_dos_based;
      else
	return file_system_kind_unix;
    }
  else
    return target_file_system_kind;
}

const char *
target_lbasename (const char *kind, const char *name)
{
  if (kind == file_system_kind_dos_based)
    return dos_lbasename (name);
  else
    return unix_lbasename (name);
}

static void
show_target_file_system_kind_command (struct ui_file *file,
				      int from_tty,
				      struct cmd_list_element *c,
				      const char *value)
{
  if (target_file_system_kind == file_system_kind_auto)
    fprintf_filtered (file, _("\
The assumed file system kind for target reported file names \
is \"%s\" (currently \"%s\").\n"),
		      value,
		      effective_target_file_system_kind ());
  else
    fprintf_filtered (file, _("\
The assumed file system kind for target reported file names \
is \"%s\".\n"),
		      value);
}

void
_initialize_filesystem (void)
{
  add_setshow_enum_cmd ("target-file-system-kind",
			class_files,
			target_file_system_kinds,
			&target_file_system_kind, _("\
Set assumed file system kind for target reported file names."), _("\
Show assumed file system kind for target reported file names."),
			_("\
If `unix', target file names (e.g., loaded shared library file names)\n\
starting the forward slash (`/') character are considered absolute,\n\
and the directory separator character is the forward slash (`/').  If\n\
`dos-based', target file names starting with a drive letter followed\n\
by a colon (e.g., `c:'), are also considered absolute, and the\n\
backslash (`\\') is also considered a directory separator.  Set to\n\
`auto' (which is the default), to let GDB decide, based on its\n\
knowledge of the target operating system."),
			NULL, /* setfunc */
			show_target_file_system_kind_command,
			&setlist, &showlist);
}
