#!/usr/bin/perl

use strict;
use warnings;

open E, "< enums.h" or die "unable to open enums.h";
open O, "> enums.c" or die "unable to open enums.c";

my %enum;
my $c;
while(<E>) {
    if (my ($name) = /enum\s*(\w+)\s*{/) {
	# $name =~ s/^ldap_//;
	$c = $enum{$name} = [];
    }
    else {
	$c->[$2] = $1 if /\b(LDAP_\w+)\s*=\s*(\d+)/;
    }
}

print O <<HEAD;
/*
 *
 * This file is generated by gen_constants.pl
 * Do not edit by hand!
 *
 */

#include "common.h"
#include "enums.h"
#include "util.h"

HEAD

for my $enum (sort keys %enum) {
    my $len = @{$enum{$enum}};
    print O "SV *enum2sv_${enum}[$len];\n";
}

# print O <<DECL for @c;
# SV *${_}_sv;
# DECL

print O <<INIT;

void init_constants(void) {
INIT

for my $enum (sort keys %enum) {
    my $c = $enum{$enum};
    for my $ix (0..$#$c) {
	my $name = $c->[$ix];
	my $value;
	if (defined $name) {
	    $value = $name;
	}
	else {
	    $name = uc "${enum}_$ix";
	    $value = $ix;
	}

	printf O <<C, $ix, $name, length($name), $value;
    enum2sv_${enum}[%d] = make_constant("%s", %d, %s);
C

    }
    print O "\n";
}

print O <<END;
}
END

for my $enum (sort keys %enum) {
    my $len = @{$enum{$enum}};
    print O <<ETS;
SV *${enum}2sv_noinc(I32 ix) {
    SV *sv;
    if (ix >= $len) {
        return newSViv(ix);
    }
    sv = enum2sv_${enum}[ix];
    return sv;
}

ETS
}
