%{
/*-
* Copyright (c)2003, 2006 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
i = rowcol_len;
p = &rowcol[--i];
table_size = p->width;
while (i > 0) {
p = &rowcol[--i];
table_size *= p->width;
}
table = (void *)malloc(table_size * dst_unit_bits / 8);
if (table == NULL) {
perror("malloc");
exit(1);
}
switch (oob_mode) {
case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
val = dst_invalid;
break;
case _CITRUS_MAPPER_STD_OOB_ILSEQ:
val = dst_ilseq;
break;
default:
_DIAGASSERT(0);
}
for (i = 0; i < table_size; i++)
(*putfunc)(table, i, val);
}
static void
setup_map(void)
{
if ((done_flag & DF_SRC_ZONE)==0) {
fprintf(stderr, "SRC_ZONE is mandatory.\n");
exit(1);
}
if ((done_flag & DF_DST_UNIT_BITS)==0) {
fprintf(stderr, "DST_UNIT_BITS is mandatory.\n");
exit(1);
}
if ((done_flag & DF_DST_INVALID) == 0)
dst_invalid = 0xFFFFFFFF;
if ((done_flag & DF_DST_ILSEQ) == 0)
dst_ilseq = 0xFFFFFFFE;
if ((done_flag & DF_OOB_MODE) == 0)
oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
if (done_flag & DF_DST_UNIT_BITS) {
warning("DST_UNIT_BITS is duplicated. ignored this one");
return;
}
switch (val) {
case 8:
putfunc = &put8;
dst_unit_bits = val;
break;
case 16:
putfunc = &put16;
dst_unit_bits = val;
break;
case 32:
putfunc = &put32;
dst_unit_bits = val;
break;
default:
yyerror("Illegal argument for DST_UNIT_BITS");
}
done_flag |= DF_DST_UNIT_BITS;
}
static int
check_src(u_int32_t begin, u_int32_t end)
{
size_t i;
linear_zone_t *p;
u_int32_t m, n;
if (begin > end)
return 1;
if (begin < end) {
m = begin & ~rowcol_mask;
n = end & ~rowcol_mask;
if (m != n)
return 1;
}
for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
i -= rowcol_bits;
m = (begin >> i) & rowcol_mask;
if (m < p->begin || m > p->end)
return 1;
}
if (begin < end) {
n = end & rowcol_mask;
_DIAGASSERT(p > rowcol);
--p;
if (n < p->begin || n > p->end)
return 1;
}
return 0;
}
static void
store(const linear_zone_t *lz, u_int32_t dst, int inc)
{
size_t i, ofs;
linear_zone_t *p;
u_int32_t n;
ofs = 0;
for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
i -= rowcol_bits;
n = ((lz->begin >> i) & rowcol_mask) - p->begin;
ofs = (ofs * p->width) + n;
}
n = lz->width;
while (n-- > 0) {
(*putfunc)(table, ofs++, dst);
if (inc)
dst++;
}
}
static void
set_range(u_int32_t begin, u_int32_t end)
{
linear_zone_t *p;
if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX)
goto bad;
p = &rowcol[rowcol_len++];
if (begin > end)
goto bad;
p->begin = begin, p->end = end;
p->width = end - begin + 1;