+DEFUN ("coding-system-canonical-name-p", Fcoding_system_canonical_name_p, 1, 1, 0, /*
+Return t if OBJECT names a coding system, and is not a coding system alias.
+*/
+ (object))
+{
+ return CODING_SYSTEMP (Fgethash (object, Vcoding_system_hash_table, Qnil))
+ ? Qt : Qnil;
+}
+
+DEFUN ("coding-system-alias-p", Fcoding_system_alias_p, 1, 1, 0, /*
+Return t if OBJECT is a coding system alias.
+All coding system aliases are created by `define-coding-system-alias'.
+*/
+ (object))
+{
+ return SYMBOLP (Fgethash (object, Vcoding_system_hash_table, Qzero))
+ ? Qt : Qnil;
+}
+
+DEFUN ("coding-system-aliasee", Fcoding_system_aliasee, 1, 1, 0, /*
+Return the coding-system symbol for which symbol ALIAS is an alias.
+*/
+ (alias))
+{
+ Lisp_Object aliasee = Fgethash (alias, Vcoding_system_hash_table, Qnil);
+ if (SYMBOLP (aliasee))
+ return aliasee;
+ else
+ signal_simple_error ("Symbol is not a coding system alias", alias);
+ return Qnil; /* To keep the compiler happy */
+}
+
+static Lisp_Object
+append_suffix_to_symbol (Lisp_Object symbol, const char *ascii_string)
+{
+ return Fintern (concat2 (Fsymbol_name (symbol), build_string (ascii_string)),
+ Qnil);
+}
+
+/* A maphash function, for removing dangling coding system aliases. */
+static int
+dangling_coding_system_alias_p (Lisp_Object alias,
+ Lisp_Object aliasee,
+ void *dangling_aliases)
+{
+ if (SYMBOLP (aliasee)
+ && NILP (Fgethash (aliasee, Vcoding_system_hash_table, Qnil)))
+ {
+ (*(int *) dangling_aliases)++;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias, 2, 2, 0, /*
+Define symbol ALIAS as an alias for coding system ALIASEE.
+
+You can use this function to redefine an alias that has already been defined,
+but you cannot redefine a name which is the canonical name for a coding system.
+\(a canonical name of a coding system is what is returned when you call
+`coding-system-name' on a coding system).
+
+ALIASEE itself can be an alias, which allows you to define nested aliases.
+
+You are forbidden, however, from creating alias loops or `dangling' aliases.
+These will be detected, and an error will be signaled if you attempt to do so.
+
+If ALIASEE is nil, then ALIAS will simply be undefined.
+
+See also `coding-system-alias-p', `coding-system-aliasee',
+and `coding-system-canonical-name-p'.
+*/
+ (alias, aliasee))
+{
+ Lisp_Object real_coding_system, probe;
+
+ CHECK_SYMBOL (alias);
+
+ if (!NILP (Fcoding_system_canonical_name_p (alias)))
+ signal_simple_error
+ ("Symbol is the canonical name of a coding system and cannot be redefined",
+ alias);
+
+ if (NILP (aliasee))
+ {
+ Lisp_Object subsidiary_unix = append_suffix_to_symbol (alias, "-unix");
+ Lisp_Object subsidiary_dos = append_suffix_to_symbol (alias, "-dos");
+ Lisp_Object subsidiary_mac = append_suffix_to_symbol (alias, "-mac");
+
+ Fremhash (alias, Vcoding_system_hash_table);
+
+ /* Undefine subsidiary aliases,
+ presumably created by a previous call to this function */
+ if (! NILP (Fcoding_system_alias_p (subsidiary_unix)) &&
+ ! NILP (Fcoding_system_alias_p (subsidiary_dos)) &&
+ ! NILP (Fcoding_system_alias_p (subsidiary_mac)))
+ {
+ Fdefine_coding_system_alias (subsidiary_unix, Qnil);
+ Fdefine_coding_system_alias (subsidiary_dos, Qnil);
+ Fdefine_coding_system_alias (subsidiary_mac, Qnil);
+ }
+
+ /* Undefine dangling coding system aliases. */
+ {
+ int dangling_aliases;
+
+ do {
+ dangling_aliases = 0;
+ elisp_map_remhash (dangling_coding_system_alias_p,
+ Vcoding_system_hash_table,
+ &dangling_aliases);
+ } while (dangling_aliases > 0);
+ }
+
+ return Qnil;
+ }
+
+ if (CODING_SYSTEMP (aliasee))
+ aliasee = XCODING_SYSTEM_NAME (aliasee);
+
+ /* Checks that aliasee names a coding-system */
+ real_coding_system = Fget_coding_system (aliasee);
+
+ /* Check for coding system alias loops */
+ if (EQ (alias, aliasee))
+ alias_loop: signal_simple_error_2
+ ("Attempt to create a coding system alias loop", alias, aliasee);
+
+ for (probe = aliasee;
+ SYMBOLP (probe);
+ probe = Fgethash (probe, Vcoding_system_hash_table, Qzero))
+ {
+ if (EQ (probe, alias))
+ goto alias_loop;
+ }
+
+ Fputhash (alias, aliasee, Vcoding_system_hash_table);
+
+ /* Set up aliases for subsidiaries.
+ #### There must be a better way to handle subsidiary coding systems. */
+ {
+ static const char *suffixes[] = { "-unix", "-dos", "-mac" };
+ int i;
+ for (i = 0; i < countof (suffixes); i++)
+ {
+ Lisp_Object alias_subsidiary =
+ append_suffix_to_symbol (alias, suffixes[i]);
+ Lisp_Object aliasee_subsidiary =
+ append_suffix_to_symbol (aliasee, suffixes[i]);
+
+ if (! NILP (Ffind_coding_system (aliasee_subsidiary)))
+ Fdefine_coding_system_alias (alias_subsidiary, aliasee_subsidiary);
+ }
+ }
+ /* FSF return value is a vector of [ALIAS-unix ALIAS-dos ALIAS-mac],
+ but it doesn't look intentional, so I'd rather return something
+ meaningful or nothing at all. */
+ return Qnil;
+}
+