/* do not edit automatically generated by mc from mcPretty.  */
/* This file is part of GNU Modula-2.

GNU Modula-2 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, or (at your option) any later
version.

GNU Modula-2 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include <stdbool.h>
#   if !defined (PROC_D)
#      define PROC_D
       typedef void (*PROC_t) (void);
       typedef struct { PROC_t proc; } PROC;
#   endif

#   if !defined (TRUE)
#      define TRUE (1==1)
#   endif

#   if !defined (FALSE)
#      define FALSE (1==0)
#   endif

#   include "GStorage.h"
#if defined(__cplusplus)
#   undef NULL
#   define NULL 0
#endif
#define _mcPretty_C

#include "GmcPretty.h"
#   include "GDynamicStrings.h"
#   include "GStorage.h"

typedef struct mcPretty_writeProc_p mcPretty_writeProc;

typedef struct mcPretty_writeLnProc_p mcPretty_writeLnProc;

typedef struct mcPretty__T1_r mcPretty__T1;

typedef mcPretty__T1 *mcPretty_pretty__opaque;

struct mcPretty__T1_r {
                        mcPretty_writeProc write_;
                        mcPretty_writeLnProc writeln;
                        bool needsSpace;
                        bool needsIndent;
                        unsigned int seekPos;
                        unsigned int curLine;
                        unsigned int curPos;
                        unsigned int indent;
                        mcPretty_pretty__opaque stacked;
                      };


/*
   initPretty - initialise a pretty print data structure.
*/

extern "C" mcPretty_pretty mcPretty_initPretty (mcPretty_writeProc w, mcPretty_writeLnProc l);

/*
   dupPretty - duplicate a pretty print data structure.
*/

extern "C" mcPretty_pretty mcPretty_dupPretty (mcPretty_pretty p);

/*
   killPretty - destroy a pretty print data structure.
                Post condition:  p is assigned to NIL.
*/

extern "C" void mcPretty_killPretty (mcPretty_pretty *p);

/*
   pushPretty - duplicate, p.  Push, p, and return the duplicate.
*/

extern "C" mcPretty_pretty mcPretty_pushPretty (mcPretty_pretty p);

/*
   popPretty - pops the pretty object from the stack.
*/

extern "C" mcPretty_pretty mcPretty_popPretty (mcPretty_pretty p);

/*
   getindent - returns the current indent value.
*/

extern "C" unsigned int mcPretty_getindent (mcPretty_pretty p);

/*
   setindent - sets the current indent to, n.
*/

extern "C" void mcPretty_setindent (mcPretty_pretty p, unsigned int n);

/*
   getcurpos - returns the current cursor position.
*/

extern "C" unsigned int mcPretty_getcurpos (mcPretty_pretty s);

/*
   getseekpos - returns the seek position.
*/

extern "C" unsigned int mcPretty_getseekpos (mcPretty_pretty s);

/*
   getcurline - returns the current line number.
*/

extern "C" unsigned int mcPretty_getcurline (mcPretty_pretty s);
extern "C" void mcPretty_setNeedSpace (mcPretty_pretty s);

/*
   noSpace - unset needsSpace.
*/

extern "C" void mcPretty_noSpace (mcPretty_pretty s);

/*
   print - print a string using, p.
*/

extern "C" void mcPretty_print (mcPretty_pretty p, const char *a_, unsigned int _a_high);

/*
   prints - print a string using, p.
*/

extern "C" void mcPretty_prints (mcPretty_pretty p, DynamicStrings_String s);

/*
   raw - print out string, s, without any translation of
         escape sequences.
*/

extern "C" void mcPretty_raw (mcPretty_pretty p, DynamicStrings_String s);

/*
   flushSpace -
*/

static void flushSpace (mcPretty_pretty__opaque p);

/*
   flushIndent -
*/

static void flushIndent (mcPretty_pretty__opaque p);


/*
   flushSpace -
*/

