#!/bin/sh

# Create a Pascal interface for rts.c. This is no general C to
# Pascal converter.
#
# Copyright (C) 2001-2004 Free Software Foundation, Inc.
#
# Author: Frank Heckenbach <frank@pascal.gnu.de>
#
# This file is part of GNU Pascal.
#
# GNU Pascal 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 2, or (at your option)
# any later version.
#
# GNU Pascal 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 GNU Pascal; see the file COPYING. If not, write to the
# Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# This should work even with a crippled sed ...
dir="`echo "$0" | sed -e 's,\(.\)/*[^/]*$,\1,'`" || exit 1
sed="`"$dir"/../script/find-sed`" || exit 1

cat << EOF
{@internal}
{ The following declarations were created by running `basename $0` }
{@endinternal}

EOF

# @@ The types should be translated automatically as well.
cat<<EOF
type
  PCStrings = ^TCStrings;
  TCStrings = array [0 .. MaxVarSize div SizeOf (CString) - 1] of CString;

  Int64 = Integer attribute (Size = 64);
  UnixTimeType = LongInt;  { This is hard-coded in the compiler. Do not change here. }
  MicroSecondTimeType = LongInt;
  FileSizeType = LongInt;
  SignedSizeType = Integer attribute (Size = BitSizeOf (SizeType));
  TSignalHandler = procedure (Signal: Integer);

  StatFSBuffer = record
    BlockSize, BlocksTotal, BlocksFree: LongestInt;
    FilesTotal, FilesFree: Integer
  end;

  InternalSelectType = record
    Handle: Integer;
    Read, Write, Exception: Boolean
  end;

  PString = ^String;

  { \`Max' so the size of the array is not zero for Count = 0 }
  PPStrings = ^TPStrings;
  TPStrings (Count: Cardinal) = array [1 .. Max (Count, 1)] of PString;

  GlobBuffer = record
    Result: PPStrings;
    Internal1: Pointer;
    Internal2: PCStrings;
    Internal3: Integer
  end;

  {@internal}
  TCPasswordEntry = record
    UserName, RealName, Password, HomeDirectory, Shell: CString;
    UID, GID: Integer
  end;

  PCPasswordEntries = ^TCPasswordEntries;
  TCPasswordEntries = array [0 .. MaxVarSize div SizeOf (TCPasswordEntry) - 1] of TCPasswordEntry;
  {@endinternal}
EOF

NOID='\([^A-Za-z0-9_]\)'
ID='\([A-Za-z0-9_]\+\)'
PAR='\(\([^()]\|([^()]*)\)*\)'

"$sed" -ne '
/^\/\*@internal\*\//s/.*/\
{@internal}/p;

/^\/\*@endinternal\*\//s/.*/{@endinternal}\
/p;

/^\/\*\* */ {
  s//\
{ /;
  :l1; /\([^/]\|[^*]\/\)$/ { N; b l1; }
  s/\(\n\)   /\1 /g;
  s/ *\*\/$/ }/;
  p;
}

/^enum {/ {
  s//const/;
  :l2; /[^};]$/ { N; b l2; }
  s/\(= *\)0x/\1$/g;
  s/\(= *\)0\+\([0-9]\)/\18#\2/g;
  s/ \?<< \?/ shl /g;
  s/ \?>> \?/ shr /g;
  s/,/;/g;
  s/\n};$/;/;
  p
}'"

/GLOBAL/ {
  :l3; /[^)]\$/ { N; b l3; }
  s/^GLOBAL *(\(.*\))\$/\1/;
  s/^GLOBAL_ATTR *(\(.*\), *\([A-Za-z_0-9,]*\))\$/\1 attribute (\2);/;
  s/ UNUSED//g;
  s/$NOID""int$NOID/\1Integer\2/g;
  s/^int$NOID/Integer\1/g;
  s/float/ShortReal/g;
  s/long \+double/LongReal/g;
  s/double/Real/g;
  s/ssize_t/SignedSizeType/g;
  s/size_t/SizeType/g;
  s/void *\* */Pointer /g;
  s/DIR *\* */Pointer /g;
  s/const \+char *\* */CString /g;
  s/char *\* */CString /g;
  s/$ID \+$ID\( *[,()]\)/\2: \1\3/g;
  s/$NOID$ID *\* *$ID/\1var \3: \2/g;
  s/void *(\*$ID) *(\(.*\))/procedure \1 (\2)/
  s/const/protected/g;
  s/attribute (protected)/attribute (const)/g;
  s/,/;/g;
  s/$ID *: *void *( *$PAR *)/procedure #\1 (\2); external name '\1';/g;
  s/$ID *: *$ID *( *$PAR *)/function  #\1 (\3): \2; external name '\1';/g;
  s/#_p_//g;
  s/#//g;
  s/ *( *void *)//g;
  s/external name\(.*[^ ]\) *attribute\(.*\)/attribute\2 external name\1/;
  p;
} " rts.c

cat << EOF
{@internal}
{ End of declarations created by `basename $0` }
{@endinternal}
EOF
