#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  %BEGIN

int main(int argc, char **argv) { /*%begin*/
  _imp_initialise(argc, argv);

  //     2  %owninteger Fail=0

  static int FAIL = 0;

  //     3  %STRING(30)S,T,U

  _imp_string30 S;
  _imp_string30 T;
  _imp_string30 U;
  auto void CHECK(_imp_string30 P, _imp_string30 Q, _imp_string30 R);

  //     4  %ROUTINESPEC CHECK(%STRING(30) P,Q,R)
  //     5        S=""; T=S


  /* clang-format off */
_imp_strncpy(/*?*/&S, ({__typeof__(_imp_string255) tmp;/*B*/ tmp = _imp_str_literal(""); (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  /* clang-format off */
_imp_strncpy(/*?*/&T, ({__typeof__(_imp_string30) tmp;/*B*/ tmp = S; (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  //     6        PRINTSTRING("BUG0") %UNLESS T=""


  /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/&T, (_imp_string *)/*?*/_imp_str_literal_ptr("")) == 0) goto L_0001;

  /* clang-format on */
  _imp_PRINTSTRING(_imp_str_literal("BUG0"));
L_0001:;

//     7        CHECK(S,T,"")

  CHECK(
      /* clang-format off */
*({  __typeof__(_imp_string30) tmp = S/*q*/;  (_imp_string30 *)&tmp;  })
      /* clang-format on */
      ,
      /* clang-format off */
*({  __typeof__(_imp_string30) tmp = T/*q*/;  (_imp_string30 *)&tmp;  })
      /* clang-format on */
      ,
      _imp_str_literal_size(30, ""));

  //     8        S="ABCD"; T=S


  /* clang-format off */
_imp_strncpy(/*?*/&S, ({__typeof__(_imp_string255) tmp;/*B*/ tmp = _imp_str_literal("ABCD"); (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  /* clang-format off */
_imp_strncpy(/*?*/&T, ({__typeof__(_imp_string30) tmp;/*B*/ tmp = S; (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  //     9        CHECK(S,T,"ABCD")

  CHECK(
      /* clang-format off */
*({  __typeof__(_imp_string30) tmp = S/*q*/;  (_imp_string30 *)&tmp;  })
      /* clang-format on */
      ,
      /* clang-format off */
*({  __typeof__(_imp_string30) tmp = T/*q*/;  (_imp_string30 *)&tmp;  })
      /* clang-format on */
      ,
      _imp_str_literal_size(30, "ABCD"));

  //    10        %UNLESS "MAST"<="MEST"<="MOST" %THEN Fail=1 %and PRINTSTRING("BUG1")

  {
    // Double-sided test on _imp_str_literal("MEST") (Part I)
    _imp_string *tmp;

    /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/_imp_str_literal_ptr("MAST"), (_imp_string *)(tmp=/*?*/_imp_str_literal_ptr("MEST"))) > 0) goto L_0002;

    /* clang-format on */

    /* clang-format off */
// Double-sided test on _imp_str_literal("MEST") (Part II)
if (_imp_strcmp((_imp_string *)tmp, (_imp_string *)/*?*/_imp_str_literal_ptr("MOST")) <= 0) goto L_0003;
}

/* clang-format on */
L_0002:;
  FAIL = 1;
  _imp_PRINTSTRING(_imp_str_literal("BUG1"));
L_0003:;

//    11        S="MAST"; T="MEST"; U="MOST"


  /* clang-format off */
_imp_strncpy(/*?*/&S, ({__typeof__(_imp_string255) tmp;/*B*/ tmp = _imp_str_literal("MAST"); (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  /* clang-format off */
_imp_strncpy(/*?*/&T, ({__typeof__(_imp_string255) tmp;/*B*/ tmp = _imp_str_literal("MEST"); (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  /* clang-format off */
_imp_strncpy(/*?*/&U, ({__typeof__(_imp_string255) tmp;/*B*/ tmp = _imp_str_literal("MOST"); (void *)&tmp;}), /*max:*/30);

  /* clang-format on */

  //    12        %UNLESS S<=T<=U %THEN Fail=1 %and PRINTSTRING("BUG2")

  {
    // Double-sided test on T (Part I)
    _imp_string30 *tmp;

    /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/&S, (_imp_string *)(tmp=/*?*/&T)) > 0) goto L_0004;

    /* clang-format on */

    /* clang-format off */
// Double-sided test on T (Part II)
if (_imp_strcmp((_imp_string *)tmp, (_imp_string *)/*?*/&U) <= 0) goto L_0005;
}

/* clang-format on */
L_0004:;
  FAIL = 1;
  _imp_PRINTSTRING(_imp_str_literal("BUG2"));
L_0005:;

//    13        %if Fail=0 %then printstring("TEST OK")

  if (FAIL != 0) goto L_0006;
  _imp_PRINTSTRING(_imp_str_literal("TEST OK"));
L_0006:;

//    14        %ROUTINE CHECK(%STRING(30) P,Q,R)

  void CHECK(_imp_string30 P, _imp_string30 Q, _imp_string30 R) {
    //    15        Fail=1 %and PRINTSTRING("CHECK FAILS") %UNLESS %C


    /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/&P, (_imp_string *)/*?*/&S) != 0) goto L_0007;

    /* clang-format on */

    /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/&Q, (_imp_string *)/*?*/&R) != 0) goto L_0007;

    /* clang-format on */
    {
      // Double-sided test on Q (Part I)
      _imp_string30 *tmp;

      /* clang-format off */
if (_imp_strcmp((_imp_string *)/*?*/&P, (_imp_string *)(tmp=/*?*/&Q)) != 0) goto L_0007;

      /* clang-format on */

      /* clang-format off */
// Double-sided test on Q (Part II)
if (_imp_strcmp((_imp_string *)tmp, (_imp_string *)/*?*/&R) == 0) goto L_0008;
}

  /* clang-format on */
  L_0007:;
    FAIL = 1;
    _imp_PRINTSTRING(_imp_str_literal("CHECK FAILS"));
  L_0008:;

  //    16+          P=S %AND Q=R %AND P=Q=R
  //    17        %END

    return;
  } /* end of CHECK */

  //    18  %ENDOFPROGRAM

  _imp_stop(0);
  return 0;
end_0:;
}