static void flushSpace (mcPretty_pretty__opaque p)
{
  if (p->needsSpace)
    {
      (*p->write_.proc) (' ');
      p->needsSpace = false;
      p->curPos += 1;
      p->seekPos += 1;
    }
}


/*
   flushIndent -
*/

static void flushIndent (mcPretty_pretty__opaque p)
{
  unsigned int i;

  flushSpace (p);
  if (p->needsIndent)
    {
      while (p->curPos < p->indent)
        {
          (*p->write_.proc) (' ');
          p->curPos += 1;
          p->seekPos += 1;
        }
      p->needsIndent = false;
    }
}


/*
   initPretty - initialise a pretty print data structure.
*/

extern "C" mcPretty_pretty mcPretty_initPretty (mcPretty_writeProc w, mcPretty_writeLnProc l)
{
  mcPretty_pretty__opaque p;

  Storage_ALLOCATE ((void **) &p, sizeof (mcPretty__T1));
  p->write_ = w;
  p->writeln = l;
  p->needsSpace = false;
  p->needsIndent = false;
  p->curPos = 0;
  p->curLine = 0;
  p->seekPos = 0;
  p->indent = 0;
  p->stacked = static_cast<mcPretty_pretty__opaque> (NULL);
  return static_cast<mcPretty_pretty> (p);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupPretty - duplicate a pretty print data structure.
*/

extern "C" mcPretty_pretty mcPretty_dupPretty (mcPretty_pretty p)
{
  mcPretty_pretty__opaque q;

  Storage_ALLOCATE ((void **) &q, sizeof (mcPretty__T1));
  (*q) = (*static_cast<mcPretty_pretty__opaque> (p));
  return static_cast<mcPretty_pretty> (q);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   killPretty - destroy a pretty print data structure.
                Post condition:  p is assigned to NIL.
*/

extern "C" void mcPretty_killPretty (mcPretty_pretty *p)
{
  (*p) = static_cast<mcPretty_pretty> (NULL);
  return;
  Storage_DEALLOCATE ((void **) &(*p), sizeof (mcPretty__T1));
  (*p) = static_cast<mcPretty_pretty> (NULL);
}


/*
   pushPretty - duplicate, p.  Push, p, and return the duplicate.
*/

extern "C" mcPretty_pretty mcPretty_pushPretty (mcPretty_pretty p)
{
  mcPretty_pretty__opaque q;

  q = static_cast<mcPretty_pretty__opaque> (mcPretty_dupPretty (p));
  q->stacked = static_cast<mcPretty_pretty__opaque> (p);
  return static_cast<mcPretty_pretty> (q);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   popPretty - pops the pretty object from the stack.
*/

extern "C" mcPretty_pretty mcPretty_popPretty (mcPretty_pretty p)
{
  mcPretty_pretty__opaque q;

  q = static_cast<mcPretty_pretty__opaque> (p)->stacked;
  q->needsIndent = static_cast<mcPretty_pretty__opaque> (p)->needsIndent;
  q->needsSpace = static_cast<mcPretty_pretty__opaque> (p)->needsSpace;
  q->curPos = static_cast<mcPretty_pretty__opaque> (p)->curPos;
  q->seekPos = static_cast<mcPretty_pretty__opaque> (p)->seekPos;
  q->curLine = static_cast<mcPretty_pretty__opaque> (p)->curLine;
  mcPretty_killPretty (&p);
  return static_cast<mcPretty_pretty> (q);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getindent - returns the current indent value.
*/

extern "C" unsigned int mcPretty_getindent (mcPretty_pretty p)
{
  return static_cast<mcPretty_pretty__opaque> (p)->indent;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setindent - sets the current indent to, n.
*/

extern "C" void mcPretty_setindent (mcPretty_pretty p, unsigned int n)
{
  static_cast<mcPretty_pretty__opaque> (p)->indent = n;
}


/*
   getcurpos - returns the current cursor position.
*/

extern "C" unsigned int mcPretty_getcurpos (mcPretty_pretty s)
{
  if (static_cast<mcPretty_pretty__opaque> (s)->needsSpace)
    {
      return static_cast<mcPretty_pretty__opaque> (s)->curPos+1;
    }
  else
    {
      return static_cast<mcPretty_pretty__opaque> (s)->curPos;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getseekpos - returns the seek position.
*/

extern "C" unsigned int mcPretty_getseekpos (mcPretty_pretty s)
{
  return static_cast<mcPretty_pretty__opaque> (s)->seekPos;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getcurline - returns the current line number.
*/

extern "C" unsigned int mcPretty_getcurline (mcPretty_pretty s)
{
  return static_cast<mcPretty_pretty__opaque> (s)->curLine;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}

extern "C" void mcPretty_setNeedSpace (mcPretty_pretty s)
{
  /*
   setneedSpace - sets needSpace flag to TRUE.
  */
  static_cast<mcPretty_pretty__opaque> (s)->needsSpace = true;
}


/*
   noSpace - unset needsSpace.
*/

extern "C" void mcPretty_noSpace (mcPretty_pretty s)
{
  static_cast<mcPretty_pretty__opaque> (s)->needsSpace = false;
}


/*
   print - print a string using, p.
*/

extern "C" void mcPretty_print (mcPretty_pretty p, const char *a_, unsigned int _a_high)
{
  DynamicStrings_String s;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  s = DynamicStrings_InitString ((const char *) a, _a_high);
  mcPretty_prints (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   prints - print a string using, p.
*/

extern "C" void mcPretty_prints (mcPretty_pretty p, DynamicStrings_String s)
{
  unsigned int l;
  unsigned int i;

  l = DynamicStrings_Length (s);
  i = 0;
  flushSpace (static_cast<mcPretty_pretty__opaque> (p));
  while (i < l)
    {
      if ((((i+2) <= l) && ((DynamicStrings_char (s, static_cast<int> (i))) == '\\')) && ((DynamicStrings_char (s, static_cast<int> (i+1))) == 'n'))
        {
          static_cast<mcPretty_pretty__opaque> (p)->needsIndent = true;
          static_cast<mcPretty_pretty__opaque> (p)->needsSpace = false;
          static_cast<mcPretty_pretty__opaque> (p)->curPos = 0;
          (*static_cast<mcPretty_pretty__opaque> (p)->writeln.proc) ();
          static_cast<mcPretty_pretty__opaque> (p)->seekPos += 1;
          static_cast<mcPretty_pretty__opaque> (p)->curLine += 1;
          i += 1;
        }
      else
        {
          flushIndent (static_cast<mcPretty_pretty__opaque> (p));
          (*static_cast<mcPretty_pretty__opaque> (p)->write_.proc) (DynamicStrings_char (s, static_cast<int> (i)));
          static_cast<mcPretty_pretty__opaque> (p)->curPos += 1;
          static_cast<mcPretty_pretty__opaque> (p)->seekPos += 1;
        }
      i += 1;
    }
}


/*
   raw - print out string, s, without any translation of
         escape sequences.
*/

extern "C" void mcPretty_raw (mcPretty_pretty p, DynamicStrings_String s)
{
  unsigned int l;
  unsigned int i;

  l = DynamicStrings_Length (s);
  i = 0;
  flushSpace (static_cast<mcPretty_pretty__opaque> (p));
  flushIndent (static_cast<mcPretty_pretty__opaque> (p));
  while (i < l)
    {
      (*static_cast<mcPretty_pretty__opaque> (p)->write_.proc) (DynamicStrings_char (s, static_cast<int> (i)));
      static_cast<mcPretty_pretty__opaque> (p)->curPos += 1;
      static_cast<mcPretty_pretty__opaque> (p)->seekPos += 1;
      i += 1;
    }
}

extern "C" void _M2_mcPretty_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
}

extern "C" void _M2_mcPretty_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
}