#!/bin/bash
# SPDX-License-Identifier: GPL-3+
# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>

set -e

: "${CC=gcc}"

if [ "$#" -ne 1 ]; then
    echo "Usage: configure <output directory for platform.h>"
fi

check_io_function()
{
    DIR="$1"
    FOO="$2"
    SNIPPET="$3"
    cat > $"$DIR"/"$FOO"test.c <<EOF
#include <sys/io.h>
int main(int argc, char **argv) {
	$SNIPPET;
	return 0;
}
EOF
    if $CC -o "$DIR"/"$FOO"test "$DIR"/"$FOO"test.c >/dev/null 2>&1
    then
	echo "#define have_$FOO" >> platform.h
    fi
    rm -f "$DIR"/"$FOO"test.c "$DIR"/"$FOO"test
}

functions=( "outb" "outw" "outl" "outb_p" "outw_p" "outl_p" "outsb" "outsw" "outsl" "inb" "inw" "inl" "inb_p" "inw_p" "inl_p" "insb" "insw" "insl" "ioperm" "iopl" )
snippets=( \
  "unsigned char data; unsigned short int port; outb(data,port);" \
  "unsigned short int data; unsigned short int port; outw(data,port);" \
  "unsigned int data; unsigned short int port; outl(data,port);" \
  "unsigned char data; unsigned short int port; outb_p(data,port);" \
  "unsigned short int data; unsigned short int port; outw_p(data,port);" \
  "unsigned int data; unsigned short int port; outl_p(data,port);" \
  "unsigned short int port; void *string; unsigned long int count; outsb(port,string,count);" \
  "unsigned short int port; void *string; unsigned long int count; outsw(port,string,count);" \
  "unsigned short int port; void *string; unsigned long int count; outsl(port,string,count);" \
  "unsigned short int port; unsigned char data; data = inb(port);" \
  "unsigned short int port; unsigned short int data; data = inw(port);" \
  "unsigned short int port; unsigned int data; data = inl(port);" \
  "unsigned short int port; unsigned char data; data = inb_p(port);" \
  "unsigned short int port; unsigned short int data; data = inw_p(port);" \
  "unsigned short int port; unsigned int data; data = inl_p(port);" \
  "unsigned short int port; void *string; unsigned long int count; insb(port,string,count);" \
  "unsigned short int port; void *string; unsigned long int count; insw(port,string,count);" \
  "unsigned short int port; void *string; unsigned long int count; insl(port,string,count);" \
  "unsigned short int port; void *string; unsigned long int count; unsigned long int from; unsigned long int extent; int enable; ioperm(from,extent,enable);" \
  "int level; iopl(level);" \
)

for i in "${!functions[@]}"
do
    check_io_function "$1" "${functions[$i]}" "${snippets[$i]}"
done
