mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-18 03:40:47 -08:00
416 lines
9.8 KiB
C
416 lines
9.8 KiB
C
/* bttest.c: BIT TABLE TEST
|
|
*
|
|
* $Id$
|
|
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
|
|
*/
|
|
|
|
|
|
#include "mpm.h"
|
|
#include "mps.h"
|
|
#include "mpsavm.h"
|
|
#include "testlib.h"
|
|
#include "mpslib.h"
|
|
#include "mpstd.h"
|
|
|
|
#include <stdio.h> /* fflush, fgets, printf, putchar, puts */
|
|
#include <stdlib.h> /* exit, strtol */
|
|
|
|
SRCID(bttest, "$Id$");
|
|
|
|
|
|
static BT bt; /* the BT which we will use */
|
|
static Size btSize; /* the size of the current BT */
|
|
static Arena arena; /* the arena which we use to allocate the BT */
|
|
|
|
|
|
#define MAX_ARGS 3
|
|
|
|
|
|
static Word args[MAX_ARGS];
|
|
static Count argCount;
|
|
|
|
|
|
static Bool argInRange(Index arg)
|
|
{
|
|
if (bt == NULL) {
|
|
printf("no BT\n");
|
|
return FALSE;
|
|
}
|
|
if (args[arg] >= btSize) {
|
|
printf("out of range\n");
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static Bool checkDefaultRange(Index arg)
|
|
{
|
|
if (bt == NULL) {
|
|
printf("no BT\n");
|
|
return FALSE;
|
|
}
|
|
if (argCount == arg+1) {
|
|
printf("range half-specified\n");
|
|
return FALSE;
|
|
}
|
|
if (argCount == arg) { /* use default range */
|
|
args[arg] = 0;
|
|
args[arg+1] = btSize;
|
|
return TRUE;
|
|
}
|
|
if (args[arg] >= args[arg+1]) {
|
|
printf("range ill-formed\n");
|
|
return FALSE;
|
|
}
|
|
if (args[arg+1] > btSize) {
|
|
printf("range too high\n");
|
|
return FALSE;
|
|
}
|
|
return TRUE; /* explicit valid range */
|
|
}
|
|
|
|
|
|
static void quit(void)
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
|
|
static void destroy(void)
|
|
{
|
|
if (bt != NULL) {
|
|
BTDestroy(bt, arena, btSize);
|
|
bt = NULL;
|
|
} else {
|
|
printf("No BT to destroy\n");
|
|
}
|
|
}
|
|
|
|
static void create(void)
|
|
{
|
|
Res res;
|
|
if (args[0] < 1) {
|
|
printf("can't create a BT of size 0\n");
|
|
return;
|
|
}
|
|
if (bt != NULL)
|
|
destroy();
|
|
res = BTCreate(&bt, arena, args[0]);
|
|
if (res == ResOK) {
|
|
btSize = args[0];
|
|
BTResRange(bt, 0, btSize);
|
|
} else {
|
|
printf("BTCreate returned %d\n",res);
|
|
}
|
|
}
|
|
|
|
|
|
static void set(void)
|
|
{
|
|
if (argInRange(0))
|
|
(BTSet)(bt, args[0]);
|
|
}
|
|
|
|
|
|
static void reset(void)
|
|
{
|
|
if (argInRange(0))
|
|
(BTRes)(bt, args[0]);
|
|
}
|
|
|
|
|
|
static void get(void)
|
|
{
|
|
if (argInRange(0)) {
|
|
Bool b = (BTGet)(bt, args[0]);
|
|
puts(b ? "TRUE" : "FALSE");
|
|
}
|
|
}
|
|
|
|
|
|
static void setRange(void)
|
|
{
|
|
if (checkDefaultRange(0))
|
|
BTSetRange(bt, args[0], args[1]);
|
|
}
|
|
|
|
|
|
static void resetRange(void)
|
|
{
|
|
if (checkDefaultRange(0))
|
|
BTResRange(bt, args[0], args[1]);
|
|
}
|
|
|
|
|
|
static void isSetRange(void)
|
|
{
|
|
if (checkDefaultRange(0)) {
|
|
Bool b = BTIsSetRange(bt, args[0], args[1]);
|
|
puts(b ? "TRUE" : "FALSE");
|
|
}
|
|
}
|
|
|
|
|
|
static void isResRange(void)
|
|
{
|
|
if (checkDefaultRange(0)) {
|
|
Bool b = BTIsResRange(bt, args[0], args[1]);
|
|
puts(b ? "TRUE" : "FALSE");
|
|
}
|
|
}
|
|
|
|
|
|
static void findShortResRange(void)
|
|
{
|
|
if (checkDefaultRange(1)) {
|
|
if (args[0] > (args[2] - args[1])) {
|
|
printf("can't fit length in range\n");
|
|
} else {
|
|
Index base, limit;
|
|
Bool b = BTFindShortResRange(&base, &limit, bt,
|
|
args[1], args[2], args[0]);
|
|
if (b)
|
|
printf("%"PRIuLONGEST" - %"PRIuLONGEST"\n",
|
|
(ulongest_t)base, (ulongest_t)limit);
|
|
else
|
|
printf("FALSE\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void findShortResRangeHigh(void)
|
|
{
|
|
if (checkDefaultRange(1)) {
|
|
if (args[0] > (args[2] - args[1])) {
|
|
printf("can't fit length in range\n");
|
|
} else {
|
|
Index base, limit;
|
|
Bool b = BTFindShortResRangeHigh(&base, &limit, bt,
|
|
args[1], args[2], args[0]);
|
|
if (b)
|
|
printf("%"PRIuLONGEST" - %"PRIuLONGEST"\n",
|
|
(ulongest_t)base, (ulongest_t)limit);
|
|
else
|
|
printf("FALSE\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
static void findLongResRange(void)
|
|
{
|
|
if (checkDefaultRange(1)) {
|
|
if (args[0] > (args[2] - args[1])) {
|
|
printf("can't fit length in range\n");
|
|
} else {
|
|
Index base, limit;
|
|
Bool b = BTFindLongResRange(&base, &limit, bt,
|
|
args[1], args[2], args[0]);
|
|
if (b)
|
|
printf("%"PRIuLONGEST" - %"PRIuLONGEST"\n",
|
|
(ulongest_t)base, (ulongest_t)limit);
|
|
else
|
|
printf("FALSE\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void help(void)
|
|
{
|
|
printf("c <s> create a BT of size 's'\n"
|
|
"d destroy the current BT\n"
|
|
"s <i> set the bit index 'i'\n"
|
|
"r <i> reset the bit index 'i'\n"
|
|
"g <i> get the bit index 'i'\n");
|
|
printf("sr [<i> <i>] set the specified range\n"
|
|
"rr [<i> <i>] reset the specified range\n"
|
|
"is [<i> <i>] is the specified range set?\n"
|
|
"ir [<i> <i>] is the specified range reset?\n");
|
|
printf("f <l> [<i> <i>] find a reset range of length 'l'.\n"
|
|
"fh <l> [<i> <i>] find a reset range length 'l', working downwards\n"
|
|
"fl <l> [<i> <i>] find a reset range of length at least 'l'\n"
|
|
"q quit\n"
|
|
"? print this message\n");
|
|
printf("\n"
|
|
"No way of testing BTSize, BTRangesSame, or BTCopyInvertRange.\n");
|
|
}
|
|
|
|
|
|
static struct commandShapeStruct {
|
|
const char *name;
|
|
Count min_args;
|
|
Count max_args;
|
|
void (*fun)(void);
|
|
} commandShapes[] = {
|
|
{"c", 1, 1, create},
|
|
{"d", 0, 0, destroy},
|
|
{"s", 1, 1, set},
|
|
{"r", 1, 1, reset},
|
|
{"g", 1, 1, get},
|
|
{"sr", 0, 2, setRange},
|
|
{"rr", 0, 2, resetRange},
|
|
{"is", 0, 2, isSetRange},
|
|
{"ir", 0, 2, isResRange},
|
|
{"f", 1, 3, findShortResRange},
|
|
{"fh", 1, 3, findShortResRangeHigh},
|
|
{"fl", 1, 3, findLongResRange},
|
|
{"?", 0, 0, help},
|
|
{"q", 0, 0, quit},
|
|
{ NULL, 0, 0, NULL}
|
|
};
|
|
|
|
|
|
typedef struct commandShapeStruct *commandShape;
|
|
|
|
|
|
static void obeyCommand(const char *command)
|
|
{
|
|
commandShape shape = commandShapes;
|
|
while(shape->name != NULL) {
|
|
const char *csp = shape->name;
|
|
const char *p = command;
|
|
while (*csp == *p) {
|
|
csp++;
|
|
p++;
|
|
}
|
|
if ((*csp == 0) && ((*p == '\n') || (*p == ' '))) { /* complete match */
|
|
argCount = 0;
|
|
while ((*p == ' ') && (argCount < shape->max_args)) {
|
|
/* get an argument */
|
|
char *newP;
|
|
long l;
|
|
l = strtol(p, &newP, 0);
|
|
if(l < 0) { /* negative integer */
|
|
printf("negative integer arguments are invalid\n");
|
|
return;
|
|
}
|
|
args[argCount] = (unsigned long)l;
|
|
if (newP == p) { /* strtoul failed */
|
|
printf("couldn't parse an integer argument\n");
|
|
return;
|
|
}
|
|
p = newP;
|
|
++ argCount;
|
|
}
|
|
if (argCount < shape->min_args) {
|
|
printf("insufficient arguments to command\n");
|
|
} else if (*p != '\n') {
|
|
printf("too many arguments to command\n");
|
|
} else { /* do the command */
|
|
shape->fun();
|
|
}
|
|
return;
|
|
} else {
|
|
++ shape; /* try next command */
|
|
}
|
|
}
|
|
printf("command not understood\n");
|
|
help();
|
|
}
|
|
|
|
|
|
static void showBT(void) {
|
|
Index i;
|
|
char c;
|
|
if (bt == NULL)
|
|
return;
|
|
i = 0;
|
|
while((i < btSize) && (i < 50)) {
|
|
if (i % 10 == 0)
|
|
c = (char)(((i / 10) % 10) + '0');
|
|
else
|
|
c = ' ';
|
|
putchar(c);
|
|
++ i;
|
|
}
|
|
putchar('\n');
|
|
i = 0;
|
|
while((i < btSize) && (i < 50)) {
|
|
c = (char)((i % 10) +'0');
|
|
putchar(c);
|
|
++ i;
|
|
}
|
|
putchar('\n');
|
|
i = 0;
|
|
while(i < btSize) {
|
|
if (BTGet(bt,i))
|
|
c = 'O';
|
|
else
|
|
c = '.';
|
|
putchar(c);
|
|
++ i;
|
|
if (i % 50 == 0)
|
|
putchar('\n');
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
|
|
#define testArenaSIZE (((size_t)64)<<20)
|
|
|
|
extern int main(int argc, char *argv[])
|
|
{
|
|
bt = NULL;
|
|
btSize = 0;
|
|
|
|
testlib_init(argc, argv);
|
|
|
|
die(mps_arena_create((mps_arena_t*)&arena, mps_arena_class_vm(),
|
|
testArenaSIZE),
|
|
"mps_arena_create");
|
|
while(1) {
|
|
char input[100];
|
|
printf("bt test> ");
|
|
(void)fflush(stdout);
|
|
if (fgets(input, 100, stdin)) {
|
|
obeyCommand(input);
|
|
showBT();
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* C. COPYRIGHT AND LICENSE
|
|
*
|
|
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
|
* All rights reserved. This is an open source license. Contact
|
|
* Ravenbrook for commercial licensing options.
|
|
*
|
|
* 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.
|
|
*
|
|
* 3. Redistributions in any form must be accompanied by information on how
|
|
* to obtain complete source code for this software and any accompanying
|
|
* software that uses this software. The source code must either be
|
|
* included in the distribution or be available for no more than the cost
|
|
* of distribution plus a nominal fee, and must be freely redistributable
|
|
* under reasonable conditions. For an executable file, complete source
|
|
* code means the source code for all modules it contains. It does not
|
|
* include source code for modules or files that typically accompany the
|
|
* major components of the operating system on which the executable file
|
|
* runs.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDERS AND 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.
|
|
*/
|