#!/usr/bin/perl -w
# Copyright Ian Jackson
# SPDX-License-Identifier: GPL-3.0-or-later
# There is NO WARRANTY.

use strict;
use autodie;
use Carp;

print <<END;
// DO NOT EDIT - this file is autogenerated
//
// Regenerate by copying new pigpio.h and running `make` here
//
// SPDX-License-Identifier: GPL-3.0-or-later
// There is NO WARRANTY.
// Generated from:
//   Makefile  converter   Copyright Ian Jackson
//   pigpio.h              Copyright ...-2022 pigpio contributors
// The "Do not edit" statement above is advice, not a legal restriction!

#![allow(dead_code)]
#![allow(unused_parens)]

//! Constants from C pigpio.h, converted into Rust `const`s.
//!
//! Also `PI_error_code_lookup` for helping print error codes
//! found in `PigpiodError`.
//!
//! But, for error handling: `PigpiodError`, and the `errors`
//! module, provide a better interface.
//!
//! Everything in this module is named `PI_...`.
END

our $def_s = '';
our $ec_lookup = <<END;
/// Provides string descriptions of a 32-bit pigpio error code.
///
/// `val` is the value from `Error:Pi`, or similar.  It can be
/// one of the `PI_*` values representing error codes.
///
/// The returned strings are
///  * The `PI_*` abbreviation name.
///  * The comment from pigpiod.h.
///
/// If the returned value is `None`, the error code was not
/// recognised.  Probably this means that you are using a newer 
/// pigpiod than this library.
///
/// (The error codes are negative.  So you should pass a negative
/// number to this function.  Do not negate the error code to
/// make it positive.)
#[allow(non_snake_case)]
pub fn PI_error_code_lookup(val: i32)
                            -> Option<(&'static str, &'static str)> {
  let r = match val {
END

while (<>) {
    if (m{^/\* *DEF_S +(.*?) *\*/\s*$}) {
	$def_s = $1;
	print;
	next;
    }
    if (m{^/\* *DEF_E.*\*/$}) {
	$def_s = '';
	print;
	next;
    }
    next if m{^/\*D\s*$} .. m{^D\*/\s*$};

    if (m{^/\* .* \*/$}) {
	print;
	next;
    }

    next unless m{^\#define\s+([A-Z0-9_]+)\s+(.*?)\s+$};
    my ($name,$val) = ($1,$2);

    next unless $name =~ m/^PI_/;
    next if $def_s =~ m/defaults/i;
    next if $val =~ m/\"/;

    my $comment = '';
    $val =~ s{ (?://|/\*).*$}{} and $comment = $&;

    if ($def_s =~ m/error codes/i) {
	print "pub const $name: i32 = $val;$comment\n";
	$comment =~ s{^ // *}{} or $comment eq '' or confess "$_ ?";
	next if $comment =~ m/DEPRECATED/;

	next if $name eq 'PI_BAD_PRIM_CHANNEL'; # special bodge

	$comment =~ s{[\\\"]}{\\$&}g;
	$ec_lookup .= "    $name => (\"$name\", \"$comment\"),\n";
	next;
    }

    print "pub const $name: u32 = $val;$comment\n";
}

$ec_lookup .= <<END;
    _ => { return None },
  };
  Some(r)
}
END

print $ec_lookup;
