10. Examples
This chapter contains example CEETRON SAM programs. The source code for all examples resides in CeetronSAM/src/sam/base/exam.
10.1. Example 1, Demonstration of Object Collections
This example provides some simple illustrations of the use the HashTable, VHashTable, IntVHash, List, Stack and Dictionary collection modules. In general the collection objects store pointers (CEETRON SAM type Vobject). In CEETRON SAM these pointers are the pointers to other CEETRON SAM objects. The type Vobject* is the C language type void*, so that any void* type may be stored in collection objects. In this example pointers to strings as well as simple integers cast to pointer type are used for illustration.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
static void
test_hashtable(void);
static void
test_vhashtable(void);
static void
test_intvhash(void);
static void
test_list(void);
static void
test_stack(void);
static void
test_dictionary(void);
static void
print_integer(Vint* n);
/*----------------------------------------------------------------------
Test and demonstrate collection objects
----------------------------------------------------------------------*/
int
main()
{
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
test_hashtable();
test_vhashtable();
test_intvhash();
test_list();
test_stack();
test_dictionary();
return 0;
}
/*----------------------------------------------------------------------
HashTable
----------------------------------------------------------------------*/
static void
test_hashtable(void)
{
Vint i;
vsy_HashTable* htab;
Vint num, count, key, keys[10];
Vchar* str;
printf("\nHashTable test\n");
/* instance HashTable object */
htab = vsy_HashTableBegin();
/* set initial allocation to two objects */
vsy_HashTableDef(htab, 2);
/* inquire and count */
vsy_HashTableInq(htab, &num);
vsy_HashTableCount(htab, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some simple "string" objects */
vsy_HashTableInsert(htab, 3, (Vobject*)"three");
vsy_HashTableInsert(htab, 0, (Vobject*)"zero");
vsy_HashTableInsert(htab, 2, (Vobject*)"two");
vsy_HashTableInsert(htab, 1, (Vobject*)"one");
/* count and find maximum key */
vsy_HashTableCount(htab, &count);
vsy_HashTableMaxKey(htab, &key);
printf("count= %d, max key= %d\n", count, key);
/* get all keys */
vsy_HashTableAllKeys(htab, keys);
for (i = 0; i < count; i++) {
printf("key = %d\n", keys[i]);
}
/* remove a couple */
vsy_HashTableRemove(htab, 2);
vsy_HashTableRemove(htab, 0);
/* add some */
vsy_HashTableInsert(htab, 4, (Vobject*)"four");
vsy_HashTableInsert(htab, 15, (Vobject*)"fifteen");
/* now inquire and count */
vsy_HashTableInq(htab, &num);
vsy_HashTableCount(htab, &count);
printf("num = %d, count = %d\n", num, count);
/* InitIter,NextIter traversal */
vsy_HashTableInitIter(htab);
while (vsy_HashTableNextIter(htab, &key, (Vobject**)&str), str != NULL) {
printf("key = %d, string = %s\n", key, str);
}
/* delete object */
vsy_HashTableEnd(htab);
}
/*----------------------------------------------------------------------
VHashTable
----------------------------------------------------------------------*/
static void
test_vhashtable(void)
{
vsy_VHashTable* htab;
Vint size, num, count, key[3];
Vchar* str;
printf("\nVHashTable test\n");
/* instance HashTable object */
htab = vsy_VHashTableBegin();
/* set initial allocation to three keys and two objects */
vsy_VHashTableDef(htab, 3, 2);
/* inquire and count */
vsy_VHashTableInq(htab, &size, &num);
vsy_VHashTableCount(htab, &count);
printf("size = %d, num = %d, count = %d\n", size, num, count);
/* insert some simple "string" objects */
key[0] = 1;
key[1] = 2;
key[2] = 3;
vsy_VHashTableInsert(htab, key, (Vobject*)"three");
key[2] = 0;
vsy_VHashTableInsert(htab, key, (Vobject*)"zero");
key[2] = 2;
vsy_VHashTableInsert(htab, key, (Vobject*)"two");
key[2] = 1;
vsy_VHashTableInsert(htab, key, (Vobject*)"one");
/* count */
vsy_VHashTableCount(htab, &count);
printf("count= %d\n", count);
/* remove a couple */
key[2] = 2;
vsy_VHashTableRemove(htab, key);
key[2] = 0;
vsy_VHashTableRemove(htab, key);
/* add some */
key[2] = 4;
vsy_VHashTableInsert(htab, key, (Vobject*)"four");
key[2] = 15;
vsy_VHashTableInsert(htab, key, (Vobject*)"fifteen");
/* now inquire and count */
vsy_VHashTableInq(htab, &size, &num);
vsy_VHashTableCount(htab, &count);
printf("size = %d, num = %d, count = %d\n", size, num, count);
/* InitIter,NextIter traversal */
vsy_VHashTableInitIter(htab);
while (vsy_VHashTableNextIter(htab, key, (Vobject**)&str), str != NULL) {
printf("key = %d %d %d, string = %s\n", key[0], key[1], key[2], str);
}
/* delete object */
vsy_VHashTableEnd(htab);
}
/*----------------------------------------------------------------------
IntVHash
----------------------------------------------------------------------*/
static void
test_intvhash(void)
{
vsy_IntVHash* ivhash;
Vint size, num, count, key[3], ival;
printf("\nIntVHash test\n");
/* instance IntVHash object */
ivhash = vsy_IntVHashBegin();
/* set initial allocation to three keys and two objects */
vsy_IntVHashDef(ivhash, 3, 2);
/* inquire and count */
vsy_IntVHashInq(ivhash, &size, &num);
vsy_IntVHashCount(ivhash, &count);
printf("size = %d, num = %d, count = %d\n", size, num, count);
/* insert some simple "string" objects */
key[0] = 1;
key[1] = 2;
key[2] = 3;
vsy_IntVHashInsert(ivhash, key, 3);
key[2] = 2;
vsy_IntVHashInsert(ivhash, key, 2);
key[2] = 1;
vsy_IntVHashInsert(ivhash, key, 1);
/* count */
vsy_IntVHashCount(ivhash, &count);
printf("count= %d\n", count);
/* remove a couple */
key[2] = 2;
vsy_IntVHashRemove(ivhash, key);
key[2] = 0;
vsy_IntVHashRemove(ivhash, key);
/* add some */
key[2] = 4;
vsy_IntVHashInsert(ivhash, key, 4);
key[2] = 15;
vsy_IntVHashInsert(ivhash, key, 15);
/* now inquire and count */
vsy_IntVHashInq(ivhash, &size, &num);
vsy_IntVHashCount(ivhash, &count);
printf("size = %d, num = %d, count = %d\n", size, num, count);
/* InitIter,NextIter traversal */
vsy_IntVHashInitIter(ivhash);
while (vsy_IntVHashNextIter(ivhash, key, &ival), ival != 0) {
printf("key = %d %d %d, ival = %d\n", key[0], key[1], key[2], ival);
}
/* delete object */
vsy_IntVHashEnd(ivhash);
}
/*----------------------------------------------------------------------
List
----------------------------------------------------------------------*/
static void
test_list(void)
{
vsy_List* list;
Vint values[3] = {1, 10, 20};
printf("\nList test\n");
/* instance object */
list = vsy_ListBegin();
/* insert some numbers */
vsy_ListInsert(list, values[0], (Vobject*)&values[0]);
vsy_ListInsert(list, values[1], (Vobject*)&values[1]);
vsy_ListInsert(list, values[2], (Vobject*)&values[2]);
/* ForEach facility to list contents */
vsy_ListForEach(list, (Vfunc1*)print_integer);
printf("\n");
/* remove an object and list contents again */
vsy_ListRemove(list, values[1]);
vsy_ListForEach(list, (Vfunc1*)print_integer);
printf("\n");
/* delete object */
vsy_ListEnd(list);
}
/*----------------------------------------------------------------------
Stack
----------------------------------------------------------------------*/
static void
test_stack(void)
{
vsy_Stack* stack;
Vint values[3] = {1, 10, 20};
printf("\nStack test\n");
/* instance object */
stack = vsy_StackBegin();
/* push some numbers */
vsy_StackPush(stack, (Vobject*)&values[0]);
vsy_StackPush(stack, (Vobject*)&values[1]);
vsy_StackPush(stack, (Vobject*)&values[2]);
/* ForEach facility to list contents */
vsy_StackForEach(stack, (Vfunc1*)print_integer);
printf("\n");
/* pop an object off and list contents again*/
vsy_StackPop(stack);
vsy_StackForEach(stack, (Vfunc1*)print_integer);
printf("\n");
/* delete object */
vsy_StackEnd(stack);
}
/*----------------------------------------------------------------------
Dictionary
----------------------------------------------------------------------*/
static void
test_dictionary(void)
{
vsy_Dictionary* dict;
Vint num, count;
Vchar* name;
Vchar* str;
printf("\nDictionary test\n");
/* instance Dictionary object */
dict = vsy_DictionaryBegin();
/* set initial allocation to two objects */
vsy_DictionaryDef(dict, 2);
/* inquire and count */
vsy_DictionaryInq(dict, &num);
vsy_DictionaryCount(dict, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some simple "string" objects */
vsy_DictionaryInsert(dict, "Three", (Vobject*)"three");
vsy_DictionaryInsert(dict, "Zero", (Vobject*)"zero");
vsy_DictionaryInsert(dict, "Two", (Vobject*)"two");
vsy_DictionaryInsert(dict, "One", (Vobject*)"one");
/* remove a couple */
vsy_DictionaryRemove(dict, "Two");
vsy_DictionaryRemove(dict, "Zero");
/* add some */
vsy_DictionaryInsert(dict, "Four", (Vobject*)"four");
vsy_DictionaryInsert(dict, "Fifteen", (Vobject*)"fifteen");
/* now inquire and count */
vsy_DictionaryInq(dict, &num);
vsy_DictionaryCount(dict, &count);
printf("num = %d, count = %d\n", num, count);
/* InitIter,NextIter traversal */
vsy_DictionaryInitIter(dict);
while (vsy_DictionaryNextIter(dict, &name, (Vobject**)&str), str != NULL) {
printf("name = %s, string = %s\n", name, str);
}
/* reinsert name and lookup */
vsy_DictionaryInsert(dict, "Three", (Vobject*)"3");
vsy_DictionaryLookup(dict, "Three", (Vobject**)&str);
printf("name = %s, string = %s\n", "Three", str);
/* delete object */
vsy_DictionaryEnd(dict);
}
/*----------------------------------------------------------------------
print utility
----------------------------------------------------------------------*/
static void
print_integer(Vint* n)
{
printf("%d ", *n);
}
10.2. Example 2, Demonstration of Numeric Type Collections
This example illustrates the use of the BitVec, DblVec, IntVec, IntDict, IntHash and IntQue numeric type collection modules. These modules are designed to store individual bit vales, double precision value, and integer values. A simple indexed vector representation is available for bits, doubles and integers. Hashtable, queue and dictionary storage are available for integers.
Three BitVec objects are instanced and various operations are performed
on the bit vectors. The results of these operations are printed.
Initially a bit vector X is instanced and the bits are set to one
for indices 1,3 and 5 using vsy_BitVecSet()
..
Any unreferenced intermediate bit indices are
initially set to zero.
Two additional bit vectors, Y and Z are instanced and various Boolean
operations are performed. Note that by default the lowest bit index
is zero. The function vsy_BitVecSetParami()
is used to exclude the
zero bit index in bit vector Y.
The DblVec and IntVec modules are identical except for the numeric data types which they store. Note that any unset value will be returned as a zero. The IntDict and IntHash modules are dictionary and hashtable storage for integer values which are very similar to the Dictionary and HashTable storage for objects. The IntQue module is a first-in, first-out access mechanism for integers.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
static void
test_bitvec(void);
static void
test_dblvec(void);
static void
test_intvec(void);
static void
test_inthash(void);
static void
test_intdict(void);
static void
test_intstack(void);
static void
test_intque(void);
static void
print_bitvector(vsy_BitVec* bitvec, Vchar* stg);
/*----------------------------------------------------------------------
Demonstration of Numeric Type Collections
----------------------------------------------------------------------*/
int
main()
{
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
test_bitvec();
test_dblvec();
test_intvec();
test_intdict();
test_intstack();
test_inthash();
test_intque();
return 0;
}
/*----------------------------------------------------------------------
BitVec
----------------------------------------------------------------------*/
static void
test_bitvec(void)
{
vsy_BitVec *bitvecx, *bitvecy, *bitvecz;
Vint index, maxindex, flag, count;
printf("\nBitVec test\n");
/* instance object */
bitvecx = vsy_BitVecBegin();
/* set some indices */
vsy_BitVecSet(bitvecx, 1, 1);
vsy_BitVecSet(bitvecx, 3, 1);
vsy_BitVecSet(bitvecx, 5, 1);
/* get max index referenced */
vsy_BitVecInq(bitvecx, &maxindex);
printf("maximum index = %d\n", maxindex);
/* test get */
for (index = 0; index <= maxindex; index++) {
vsy_BitVecGet(bitvecx, index, &flag);
printf("index %d = %d\n", index, flag);
}
/* count flags */
vsy_BitVecCount(bitvecx, &count);
printf("number of flags = %d\n", count);
/* test iteration with print */
print_bitvector(bitvecx, (Vchar*)"X");
/* boolean operations */
bitvecy = vsy_BitVecBegin();
bitvecz = vsy_BitVecBegin();
/* copy the bit vector to bit vector x */
vsy_BitVecBoolean(bitvecy, BITVEC_SET, bitvecx);
vsy_BitVecSet(bitvecy, 5, 0);
print_bitvector(bitvecy, (Vchar*)"Y is a copy of X with index 5 set to zero");
vsy_BitVecBoolean(bitvecz, BITVEC_SET, bitvecy);
vsy_BitVecBoolean(bitvecz, BITVEC_AND, bitvecx);
print_bitvector(bitvecz, (Vchar*)"Z is X AND Y");
vsy_BitVecBoolean(bitvecz, BITVEC_SET, bitvecy);
vsy_BitVecBoolean(bitvecz, BITVEC_OR, bitvecx);
print_bitvector(bitvecz, (Vchar*)"Z is X OR Y");
vsy_BitVecBoolean(bitvecz, BITVEC_SET, bitvecy);
vsy_BitVecBoolean(bitvecz, BITVEC_XOR, bitvecx);
print_bitvector(bitvecz, (Vchar*)"Z is X XOR Y");
vsy_BitVecComplement(bitvecy);
print_bitvector(bitvecy, (Vchar*)"Y is NOT Y");
vsy_BitVecSetParami(bitvecy, VSY_INCLUDEZERO, SYS_OFF);
print_bitvector(bitvecy, (Vchar*)"exclude index zero from Y");
/* delete object */
vsy_BitVecEnd(bitvecx);
vsy_BitVecEnd(bitvecy);
vsy_BitVecEnd(bitvecz);
}
/*----------------------------------------------------------------------
print utility
----------------------------------------------------------------------*/
static void
print_bitvector(vsy_BitVec* bitvec, Vchar* stg)
{
Vint index;
/* print a title */
printf("\n%s\n", stg);
/* print indices of all one bits */
vsy_BitVecInitIter(bitvec);
while (vsy_BitVecNextIter(bitvec, &index), index >= 0) {
printf("index = %d\n", index);
}
}
/*----------------------------------------------------------------------
DblVec
----------------------------------------------------------------------*/
static void
test_dblvec(void)
{
vsy_DblVec* dblvec;
Vint num, count;
Vint index;
Vdouble val, *ptr;
printf("\nDblVec test\n");
/* instance DblVec object */
dblvec = vsy_DblVecBegin();
/* set initial allocation to two integers */
vsy_DblVecDef(dblvec, 2);
/* inquire and count */
vsy_DblVecInq(dblvec, &num);
vsy_DblVecCount(dblvec, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some integers */
vsy_DblVecSet(dblvec, 5, 105.);
vsy_DblVecSet(dblvec, 3, 103.);
vsy_DblVecSet(dblvec, 7, 107.);
vsy_DblVecSet(dblvec, 2, 102.);
vsy_DblVecSet(dblvec, 1, 101.);
/* get a set value */
vsy_DblVecGet(dblvec, 5, &val);
printf("value = %f\n", val);
/* get an unset value */
vsy_DblVecGet(dblvec, 6, &val);
printf("value = %f\n", val);
/* get pointer, index starts from 1 */
vsy_DblVecGetPtr(dblvec, &ptr);
vsy_DblVecInq(dblvec, &num);
for (index = 1; index <= num; index++) {
printf("index= %d, value= %f\n", index, ptr[index - 1]);
}
/* InitIter,NextIter traversal */
vsy_DblVecInitIter(dblvec);
while (vsy_DblVecNextIter(dblvec, &index, &val), index != -1) {
printf("index = %d, value = %f\n", index, val);
}
/* clear */
vsy_DblVecClear(dblvec);
/* inquire and count */
vsy_DblVecInq(dblvec, &num);
vsy_DblVecCount(dblvec, &count);
printf("num = %d, count = %d\n", num, count);
/* delete object */
vsy_DblVecEnd(dblvec);
}
/*----------------------------------------------------------------------
IntVec
----------------------------------------------------------------------*/
static void
test_intvec(void)
{
vsy_IntVec* intvec;
Vint num, count;
Vint index;
Vint val, *ptr;
printf("\nIntVec test\n");
/* instance IntVec object */
intvec = vsy_IntVecBegin();
/* set initial allocation to two integers */
vsy_IntVecDef(intvec, 2);
/* inquire and count */
vsy_IntVecInq(intvec, &num);
vsy_IntVecCount(intvec, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some integers */
vsy_IntVecSet(intvec, 5, 105);
vsy_IntVecSet(intvec, 3, 103);
vsy_IntVecSet(intvec, 7, 107);
vsy_IntVecSet(intvec, 2, 102);
vsy_IntVecSet(intvec, 1, 101);
/* get a set value */
vsy_IntVecGet(intvec, 5, &val);
printf("value = %d\n", val);
/* get an unset value */
vsy_IntVecGet(intvec, 6, &val);
printf("value = %d\n", val);
/* get pointer, index starts from 1 */
vsy_IntVecGetPtr(intvec, &ptr);
vsy_IntVecInq(intvec, &num);
for (index = 1; index <= num; index++) {
printf("index= %d, value= %d\n", index, ptr[index - 1]);
}
/* InitIter,NextIter traversal */
vsy_IntVecInitIter(intvec);
while (vsy_IntVecNextIter(intvec, &index, &val), index != -1) {
printf("index = %d, value = %d\n", index, val);
}
/* clear */
vsy_IntVecClear(intvec);
/* inquire and count */
vsy_IntVecInq(intvec, &num);
vsy_IntVecCount(intvec, &count);
printf("num = %d, count = %d\n", num, count);
/* delete object */
vsy_IntVecEnd(intvec);
}
/*----------------------------------------------------------------------
IntDict
----------------------------------------------------------------------*/
static void
test_intdict(void)
{
vsy_IntDict* intdict;
Vint num, count;
Vchar* name;
Vint val;
printf("\nIntDict test\n");
/* instance IntDict object */
intdict = vsy_IntDictBegin();
/* set initial allocation to two integers */
vsy_IntDictDef(intdict, 2);
/* inquire and count */
vsy_IntDictInq(intdict, &num);
vsy_IntDictCount(intdict, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some integers */
vsy_IntDictInsert(intdict, "105", 105);
vsy_IntDictInsert(intdict, "103", 103);
vsy_IntDictInsert(intdict, "100", 100);
vsy_IntDictInsert(intdict, "102", 102);
vsy_IntDictInsert(intdict, "101", 101);
/* lookup a legal value */
vsy_IntDictLookup(intdict, "101", &val);
printf("value = %d\n", val);
/* lookup a illegal value */
vsy_IntDictLookup(intdict, "104", &val);
printf("value = %d\n", val);
/* now inquire and count */
vsy_IntDictInq(intdict, &num);
vsy_IntDictCount(intdict, &count);
printf("num = %d, count = %d\n", num, count);
/* InitIter,NextIter traversal */
vsy_IntDictInitIter(intdict);
while (vsy_IntDictNextIter(intdict, &name, &val), name != NULL) {
printf("name = %s, value = %d\n", name, val);
}
/* clear */
vsy_IntDictClear(intdict);
/* inquire and count */
vsy_IntDictInq(intdict, &num);
vsy_IntDictCount(intdict, &count);
printf("num = %d, count = %d\n", num, count);
/* delete object */
vsy_IntDictEnd(intdict);
}
/*----------------------------------------------------------------------
IntStack
----------------------------------------------------------------------*/
static void
test_intstack(void)
{
vsy_IntStack* intstack;
Vint id, num;
printf("\nIntStack test\n");
/* instance IntStack object */
intstack = vsy_IntStackBegin();
/* set initial allocation to 20 integers */
vsy_IntStackDef(intstack, 20);
/* push some integers */
vsy_IntStackPush(intstack, 105);
vsy_IntStackPush(intstack, 103);
vsy_IntStackPush(intstack, 100);
vsy_IntStackPush(intstack, 102);
vsy_IntStackPush(intstack, 101);
vsy_IntStackPrint(intstack);
vsy_IntStackPush(intstack, 101);
vsy_IntStackPrint(intstack);
/* pop */
vsy_IntStackPop(intstack, &id);
printf("id = %d\n", id);
vsy_IntStackPrint(intstack);
/* clear */
vsy_IntStackClear(intstack);
vsy_IntStackPrint(intstack);
vsy_IntStackCount(intstack, &num);
printf("num = %d\n", num);
/* delete object */
vsy_IntStackEnd(intstack);
}
/*----------------------------------------------------------------------
IntHash
----------------------------------------------------------------------*/
static void
test_inthash(void)
{
vsy_IntHash* inthash;
Vint num, count, key;
Vint val;
printf("\nIntHash test\n");
/* instance IntHash object */
inthash = vsy_IntHashBegin();
/* set initial allocation to two integers */
vsy_IntHashDef(inthash, 2);
/* inquire and count */
vsy_IntHashInq(inthash, &num);
vsy_IntHashCount(inthash, &count);
printf("num = %d, count = %d\n", num, count);
/* insert some integers */
vsy_IntHashInsert(inthash, 5, 105);
vsy_IntHashInsert(inthash, 3, 103);
vsy_IntHashInsert(inthash, 0, 100);
vsy_IntHashInsert(inthash, 2, 102);
vsy_IntHashInsert(inthash, 1, 101);
/* lookup a legal value */
vsy_IntHashLookup(inthash, 1, &val);
printf("value = %d\n", val);
/* lookup a illegal value */
vsy_IntHashLookup(inthash, 4, &val);
printf("value = %d\n", val);
/* now inquire and count */
vsy_IntHashInq(inthash, &num);
vsy_IntHashCount(inthash, &count);
printf("num = %d, count = %d\n", num, count);
/* InitIter,NextIter traversal */
vsy_IntHashInitIter(inthash);
while (vsy_IntHashNextIter(inthash, &key, &val), val != 0) {
printf("key = %d, value = %d\n", key, val);
}
/* delete object */
vsy_IntHashEnd(inthash);
}
/*----------------------------------------------------------------------
IntQue
----------------------------------------------------------------------*/
static void
test_intque(void)
{
vsy_IntQue* intque;
Vint num, count;
Vint val;
printf("\nIntQue test\n");
/* instance IntQue object */
intque = vsy_IntQueBegin();
/* set initial allocation to two integers */
vsy_IntQueDef(intque, 2);
/* inquire and count */
vsy_IntQueInq(intque, &num);
vsy_IntQueCount(intque, &count);
printf("num = %d, count = %d\n", num, count);
/* put some integers */
vsy_IntQuePut(intque, 105);
vsy_IntQuePut(intque, 103);
vsy_IntQuePut(intque, 100);
vsy_IntQuePut(intque, 102);
vsy_IntQuePut(intque, 101);
/* reference */
vsy_IntQueRef(intque, &val);
printf("value = %d\n", val);
/* get */
vsy_IntQueGet(intque, &val);
printf("value = %d\n", val);
/* now inquire and count */
vsy_IntQueInq(intque, &num);
vsy_IntQueCount(intque, &count);
printf("num = %d, count = %d\n", num, count);
/* delete object */
vsy_IntQueEnd(intque);
}
10.3. Example 3, Demonstration of Property Sets
This example illustrates the use of the PropSet property set module. A single PropSet object is instanced and a number of property types are inserted. Note that the PropSet object makes a copy of all the inserted properties. The total number of defined properties is counted. Finally all the properties inserted in the PropSet object are printed.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
static void
print_propset(vsy_PropSet* propset, Vchar* stg);
/*----------------------------------------------------------------------
Test and demonstrate property sets
----------------------------------------------------------------------*/
int
main()
{
vsy_PropSet* propset;
Vint ivalue[16];
Vdouble dvalue[16];
Vobject* pvalue[16];
Vint count;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
printf("\nPropSet test\n");
/* instance object */
propset = vsy_PropSetBegin();
/* insert some properties */
vsy_PropSetInserti(propset, "integer", 1);
vsy_PropSetInsertf(propset, "float", 2.);
ivalue[0] = 10;
ivalue[1] = 11;
ivalue[2] = 12;
vsy_PropSetInsertiv(propset, "integer vector", 3, ivalue);
vsy_PropSetInsertc(propset, "string", (Vchar*)"Test and demonstrate property set");
dvalue[0] = 100.;
dvalue[1] = 101.;
vsy_PropSetInsertdv(propset, "double vector", 2, dvalue);
pvalue[0] = (void*)1;
pvalue[1] = (void*)2;
vsy_PropSetInsertpv(propset, "object vector", 2, pvalue);
vsy_PropSetCount(propset, &count);
printf("number of properties = %d\n", count);
print_propset(propset, (Vchar*)"Property Set");
/* delete object */
vsy_PropSetEnd(propset);
return 0;
}
/*----------------------------------------------------------------------
print utility
----------------------------------------------------------------------*/
static void
print_propset(vsy_PropSet* propset, Vchar* stg)
{
Vchar* name;
Vint type, num, size;
Vint i;
Vint ivalue[16];
Vfloat fvalue[16];
Vdouble dvalue[16];
Vobject* pvalue[16];
Vchar cvalue[256];
/* print a title */
printf("\n%s\n", stg);
/* print values of all entries */
vsy_PropSetInitIter(propset);
while (vsy_PropSetNextIter(propset, &name), name != NULL) {
vsy_PropSetLookup(propset, name, &type, &num, &size);
printf("\nProperty name = %s\n", name);
printf(" type = %d\n", type);
printf(" num = %d\n", num);
printf(" size = %d\n", size);
if (type == SYS_INTEGER) {
vsy_PropSetLookupInteger(propset, name, ivalue);
for (i = 0; i < num; i++) {
printf(" prop[%2d] = %d\n", i, ivalue[i]);
}
}
else if (type == SYS_FLOAT) {
vsy_PropSetLookupFloat(propset, name, fvalue);
for (i = 0; i < num; i++) {
printf(" prop[%2d] = %f\n", i, fvalue[i]);
}
}
else if (type == SYS_DOUBLE) {
vsy_PropSetLookupDouble(propset, name, dvalue);
for (i = 0; i < num; i++) {
printf(" prop[%2d] = %f\n", i, dvalue[i]);
}
}
else if (type == SYS_OBJECT) {
vsy_PropSetLookupObject(propset, name, pvalue);
for (i = 0; i < num; i++) {
printf(" prop[%2d] = %p\n", i, pvalue[i]);
}
}
else if (type == SYS_STRING) {
vsy_PropSetLookupString(propset, name, cvalue);
printf(" prop = %s\n", cvalue);
}
}
}
10.4. Example 4, Demonstration of Random Number Generation
This example illustrates the use of the Random random number module.
A single Random object is instanced and 10 random numbers are generated
and printed using the default seed. Then a user specified seed is set
using vsy_RandomInit()
and 10 more random numbers are generated.
Note that Random will generate an identical sequence of random numbers from
the same seed.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
test and demonstrate random object
----------------------------------------------------------------------*/
int
main()
{
int i;
Vint ir;
Vfloat fr;
vsy_Random* random;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance Random object */
random = vsy_RandomBegin();
/* generate and print 10 random numbers */
printf("Default seed\n");
for (i = 0; i < 10; i++) {
vsy_RandomNumber(random, &fr);
printf("i,fr %d %f\n", i, fr);
}
/* set a seed and generate 10 more random numbers */
printf("User seed\n");
vsy_RandomInit(random, 70946);
for (i = 0; i < 10; i++) {
vsy_RandomNumber(random, &fr);
printf("i,fr %d %f\n", i, fr);
}
for (i = 0; i < 10; i++) {
vsy_RandomInteger(random, &ir);
printf("i,ir %d %d\n", i, ir);
}
/* destroy Random object */
vsy_RandomEnd(random);
return 0;
}
10.5. Example 5, Creating a Derived Class in C++ Using a Base Random Class
This example is an extension of Example 4 and illustrates creating a derived class, der_Random, in C++ using Random as a public base class. The derived class extends the base class by adding the function, Boolean, to return random boolean values (an integer 0 or 1).
#include <stdio.h>
#include "sam/base/base.h"
class der_Random: public vsy_Random {
public:
void
Boolean(Vint*);
};
void
der_Random::Boolean(Vint* boolean)
{
Vfloat r;
vsy_Random::Number(&r);
if (r < .5) {
*boolean = 0;
}
else {
*boolean = 1;
}
}
/*----------------------------------------------------------------------
demonstrate derived der_Random object
----------------------------------------------------------------------*/
int
main()
{
int i;
Vfloat f;
Vint b;
der_Random* random;
/* instance derived Random object */
random = new der_Random();
/* generate and print 10 random numbers */
printf("Default seed\n");
for (i = 0; i < 10; i++) {
random->Number(&f);
printf("i,f %d %f\n", i, f);
}
/* set a seed and generate 10 more random numbers */
printf("User seed\n");
random->Init(70946);
for (i = 0; i < 10; i++) {
random->Number(&f);
printf("i,f %d %f\n", i, f);
}
/* generate 10 random Booleans */
printf("Added function Boolean\n");
for (i = 0; i < 10; i++) {
random->Boolean(&b);
printf("i,b %d %d\n", i, b);
}
/* destroy derived Random object */
delete random;
return 0;
}
10.6. Example 6, Install User Error Handler and Memory Management
This example illustrates the procedure for installing a user error
handler and user memory management functions.
The user error handler is installed using vut_ErrorSetHandler()
. When
installed it acts as the error handler for all objects. The user error
handler in this example prints the data passed in the argument list
and uses the vut_ErrorString()
function to interpret the errorflag
argument. The user memory management functions are set using
vut_MemorySetFunctions()
and like the user error handler act as the memory
management system for all objects.
A simple List object is instanced and vsy_ListInsert()
is called with
an improper argument to generate an error. The user error handler is
invoked at this point. The default error handler is reinstalled by calling
vut_ErrorSetHandler()
with a NULL argument, vsy_ListInsert()
is called
again with an improper argument and the default handler is invoked.
Notice the printed output of the user defined memory management functions.
User defined memory management functions should only be installed once
before any objects are instanced and should remain in effect until all objects
are destroyed.
#include <stdlib.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/* list of system error types */
static Vint errortable[SYS_ERROR_MAX] = {SYS_ERROR_VALUE, SYS_ERROR_ENUM, SYS_ERROR_OBJECTTYPE, SYS_ERROR_MEMORY,
SYS_ERROR_NULLOBJECT, SYS_ERROR_FILE, SYS_ERROR_COMPUTE, SYS_ERROR_OPERATION,
SYS_ERROR_OVERFLOW, SYS_ERROR_UNDERFLOW, SYS_ERROR_UNKNOWN, SYS_ERROR_FORMAT,
SYS_ERROR_SEVERE};
static const Vchar* errorname[SYS_ERROR_MAX] = {
"SYS_ERROR_VALUE", "SYS_ERROR_ENUM", "SYS_ERROR_OBJECTTYPE", "SYS_ERROR_MEMORY", "SYS_ERROR_NULLOBJECT",
"SYS_ERROR_FILE", "SYS_ERROR_COMPUTE", "SYS_ERROR_OPERATION", "SYS_ERROR_OVERFLOW", "SYS_ERROR_UNDERFLOW",
"SYS_ERROR_UNKNOWN", "SYS_ERROR_FORMAT", "SYS_ERROR_SEVERE"};
static void
user_ErrorHandler(const Vchar* funcname, Vint errorflag, const Vchar* message)
{
printf("\n");
if (funcname) {
printf("function : %s\n", funcname);
}
if (errorflag > 0 && errorflag <= SYS_ERROR_MAX) {
printf("error : %s\n", vut_ErrorString(errorflag));
}
if (strlen(message)) {
printf("message : %s\n", message);
}
}
static void*
user_malloc(size_t siz)
{
printf("\n");
printf("malloc %lu bytes\n", (unsigned long)siz);
return (malloc(siz));
}
static void*
user_realloc(void* ptr, size_t siz)
{
printf("\n");
printf("realloc %p ptr, %lu bytes\n", ptr, (unsigned long)siz);
return (realloc(ptr, siz));
}
static void
user_free(void* ptr)
{
printf("\n");
printf("free %p ptr\n", ptr);
free(ptr);
}
/*----------------------------------------------------------------------
Install user error handler and memory management
----------------------------------------------------------------------*/
int
main()
{
Vint i;
vsy_List* list;
Vint num;
Vint ierr;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* print DevTools version string */
printf("version= %s\n", vut_Name(NAME_VERSION, 0));
/* install user error handler */
vut_ErrorSetHandler(user_ErrorHandler);
/* install user memory management */
vut_MemorySetFunctions(user_malloc, user_realloc, user_free);
/* instance object */
list = vsy_ListBegin();
/* insert some numbers */
/* index= -1 produces an error */
vsy_ListInsert(list, -1, (void*)1);
vsy_ListInsert(list, 10, (void*)10);
vsy_ListInsert(list, 20, (void*)20);
/* count objects */
vsy_ListCount(list, &num);
printf("\n");
printf("num= %d\n", num);
printf("\n");
/* reinstall default error handler */
vut_ErrorSetHandler(NULL);
/* insert an object */
/* index= -2 produces an error */
vsy_ListInsert(list, -2, (void*)2);
/* query object for error and search */
ierr = vsy_ListError(list);
/* in general, errors are non-zero */
if (ierr) {
for (i = 0; i < SYS_ERROR_MAX; i++) {
if (ierr == errortable[i]) {
printf("\nError, ierr= %d, name= %s\n", ierr, errorname[i]);
break;
}
}
}
/* delete object */
vsy_ListEnd(list);
return 0;
}
10.7. Example 7, Test and Demonstrate Concatenated Storage
This example illustrates using the Concat module for storing
a series of data records efficiently without the need for many small
individual memory allocations for each record.
After the Concat object is instanced, 10000 small data records, lm,
containing 4 integers each are added to the concatenation. Each
call to vsy_ConcatAdd()
copies the contents of the integer lm vector
to the concatenation.
The number of bytes currently stored in the concatenation and
the number of records added are returned and printed.
Then each data record is visited sequentially using
the iterator functions. The contents of each record are printed.
#include <stdlib.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate concatenation storage
----------------------------------------------------------------------*/
int
main()
{
Vint i;
vsy_Concat* concat;
Vint lm[4];
Vint num;
Vlong siz;
Vint nbytes;
Vint* lmptr;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
concat = vsy_ConcatBegin();
/* insert some arrays */
for (i = 0; i < 10000; i++) {
lm[0] = i;
lm[1] = i + 1;
lm[2] = i + 2;
lm[3] = i + 3;
vsy_ConcatAdd(concat, 4 * sizeof(Vint), lm);
/* get the pointer to the last data entered for i == 100 */
if (i == 100) {
vsy_ConcatRef(concat, (void**)&lmptr);
printf("ith = %d, lm[] = %d %d %d %d\n", i, lmptr[0], lmptr[1], lmptr[2], lmptr[3]);
}
}
/* count objects */
vsy_ConcatInq(concat, &siz);
vsy_ConcatCount(concat, &num);
printf("\n");
printf("siz= %lld\n", siz);
printf("num= %d\n", num);
printf("\n");
/* iterate through records printing every 100th */
i = 0;
vsy_ConcatInitIter(concat);
while (vsy_ConcatNextIter(concat, &nbytes, (void**)&lmptr), lmptr != NULL) {
if (i % 100 == 0) {
printf("ith = %d, nbytes = %d, lm[] = %d %d %d %d\n", i, nbytes, lmptr[0], lmptr[1], lmptr[2], lmptr[3]);
}
i++;
}
/* delete object */
vsy_ConcatEnd(concat);
return 0;
}
10.8. Example 8, Test and Demonstrate a Data Table
This example demonstrates the use of the DataTable module.
The DataTable module is designed to hold pointers to
vectors of double precision data
at associated values of a double precision independent variable. Each
vector is assumed to be a constant length specified by the vsy_DataTableDef()
function. In this example four vectors of data of length three are inserted
at values -50., 50., 100., and 200. of the independent variable using
function vsy_DataTableInsert()
.
These vectors might represent, for example,
values of material properties as a function of temperature.
This function does not copy the vector data
only the pointer to the vector.
The order in which the values
are entered is immaterial, the DataTable object always sorts the vectors
as a function of increasing value of the independent variable.
The function vsy_DataTableLookup()
is used to return the pointer to the
vector at a previously input value. The function vsy_DataTableEval()
is used
to evaluate the vector data at some arbitrary value of the independent
variable. The function vsy_DataTableSetParami()
is called to enable
linear extrapolation.
The function vsy_DataTableForEach()
is be used in this example
to free all the vector memory objects.
#include <stdlib.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate data table
----------------------------------------------------------------------*/
int
main()
{
Vint num;
vsy_DataTable* datatable;
Vdouble v, *d, deval[3];
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
datatable = vsy_DataTableBegin();
/* configure to hold 3-component data objects */
vsy_DataTableDef(datatable, 0, 3);
d = (Vdouble*)malloc(3 * sizeof(Vdouble));
d[0] = 20000000.;
d[1] = .3;
d[2] = .0020;
vsy_DataTableInsert(datatable, 200., d);
d = (Vdouble*)malloc(3 * sizeof(Vdouble));
d[0] = 10000000.;
d[1] = .3;
d[2] = .0015;
vsy_DataTableInsert(datatable, 100., d);
d = (Vdouble*)malloc(3 * sizeof(Vdouble));
d[0] = 8000000.;
d[1] = .3;
d[2] = .0010;
vsy_DataTableInsert(datatable, 50., d);
d = (Vdouble*)malloc(3 * sizeof(Vdouble));
d[0] = 6000000.;
d[1] = .3;
d[2] = .0008;
vsy_DataTableInsert(datatable, -50., d);
/* count objects */
vsy_DataTableCount(datatable, &num);
printf("\n");
printf("num= %d\n\n", num);
/* lookup */
vsy_DataTableLookup(datatable, 200., &d);
if (d != NULL) {
printf("Lookup v= 200. d = %f %f %f\n\n", d[0], d[1], d[2]);
}
/* evaluate */
vsy_DataTableSetParami(datatable, DATATABLE_EXTRAPOLATE, DATATABLE_LINEAR);
vsy_DataTableEval(datatable, 150., deval);
printf("Eval v= 150. d = %f %f %f\n\n", deval[0], deval[1], deval[2]);
vsy_DataTableEval(datatable, 400., deval);
printf("Eval v= 400. d = %f %f %f\n\n", deval[0], deval[1], deval[2]);
/* iterate through objects */
vsy_DataTableInitIter(datatable);
while (vsy_DataTableNextIter(datatable, &v, (Vdouble**)&d), d != NULL) {
printf("v = %f, d = %f %f %f\n", v, d[0], d[1], d[2]);
}
/* free data objects */
vsy_DataTableForEach(datatable, (void (*)(void*))free);
/* delete object */
vsy_DataTableEnd(datatable);
return 0;
}
10.9. Example 9, Test and Demonstrate a PQueue Object
This example demonstrates the use of the PQueue module.
The PQueue module is designed to hold integer indices and
associated priority values.
In this example priority values representing angles in degrees are stored.
A priority queue of this type may represent the minimum angle in a triangle.
The dynamic range of the priority values is set to (0.,60.). Any angles
larger than 60. degrees will be placed in the accumulator associated with
angles within the priority queue precision of 60. degrees. The priority
queue precision is 60./1024. in this case.
Several indices with associated priority values are inserted using
vsy_PQueueInsert()
. Note that the priority value of index 6 is redefined.
The index with the minimum angle is queried using vsy_PQueueMinMax()
and
removed using vsy_PQueueRemove()
. The next minimum is then queried and
printed but not removed. A new index is inserted with an angle which
is a new minimum. A subsequent query for the current minimum retrieves this
index. Unlike standard priority queues based upon heap data structures, the
PQueue module allows queries for either minimum or maximum value.
Finally the priority queue is cleared and a subsequent check for a maximum
value returns an index of zero.
#include <stdlib.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and Demonstrate PQueue object
----------------------------------------------------------------------*/
int
main()
{
vsy_PQueue* pqueue;
Vint id;
Vdouble val;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
pqueue = vsy_PQueueBegin();
/* configure to degrees from 0. to 60. */
vsy_PQueueDef(pqueue, 0, 1024);
vsy_PQueueRange(pqueue, 0., 60.);
vsy_PQueueInsert(pqueue, 1, 20.);
vsy_PQueueInsert(pqueue, 3, 30.);
vsy_PQueueInsert(pqueue, 6, 10.);
vsy_PQueueInsert(pqueue, 7, 10.001);
/* redefine index 6 */
vsy_PQueueInsert(pqueue, 6, 40.001);
/* query for minimum and remove */
vsy_PQueueMinMax(pqueue, 0, &id, &val);
vsy_PQueueRemove(pqueue, id);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* query for minimum */
vsy_PQueueMinMax(pqueue, 0, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* insert new minimum */
vsy_PQueueInsert(pqueue, 2, 5.);
vsy_PQueueMinMax(pqueue, 0, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* query for maximum */
vsy_PQueueMinMax(pqueue, 1, &id, &val);
printf("\n");
printf("maximum id= %d, val= %e\n", id, val);
/* clear */
vsy_PQueueClear(pqueue);
/* check */
vsy_PQueueMinMax(pqueue, 1, &id, &val);
printf("maximum id= %d\n", id);
/* delete object */
vsy_PQueueEnd(pqueue);
return 0;
}
10.10. Example 9a, Test and Demonstrate a Heap Object
This example demonstrates the use of the Heap module. Like the PQueue module, the Heap module is designed to hold integer indices and associated priority values. The Heap module maintains a precise priority queue while the PQueue module is approximate. The Heap is set up to maintain a minimum priority queue.
Several indices with associated priority values are inserted using
vsy_HeapInsert()
. Note that the priority value of index 6 is redefined.
The index with the minimum value is queried and removed
using vsy_HeapRefRemove()
.
The next minimum is then queried and
printed but not removed. A new index is inserted with a value which
is a new minimum. A subsequent query for the current minimum retrieves this
index.
Index 1 is removed even though it does not contain the minimum value.
Finally the priority queue is cleared and a subsequent check for a minimum
value returns an index of zero.
#include <stdlib.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and Demonstrate Heap object
----------------------------------------------------------------------*/
int
main()
{
vsy_Heap* heap;
Vint id;
Vdouble val;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
heap = vsy_HeapBegin();
/* set up heap to return minimum */
vsy_HeapDef(heap, 10, 0);
vsy_HeapInsert(heap, 1, 20.);
vsy_HeapInsert(heap, 3, 30.);
vsy_HeapInsert(heap, 6, 10.);
vsy_HeapInsert(heap, 7, 10.001);
/* redefine index 6 */
vsy_HeapInsert(heap, 6, 40.001);
/* query for minimum and remove */
vsy_HeapRefRemove(heap, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* query for minimum */
vsy_HeapRef(heap, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* insert new minimum */
vsy_HeapInsert(heap, 2, 5.);
vsy_HeapRef(heap, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* remove index 1 */
vsy_HeapRemove(heap, 1);
/* remove two, if 1 has been removed the 3 is new min */
vsy_HeapRefRemove(heap, &id, &val);
vsy_HeapRefRemove(heap, &id, &val);
printf("\n");
printf("minimum id= %d, val= %e\n", id, val);
/* clear */
vsy_HeapClear(heap);
/* check */
vsy_HeapRef(heap, &id, &val);
printf("minimum id= %d\n", id);
/* delete object */
vsy_HeapEnd(heap);
return 0;
}
10.11. Example 10, Test and Demonstrate a TriCon Object
This example demonstrates the use of the TriCon module.
The TriCon module is designed to hold triangle connectivity and support
triangle stripping, connectivity and adjacency queries.
In this example two separate sets of triangles are processed, the first
contains 4 triangles, the second 9 triangles.
An estimated number of triangles, in this case the exact number contained
in the first set, is defined with vsy_TriConDef()
. Each triangle is entered
using vsy_TriConAppend()
, and triangle indices are assigned to each
triangle starting with 1.
Once all triangles are entered, the function vsy_TriConProcess()
is called
to generate adjacency and strip information. The number of triangle strips
and maximum number of points in any strip are returned.
A loop over the number of strips is performed and vsy_TriConStrip()
is called
to return the point connectivity of each strip.
The function vsy_TriConNum()
may be used to conveniently query the
number of defined triangles.
In order to process another triangle set the function vsy_TriConClear()
must be called. The triangles for the second set are then appended in a
manner similar to the procedure used for the first set. Indices are
assigned starting with 1. This second set of triangles is processed
and the resulting strips queried and printed.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*
3
/ \
6---5
/ \ / \
1---4---2
*/
Vint tri4[4][3] = {{1, 4, 6}, {4, 5, 6}, {4, 2, 5}, {6, 5, 3}};
/*
10
/ \
8---9
/ \ / \
5---6---7
/ \ / \ / \
1---2---3---4
*/
Vint tri9[9][3] = {{1, 2, 5}, {2, 6, 5}, {2, 3, 6}, {3, 7, 6}, {3, 4, 7}, {5, 6, 8}, {6, 9, 8}, {6, 7, 9}, {8, 9, 10}};
/*----------------------------------------------------------------------
test and demonstrate TriCon object
----------------------------------------------------------------------*/
int
main()
{
Vint i;
vsy_TriCon* tricon;
Vint numstrips, maxlength, istrip;
Vint ntris;
Vint ns, ie[9], is[11];
Vint ix[3];
Vint numtri;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* do 4 element triangular mesh */
ntris = 4;
/* instance TriCon object */
tricon = vsy_TriConBegin();
vsy_TriConDef(tricon, ntris);
/* insert triangles */
for (i = 0; i < ntris; i++) {
vsy_TriConAppend(tricon, tri4[i]);
}
/* process */
vsy_TriConProcess(tricon, &numstrips, &maxlength);
printf(" numstrips= %d, maxlength= %d\n", numstrips, maxlength);
/* access triangle strips */
for (istrip = 1; istrip <= numstrips; istrip++) {
vsy_TriConStrip(tricon, istrip, &ns, ie, is);
printf("strip= %d, ns= %d\n", istrip, ns);
for (i = 0; i < ns; i++) {
printf(" %d", is[i]);
}
printf("\n");
}
/* find out how many triangles there are */
vsy_TriConNum(tricon, &numtri);
printf("Current number of triangles= %d\n", numtri);
/* access input triangle connections */
for (i = 1; i <= numtri; i++) {
vsy_TriConRef(tricon, i, ix);
printf("tri[%d]= %d %d %d\n", i, ix[0], ix[1], ix[2]);
}
/* now do 9 element triangular mesh */
vsy_TriConClear(tricon);
ntris = 9;
for (i = 0; i < ntris; i++) {
vsy_TriConAppend(tricon, tri9[i]);
}
vsy_TriConProcess(tricon, &numstrips, &maxlength);
printf(" numstrips= %d, maxlength= %d\n", numstrips, maxlength);
for (istrip = 1; istrip <= numstrips; istrip++) {
vsy_TriConStrip(tricon, istrip, &ns, ie, is);
printf("strip= %d, ns= %d\n", istrip, ns);
for (i = 0; i < ns; i++) {
printf(" %d", is[i]);
}
printf("\n");
}
/* destroy TriCon object */
vsy_TriConEnd(tricon);
return 0;
}
10.12. Example 11, Test and Demonstrate a VertLoc Object
This example demonstrates the use of the VertLoc module.
The VertLoc module is designed to hold point coordinates and associated
attributes and support point colocation queries.
In this example 4 points are defined in the x,y plane. Points 2 and 4
are colocated at (1.,0.,0.) and are assigned identical color and normal
attributes. The points are inserted at the specified coordinate locations
and their attributes are set. The functions vsy_VertLocSetColor()
and
vsy_VertLocSetNormal()
are called before the call to vsy_VertLocInsert()
is made to define the point location. This ensures that the current
attributes are set to the point attributes when the insertion is made.
The colocated points are determined with the call to vsy_VertLocMerge()
.
The number of unique point locations and the maximum number of colocated points
is returned. Since two of the four points are colocated, then the number of
unique sets is 3 and the maximum number of colocated points is 2. If the
attributes for points 2 and 4 were not identical they would not have been
identified as colocated points. All attributes are stored internally
with an 8-bit representation and all attribute comparisons are done at this
resolution. Note that this fact also affects the attribute values returned
by vsy_VertLocColor()
and vsy_VertLocNormal()
. There will be round
off errors due to this 8-bit representation.
A loop over the number of uniques sets is performed
and vsy_VertLocUnique()
is called
to return the point indices contained in each set.
The function vsy_VertLocLowest()
is useful for finding the lowest point index
coincident with any given point index.
The function vsy_VertLocNum()
may be used to conveniently query the
number of defined points.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
Vfloat vert[4][3] = {{0.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {1.f, 0.f, 0.f}};
Vfloat ct[4][3] = {{0.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {0.f, 1.f, 0.f}};
Vfloat vn[4][3] = {{1.f, 0.f, 0.f}, {.7071f, .7071f, 0.f}, {0.f, 0.f, -1.f}, {.7071f, .7071f, 0.f}};
/*----------------------------------------------------------------------
test and demonstrate VertLoc object
----------------------------------------------------------------------*/
int
main()
{
Vint i;
vsy_VertLoc* vertloc;
Vint numunique, maxlocate, iunique, lowestid;
Vint nverts;
Vfloat x[3];
Vfloat c[3], v[3];
Vint nu, iu[10];
Vint numvert;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
nverts = 4;
/* instance VertLoc object */
vertloc = vsy_VertLocBegin();
vsy_VertLocDef(vertloc, nverts);
/* insert vertices */
for (i = 1; i <= nverts; i++) {
vsy_VertLocSetColor(vertloc, ct[i - 1]);
vsy_VertLocSetNormal(vertloc, vn[i - 1]);
vsy_VertLocInsert(vertloc, i, vert[i - 1]);
}
/* merge */
vsy_VertLocMerge(vertloc, &numunique, &maxlocate);
printf(" numunique= %d, maxlocate= %d\n", numunique, maxlocate);
/* query for unique clusters of vertices */
for (iunique = 1; iunique <= numunique; iunique++) {
vsy_VertLocUnique(vertloc, iunique, &nu, iu);
printf("unique vertex cluster= %d, nu= %d\n", iunique, nu);
for (i = 0; i < nu; i++) {
printf(" %d", iu[i]);
}
printf("\n");
}
/* access lowest id */
for (i = 1; i <= nverts; i++) {
vsy_VertLocLowest(vertloc, i, &iunique, &lowestid);
printf("vert[%d], iunique= %d, lowestid= %d\n", i, iunique, lowestid);
}
/* find out how many points there are */
vsy_VertLocNum(vertloc, &numvert);
printf("Current number of points= %d\n", numvert);
/* access input vertex locations */
for (i = 1; i <= numvert; i++) {
vsy_VertLocRef(vertloc, i, x);
printf("vert[%d]= %e %e %e\n", i, x[0], x[1], x[2]);
vsy_VertLocColor(vertloc, i, c);
printf("color[%d]= %e %e %e\n", i, c[0], c[1], c[2]);
vsy_VertLocNormal(vertloc, i, v);
printf("normal[%d]= %e %e %e\n", i, v[0], v[1], v[2]);
}
/* destroy VertLoc object */
vsy_VertLocEnd(vertloc);
return 0;
}
10.13. Example 12, Test and Demonstrate a LineCon Object
This example demonstrates the use of the LineCon module.
The LineCon module is designed to hold line connectivity and support
line stripping and connectivity queries.
In this example two separate sets of lines are processed, the first
contains 9 lines outlining a mesh of 4 triangles, the contains 11 lines
incompletely outlining a mesh of 9 triangles.
An estimated number of lines, in this case the exact number contained
in the first set, is defined with vsy_LineConDef()
. Each line is entered
using vsy_LineConAppend()
, and line indices are assigned to each
line starting with 1.
Once all lines are entered, the function vsy_LineConProcess()
is called
to generate strip information. The number of line strips
and maximum number of points in any strip are returned.
A loop over the number of strips is performed and vsy_LineConStrip()
is called
to return the point connectivity of each strip.
The function vsy_LineConNum()
may be used to conveniently query the
number of defined lines.
In order to process another line set the function vsy_LineConClear()
must be called. The lines for the second set are then appended in a
manner similar to the procedure used for the first set. Indices are
assigned starting with 1. This second set of lines is processed
and the resulting strips queried and printed.
In each case LineCon is able to connect the line sets with a single
line strip.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*
3
/ \
6---5
/ \ / \
1---4---2
*/
Vint line9[9][2] = {{1, 4}, {4, 2}, {1, 6}, {4, 6}, {4, 5}, {2, 5}, {6, 5}, {6, 3}, {5, 3}};
/*
10
/ \
8 9
/ \
5---6---7
/ \
1---2---3---4
*/
Vint line11[11][2] = {{1, 2}, {2, 3}, {3, 4}, {1, 5}, {4, 7}, {5, 6}, {6, 7}, {5, 8}, {7, 9}, {8, 10}, {9, 10}};
/*----------------------------------------------------------------------
test and demonstrate LineCon object
----------------------------------------------------------------------*/
int
main()
{
Vint i;
vsy_LineCon* linecon;
Vint numstrips, maxlength, istrip;
Vint nlines;
Vint ns, ie[11], is[12];
Vint ix[2];
Vint numline;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* do 4 element triangular mesh, with 9 lines */
nlines = 9;
/* instance LineCon object */
linecon = vsy_LineConBegin();
vsy_LineConDef(linecon, nlines);
/* insert lines */
for (i = 0; i < nlines; i++) {
vsy_LineConAppend(linecon, line9[i]);
}
/* process */
vsy_LineConProcess(linecon, &numstrips, &maxlength);
printf(" numstrips= %d, maxlength= %d\n", numstrips, maxlength);
/* access line strips */
for (istrip = 1; istrip <= numstrips; istrip++) {
vsy_LineConStrip(linecon, istrip, &ns, ie, is);
printf("strip= %d, ns= %d\n", istrip, ns);
printf("lines=");
for (i = 0; i < ns - 1; i++) {
printf(" %d", ie[i]);
}
printf("\n");
printf("nodes=");
for (i = 0; i < ns; i++) {
printf(" %d", is[i]);
}
printf("\n");
}
/* find out how many lines there are */
vsy_LineConNum(linecon, &numline);
printf("Current number of lines= %d\n", numline);
/* access input lines connections */
for (i = 1; i <= numline; i++) {
vsy_LineConRef(linecon, i, ix);
printf("line[%d]= %d %d\n", i, ix[0], ix[1]);
}
/* now do a 10 point mesh incompletely connected */
vsy_LineConClear(linecon);
nlines = 11;
for (i = 0; i < nlines; i++) {
vsy_LineConAppend(linecon, line11[i]);
}
vsy_LineConProcess(linecon, &numstrips, &maxlength);
printf(" numstrips= %d, maxlength= %d\n", numstrips, maxlength);
for (istrip = 1; istrip <= numstrips; istrip++) {
vsy_LineConStrip(linecon, istrip, &ns, ie, is);
printf("strip= %d, ns= %d\n", istrip, ns);
printf("lines=");
for (i = 0; i < ns - 1; i++) {
printf(" %d", ie[i]);
}
printf("\n");
printf("nodes=");
for (i = 0; i < ns; i++) {
printf(" %d", is[i]);
}
printf("\n");
}
/* destroy LineCon object */
vsy_LineConEnd(linecon);
return 0;
}
10.14. Example 13, Test and Demonstrate a Timer Object
This example demonstrates the use of the Timer module.
A single Timer object can be used to accumulate timing information
for several timed sections. In this example two timing
sections, PlusOne and Multiply are created. First the timing
interval for PlusOne is started using vsy_TimerStart()
.
Since this is the first reference
to this timed section it is created by this call.
After the addition loop the timing interval is stopped using vsy_TimerStop()
.
The contents of Timer are printed using vsy_TimerInitIter()
,
vsy_TimerNextIter()
and vsy_TimerEval()
.
Then a timing interval for timed section, Multiply is performed
for a multiplication loop. Note that timing information can be retrieved
using vsy_TimerEval()
inside or outside a timing interval.
The functions vsy_TimerInit()
, vsy_TimerRemove()
and vsy_TimerClear()
are called illustrating their effects on the timed sections in Timer.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
static void
print_time(vsy_Timer* timer);
/*----------------------------------------------------------------------
Test and demonstrate Timer
----------------------------------------------------------------------*/
int
main()
{
Vint i;
Vdouble a;
vsy_Timer* timer;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
printf("\nTimer test\n");
/* instance object */
timer = vsy_TimerBegin();
/* start timing addition */
vsy_TimerStart(timer, "PlusOne");
a = 0;
for (i = 0; i < 10000000; i++) {
a += 1.;
}
/* stop and print */
vsy_TimerStop(timer, "PlusOne");
print_time(timer);
/* start timing multiplication */
vsy_TimerStart(timer, "Multiply");
a = 1;
for (i = 0; i < 10000000; i++) {
a *= 1.0000001;
}
/* stop and print */
vsy_TimerStop(timer, "Multiply");
print_time(timer);
/* restart timing addition */
vsy_TimerStart(timer, "PlusOne");
a = 0;
for (i = 0; i < 20000000; i++) {
a += 1.;
}
/* print before stopping */
print_time(timer);
/* stop and print */
vsy_TimerStop(timer, "PlusOne");
print_time(timer);
/* initialize and print */
vsy_TimerInit(timer, "PlusOne");
print_time(timer);
/* remove and print */
vsy_TimerRemove(timer, "Multiply");
print_time(timer);
/* clear all */
vsy_TimerClear(timer);
print_time(timer);
/* delete object */
vsy_TimerEnd(timer);
return 0;
}
/*----------------------------------------------------------------------
print utility
----------------------------------------------------------------------*/
static void
print_time(vsy_Timer* timer)
{
Vchar* name;
Vint num, run;
Vfloat usr, sys, ela;
printf("Current timer state\n");
/* iterate through all times */
vsy_TimerInitIter(timer);
while (vsy_TimerNextIter(timer, &name), name) {
vsy_TimerEval(timer, name, &num, &run, &usr, &sys, &ela);
printf(" name: %s, num= %d, run= %d, cpu= %f, sys= %f, ela= %f\n", name, num, run, usr, sys, ela);
}
}
10.15. Example 14, Test and Demonstrate the MachInfo Module
This example demonstrates querying the MachInfo object for the machine information such as system name, host name, number of processors, processor MFlop rate and total physical memory. The status flag returned by each machine information call indicates whether the query is supported or not. Certain compiled options such as VKI_LIBAPI_SOCKETS may also be queried. The returned status flag indicates whether MachInfo has been compiled with the respective compile options.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate MachInfo
----------------------------------------------------------------------*/
int
main()
{
Vint flag;
Vint numproc;
Vint totalmem;
Vint usedmem;
Vint objectsize;
Vint filepossize;
Vint endian;
Vdouble machprec;
Vchar sysname[256];
Vchar hostname[256];
Vchar username[256];
Vchar datestg[SYS_MAXDATENAME] = {0};
Vchar timestg[SYS_MAXTIMENAME] = {0};
Vchar vlongstg[33];
Vint day, mon, year;
Vint sec, min, hour;
Vlong vli;
Vfloat cpuusr, cpusys;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
printf("\nMachInfo test\n");
/* query for system name */
vut_MachInfoSystemName(&flag, sysname);
if (flag) {
printf("System name = %s\n", sysname);
}
else {
printf("System name query unsupported\n");
}
/* query for host name */
vut_MachInfoHostName(&flag, hostname);
if (flag) {
printf("Host name = %s\n", hostname);
}
else {
printf("Host name query unsupported\n");
}
/* query for user name */
vut_MachInfoUserName(&flag, username);
if (flag) {
printf("User name = %s\n", username);
}
else {
printf("User name query unsupported\n");
}
/* query for number of processors */
vut_MachInfoNumProc(&flag, &numproc);
if (flag) {
printf("Number of processors = %d\n", numproc);
}
else {
printf("Number of processors query unsupported\n");
}
/* query for machine precision */
vut_MachInfoPrec(&flag, &machprec);
if (flag) {
printf("Machine precision = %e\n", machprec);
}
else {
printf("Machine precision query unsupported\n");
}
/* query for total physical memory */
vut_MachInfoTotalMem(&flag, &totalmem);
if (flag) {
printf("Total memory (MBytes)= %d\n", totalmem);
}
else {
printf("Total memory (MBytes) query unsupported\n");
}
/* query for used physical memory */
vut_MachInfoUsedMem(&flag, &usedmem);
if (flag) {
printf("Used memory (MBytes)= %d\n", usedmem);
}
else {
printf("Used memory (MBytes) query unsupported\n");
}
/* query for object size */
vut_MachInfoObjectSize(&flag, &objectsize);
if (flag) {
printf("Object size sizeof(size_t)= %d\n", objectsize);
}
else {
printf("Object size query unsupported\n");
}
/* query for file position size */
vut_MachInfoFilePosSize(&flag, &filepossize);
if (flag) {
printf("File position size sizeof(long)= %d\n", filepossize);
}
else {
printf("File position size query unsupported\n");
}
/* query for endian */
/* the flag is always 1 */
vut_MachInfoEndian(&flag, &endian);
if (endian == 0) {
printf("Endian= big\n");
}
else {
printf("Endian= little\n");
}
/* date and time strings */
/* the flag is always 1 */
vut_MachInfoDateString(&flag, datestg);
printf("Date: %s\n", datestg);
vut_MachInfoTimeString(&flag, timestg);
printf("Time: %s\n", timestg);
/* date and time integers */
vut_MachInfoDateInteger(&flag, &day, &mon, &year);
printf("Date: day= %d, mon= %d, year= %d\n", day, mon, year);
vut_MachInfoTimeInteger(&flag, &sec, &min, &hour);
printf("Time: sec= %d, min= %d, hour= %d\n", sec, min, hour);
/* cpu times, user and system */
vut_MachInfoCpuTimes(&flag, &cpuusr, &cpusys);
printf("CpuTimes: usr= %e, sys= %e\n", cpuusr, cpusys);
/* Vlong string */
vli = 1234567;
vut_MachInfoVlongString(vli, vlongstg);
printf("long int(Vlong)= %s\n", vlongstg);
/* query for compiled options */
vut_MachInfoLIBAPI_SOCKETS(&flag);
if (flag) {
printf("VKI_LIBAPI_SOCKETS compiled\n");
}
else {
printf("VKI_LIBAPI_SOCKETS not compiled\n");
}
return 0;
}
10.16. Example 15, Test and Demonstrate a PTask Object
This example illustrates using a PTask object to compute
a dot product using threads. On a multiprocessor computer the objective
is to utilize all machine processors by dividing the computation into
equalized tasks and performing the dot product in parallel. In this example
2 processors are assumed and the dot product is carried out on two vectors
of length 1000000 doubles containing all ones.
A computing task which is to be executed on
a thread must be posed as a call to a function with a single argument of
type pointer to void. The function in this case is pdot and its argument
is a pointer to a structure, ptdot,
which has been designed to perform a dot product
on a subset of entries in the two vectors. Each thread structure contains
the number of entries to process, pointers to the starting addresses in
the global vectors and a single double, s, containing the dot product of the
subset. Note that each structure is allocated from the heap with an
additional CACHEPAD number of bytes. This is done to ensure that the
accumulators, s, are separated in memory by more than the size of a
cache line. This effectively eliminates cache line invalidation caused
by writing to the individual accumulators by more than one processor.
After the individual ptdot structures are initialized the threads
are created and executed using vsy_PTaskExec()
.
Once execution is complete,
the accumulators for each task are added and printed.
#include "stdio.h"
#include "stdlib.h"
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
typedef struct ptdot ptdot;
struct ptdot {
int n;
double* a;
double* b;
double s;
};
void
pdot(ptdot* p);
#define NUMPROC 2
#define NUMVEC 1000000
#define CACHEPAD 1024
/*----------------------------------------------------------------------
Test and Demonstrate PTask
----------------------------------------------------------------------*/
int
main()
{
int i, j;
int num, rem;
int np, nt;
double *at, *bt;
double st;
vsy_PTask* ptask;
ptdot* pt[NUMPROC];
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance PTask object */
ptask = vsy_PTaskBegin();
/* allocate vectors */
at = (double*)malloc(NUMVEC * sizeof(double));
bt = (double*)malloc(NUMVEC * sizeof(double));
/* initialize with ones */
for (j = 0; j < NUMVEC; j++) {
at[j] = 1.;
bt[j] = 1.;
}
/* partition dot product */
num = NUMVEC / NUMPROC;
rem = (NUMVEC % NUMPROC);
nt = 0;
for (i = 0; i < NUMPROC; i++) {
pt[i] = (ptdot*)malloc(sizeof(ptdot) + CACHEPAD);
if (i < NUMPROC - 1) {
np = num;
}
else {
np = num + rem;
}
pt[i]->n = np;
pt[i]->a = &at[nt];
pt[i]->b = &bt[nt];
nt += np;
}
/* execute over NUMPROC threads */
vsy_PTaskDef(ptask, NUMPROC, PTASK_EXEC);
vsy_PTaskExec(ptask, NUMPROC, (void (*)(void*))pdot, (Vobject**)pt);
/* add results of each thread */
st = 0.;
for (i = 0; i < NUMPROC; i++) {
st += pt[i]->s;
free(pt[i]);
}
printf("st= %e\n", st);
/* free vectors */
free(at);
free(bt);
/* delete PTask */
vsy_PTaskEnd(ptask);
return 0;
}
void
pdot(ptdot* p)
{
int i;
/* perform dot product */
p->s = 0.;
for (i = 0; i < p->n; i++) {
p->s += p->a[i] * p->b[i];
}
}
10.17. Example 16, Test and Demonstrate Text Processing and Formatting
This example illustrates using the text processing and formatting modules. Three formatting objects are used, HTMLText for HTML formatting, PlainText for plain text formatting and LaTeXText for LaTeX formatting. A TextTee object is used to direct the text content to all three formatters simultaneously. It requires three TextFun abstract interfaces (tf0, tf1 and tf2) to link the three formatters to the TextTee object and a single abstract interface (tf) to the TextTee object. All text content is written to the interface to the TextTee object and it propagates to the three formatters. Each of the three formatters writes to a file and the files exam16.htm, exam16.txt and exam16.tex are generated by this application. These files may be viewed/processed by a HTML browser, any text editor and the LaTeX text processing system. The following content is generated.
Title
Heading
Horizontal rule
Basic text
Itemized list
Table
Graphics image
Preformatted text
The function vsy_TextFunSetMode()
can be used to enable and disable
text formatting modes such as italics, bold, centering, etc.
Note the use of vsy_TextFunTextColor()
and vsy_TextFunTableColor()
to
control the color of text and the color of the table cells.
Finally the files are closed using vsy_TextFunCloseFile()
.
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/* define some colors */
static Vfloat red[3] = {1.f, 0.f, 0.f};
static Vfloat grn[3] = {0.f, 1.f, 0.f};
static Vfloat blu[3] = {0.f, 0.f, 1.f};
static Vfloat blk[3] = {0.f, 0.f, 0.f};
static Vfloat wht[3] = {1.f, 1.f, 1.f};
static Vfloat back[3] = {0.733333f, 0.866666f, 1.0f};
static Vfloat offwht[3] = {0.8f, 0.8f, 0.8f};
static Vfloat altwht[3] = {0.9f, 0.9f, 0.9f};
/*----------------------------------------------------------------------
Test and demonstrate TextFun objects
----------------------------------------------------------------------*/
int
main()
{
vsy_HTMLText* htmltext;
vsy_PlainText* plaintext;
vsy_LaTeXText* latextext;
vsy_TextTee* texttee;
vsy_TextFun *tf0, *tf1, *tf2, *tf;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* set HTML output */
htmltext = vsy_HTMLTextBegin();
tf0 = vsy_TextFunBegin();
vsy_HTMLTextTextFun(htmltext, tf0);
vsy_TextFunOpenFile(tf0, (Vchar*)"exam16.htm");
/* set plain text output */
plaintext = vsy_PlainTextBegin();
tf1 = vsy_TextFunBegin();
vsy_PlainTextTextFun(plaintext, tf1);
vsy_TextFunOpenFile(tf1, (Vchar*)"exam16.txt");
/* set LaTeX output */
latextext = vsy_LaTeXTextBegin();
tf2 = vsy_TextFunBegin();
vsy_LaTeXTextTextFun(latextext, tf2);
vsy_TextFunOpenFile(tf2, (Vchar*)"exam16.tex");
/* create a tee to write to all formats */
texttee = vsy_TextTeeBegin();
vsy_TextTeeSetObject(texttee, VSY_TEXTFUN, tf0);
vsy_TextTeeSetObject(texttee, VSY_TEXTFUN_1, tf1);
vsy_TextTeeSetObject(texttee, VSY_TEXTFUN_2, tf2);
tf = vsy_TextFunBegin();
vsy_TextTeeTextFun(texttee, tf);
/* title */
vsy_TextFunFormInit(tf, SYS_TEXT_TITLE);
vsy_TextFunString(tf, "This is the title");
vsy_TextFunFormTerm(tf, SYS_TEXT_TITLE);
/* level 1 heading */
vsy_TextFunHeadingLevel(tf, 1);
vsy_TextFunFormInit(tf, SYS_TEXT_HEADING);
vsy_TextFunString(tf, "This is a heading 1 test");
vsy_TextFunFormTerm(tf, SYS_TEXT_HEADING);
/* horizontal rule */
vsy_TextFunHorizontalRule(tf);
/* level 2 heading */
vsy_TextFunHeadingLevel(tf, 2);
vsy_TextFunFormInit(tf, SYS_TEXT_HEADING);
vsy_TextFunString(tf, "This is a heading 2 test");
vsy_TextFunFormTerm(tf, SYS_TEXT_HEADING);
/* basic text */
vsy_TextFunTextColor(tf, wht);
vsy_TextFunString(tf, "This is white-colored text.");
vsy_TextFunTextColor(tf, red);
vsy_TextFunString(tf, "This is red-colored text.");
vsy_TextFunTextColor(tf, grn);
vsy_TextFunString(tf, "This is green-colored text.");
vsy_TextFunTextColor(tf, blu);
vsy_TextFunString(tf, "This is blue-colored text.");
vsy_TextFunTextColor(tf, blk);
vsy_TextFunString(tf, "And now back to black-colored text.");
/* list */
vsy_TextFunListType(tf, SYS_TEXT_ORDERED);
vsy_TextFunFormInit(tf, SYS_TEXT_LIST);
vsy_TextFunFormInit(tf, SYS_TEXT_ITEM);
vsy_TextFunSetMode(tf, SYS_TEXT_BOLD, SYS_ON);
vsy_TextFunString(tf, "This is item 1 in a list in bold font");
vsy_TextFunSetMode(tf, SYS_TEXT_BOLD, SYS_OFF);
vsy_TextFunFormTerm(tf, SYS_TEXT_ITEM);
vsy_TextFunFormInit(tf, SYS_TEXT_ITEM);
vsy_TextFunSetMode(tf, SYS_TEXT_ITALICS, SYS_ON);
vsy_TextFunString(tf, "This is item 2 in a list in italics font");
vsy_TextFunSetMode(tf, SYS_TEXT_ITALICS, SYS_OFF);
vsy_TextFunFormTerm(tf, SYS_TEXT_ITEM);
vsy_TextFunFormInit(tf, SYS_TEXT_ITEM);
vsy_TextFunSetMode(tf, SYS_TEXT_TYPEWRITER, SYS_ON);
vsy_TextFunString(tf, "This is item 3 in a list in typewriter font");
vsy_TextFunSetMode(tf, SYS_TEXT_TYPEWRITER, SYS_OFF);
vsy_TextFunFormTerm(tf, SYS_TEXT_ITEM);
vsy_TextFunFormTerm(tf, SYS_TEXT_LIST);
/* table */
vsy_TextFunSetMode(tf, SYS_TEXT_CENTER, SYS_ON);
vsy_TextFunTableWidth(tf, 60);
vsy_TextFunBorderWidth(tf, 4);
vsy_TextFunFormInit(tf, SYS_TEXT_TABLE);
/* row 1 */
vsy_TextFunFormInit(tf, SYS_TEXT_ROW);
vsy_TextFunColumnAlign(tf, SYS_TEXT_LEFT);
vsy_TextFunTableColor(tf, red);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "Aligned left");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunColumnAlign(tf, SYS_TEXT_MIDDLE);
vsy_TextFunTableColor(tf, grn);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "Aligned middle");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunColumnAlign(tf, SYS_TEXT_RIGHT);
vsy_TextFunTableColor(tf, blu);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "Aligned right");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormTerm(tf, SYS_TEXT_ROW);
/* row 2 */
vsy_TextFunTableColor(tf, offwht);
vsy_TextFunFormInit(tf, SYS_TEXT_ROW);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 2 col 1");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 2 col 2");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 2 col 3");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormTerm(tf, SYS_TEXT_ROW);
/* row 3 */
vsy_TextFunTableColor(tf, altwht);
vsy_TextFunFormInit(tf, SYS_TEXT_ROW);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 3 col 1");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 3 col 2");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormInit(tf, SYS_TEXT_COLUMN);
vsy_TextFunSpace(tf, 3);
vsy_TextFunString(tf, "row 3 col 3");
vsy_TextFunSpace(tf, 3);
vsy_TextFunFormTerm(tf, SYS_TEXT_COLUMN);
vsy_TextFunFormTerm(tf, SYS_TEXT_ROW);
vsy_TextFunTableColor(tf, back);
vsy_TextFunFormTerm(tf, SYS_TEXT_TABLE);
/* image file */
vsy_TextFunFormAction(tf, SYS_TEXT_LINEBREAK);
vsy_TextFunImageFile(tf, (Vchar*)"../../vgl/exam/earth.gif");
vsy_TextFunSetMode(tf, SYS_TEXT_CENTER, SYS_OFF);
vsy_TextFunFormAction(tf, SYS_TEXT_LINEBREAK);
/* pre-formatted text */
vsy_TextFunHeadingLevel(tf, 2);
vsy_TextFunFormInit(tf, SYS_TEXT_HEADING);
vsy_TextFunString(tf, "Pre-formatted text");
vsy_TextFunFormTerm(tf, SYS_TEXT_HEADING);
vsy_TextFunSetMode(tf, SYS_TEXT_PREFORMATTED, SYS_ON);
vsy_TextFunString(tf, "j = 0;\n");
vsy_TextFunString(tf, "for(i = 0; i < 3; i++) {\n");
vsy_TextFunTextColor(tf, red);
vsy_TextFunString(tf, " j += i;\n");
vsy_TextFunTextColor(tf, blk);
vsy_TextFunString(tf, "}\n");
vsy_TextFunSetMode(tf, SYS_TEXT_PREFORMATTED, SYS_OFF);
/* close files */
vsy_TextFunCloseFile(tf);
/* delete objects */
vsy_HTMLTextEnd(htmltext);
vsy_PlainTextEnd(plaintext);
vsy_LaTeXTextEnd(latextext);
vsy_TextTeeEnd(texttee);
vsy_TextFunEnd(tf0);
vsy_TextFunEnd(tf1);
vsy_TextFunEnd(tf2);
vsy_TextFunEnd(tf);
return 0;
}
10.18. Example 17, Test and Demonstrate the LinkList object
This example illustrates using a LinkList object to manage a dynamic
data structure. A linked list is particularly suitable for data structures
in which fixed length records are being repeatedly created and deleted.
In this example double precision numbers
are the data to be stored in
each record of the linked list. The function vsy_LinkListDef()
is used
to specify the approximate number of records to be stored and the
length of each record - in this case sizeof(double).
The memory location to store each of the records is returned using
vsy_LinkListAdd()
. An integer index is assigned to each record.
The function vsy_LinkListRemove()
deletes a record associated with
the given index and moves it to the “free” list. This record now becomes
available for future calls to vsy_LinkListAdd()
. Use vsy_LinkListRef()
to return the pointer to the data associated with a given index.
The functions vsy_LinkListInitIter()
and vsy_LinkListNextIter()
are used
to visit each index and associated memory pointer.
The function vsy_LinkListClear()
will remove all records and move them
to the free list.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate LinkList
----------------------------------------------------------------------*/
int
main()
{
Vint index, i1, i2, i3, i4;
Vint num, nbytes, count;
vsy_LinkList* linklist;
Vdouble* d;
printf("\nLinkList test\n");
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance LinkList object */
linklist = vsy_LinkListBegin();
/* set initial allocation to four objects */
vsy_LinkListDef(linklist, 4, sizeof(Vdouble));
/* inquire and count */
vsy_LinkListInq(linklist, &num, &nbytes);
vsy_LinkListCount(linklist, &count);
printf("num = %d, nbytes= %d, count = %d\n", num, nbytes, count);
/* insert some double objects */
vsy_LinkListAdd(linklist, &i1, (Vobject**)&d);
*d = 1000.;
vsy_LinkListAdd(linklist, &i2, (Vobject**)&d);
*d = 2000.;
vsy_LinkListAdd(linklist, &i3, (Vobject**)&d);
*d = 3000.;
vsy_LinkListAdd(linklist, &i4, (Vobject**)&d);
*d = 4000.;
/* inquire and count */
vsy_LinkListInq(linklist, &num, &nbytes);
vsy_LinkListCount(linklist, &count);
printf("num = %d, nbytes= %d, count = %d\n", num, nbytes, count);
/* InitIter,NextIter traversal */
vsy_LinkListInitIter(linklist);
while (vsy_LinkListNextIter(linklist, &index, (Vobject**)&d), d != NULL) {
printf("index = %d, double = %e\n", index, *d);
}
/* remove a couple */
vsy_LinkListRemove(linklist, i1);
vsy_LinkListRemove(linklist, i2);
/* lookup */
vsy_LinkListRef(linklist, i3, (Vobject**)&d);
printf("index = %d, double = %e\n", i3, *d);
vsy_LinkListRef(linklist, i4, (Vobject**)&d);
printf("index = %d, double = %e\n", i4, *d);
/* now inquire and count */
vsy_LinkListInq(linklist, &num, &nbytes);
vsy_LinkListCount(linklist, &count);
printf("num = %d, nbytes= %d, count = %d\n", num, nbytes, count);
/* InitIter,NextIter traversal */
vsy_LinkListInitIter(linklist);
while (vsy_LinkListNextIter(linklist, &index, (Vobject**)&d), d != NULL) {
printf("index = %d, double = %e\n", index, *d);
}
/* clear */
vsy_LinkListClear(linklist);
/* inquire and count */
vsy_LinkListInq(linklist, &num, &nbytes);
vsy_LinkListCount(linklist, &count);
printf("num = %d, nbytes= %d, count = %d\n", num, nbytes, count);
/* delete object */
vsy_LinkListEnd(linklist);
return 0;
}
10.19. Example 18, Test and Demonstrate the ADTree object
This example illustrates using an ADTree object to perform geometric
searches.
An alternating digital tree may contain either discrete point entities
or geometric entities with extent, such as lines, triangles or tetrahedra.
This example illustrates both types of trees. First a point tree is
setup to contain 5 points within a unit cube. Each point is given
a user defined key and inserted using vsy_ADTreeInsertPoint()
.
Then a tolerance bound of .26 is specified and a point search is performed
for all entities which are contained within the coordinate extent of + or -
.26 centered about .5,.5.0.
The search in initiated and performed using vsy_ADTreeRefPointInit()
.
Each point entity contained with the specified extent about the input
point is returned using successive calls to vsy_ADTreeRefPointNext()
.
Then point 3 is removed using vsy_ADTreeRemove()
and the search is repeated.
The tolerance is changed to .36 and the searches are repeated with point
2 removed.
The tree is redefined to an extent tree using vsy_ADTreeDef()
and three
geometric entities defined by extent are inserted using
vsy_ADTreeInsertExtent()
. The function vsy_ADTreeDef()
will remove
any previous defined entities from the tree.
Then both a search about a point and a search within an extent are
performed. Any extent entity in the tree which overlaps the input
extent is returned by the search.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate ADTree
----------------------------------------------------------------------*/
int
main()
{
Vint key;
Vint nhits;
vsy_ADTree* adtree;
Vdouble xmin[3], xmax[3];
Vdouble x[3], tol;
Vdouble xn[3], xx[3];
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
printf("\nADTree test\n");
/* instance ADTree object */
adtree = vsy_ADTreeBegin();
/* set up POINT ADTree within unit square */
/* set initial allocation to five objects */
printf("\nPOINT ADTree\n");
xmin[0] = 0.;
xmin[1] = 0.;
xmin[2] = 0.;
xmax[0] = 1.;
xmax[1] = 1.;
xmax[2] = 1.;
vsy_ADTreeDef(adtree, ADTREE_POINT, xmin, xmax);
/* insert 5 points */
x[0] = .25;
x[1] = .75;
x[2] = 0.;
vsy_ADTreeInsertPoint(adtree, 1, x);
x[0] = .75;
x[1] = .75;
x[2] = 0.;
vsy_ADTreeInsertPoint(adtree, 2, x);
x[0] = .65;
x[1] = .65;
x[2] = 0.;
vsy_ADTreeInsertPoint(adtree, 3, x);
x[0] = .05;
x[1] = .65;
x[2] = 0.;
vsy_ADTreeInsertPoint(adtree, 4, x);
x[0] = .65;
x[1] = .15;
x[2] = 0.;
vsy_ADTreeInsertPoint(adtree, 5, x);
/* search with .26 tolerace box about point .5,.5 */
tol = .26;
vsy_ADTreeSetParamd(adtree, ADTREE_TOLERANCE, tol);
x[0] = .5;
x[1] = .5;
x[2] = 0.;
printf("search point= %f, %f, %f, tolerance= %f\n", x[0], x[1], x[2], tol);
vsy_ADTreeRefPointInit(adtree, x);
while (vsy_ADTreeRefPointNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* remove point 3 and search again */
printf("remove point 3\n");
vsy_ADTreeRemove(adtree, 3);
printf("search point= %f, %f, %f, tolerance= %f\n", x[0], x[1], x[2], tol);
vsy_ADTreeRefPointInit(adtree, x);
while (vsy_ADTreeRefPointNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* search */
tol = .36;
vsy_ADTreeSetParamd(adtree, ADTREE_TOLERANCE, tol);
printf("search point= %f, %f, %f, tolerance= %f\n", x[0], x[1], x[2], tol);
vsy_ADTreeRefPointInit(adtree, x);
while (vsy_ADTreeRefPointNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* remove and search */
printf("remove point 2\n");
vsy_ADTreeRemove(adtree, 2);
printf("search point= %f, %f, %f, tolerance= %f\n", x[0], x[1], x[2], tol);
vsy_ADTreeRefPointInit(adtree, x);
while (vsy_ADTreeRefPointNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* now do objects with EXTENT */
printf("\nEXTENT ADTree\n");
vsy_ADTreeDef(adtree, ADTREE_EXTENT, xmin, xmax);
/* insert 3 extent boxes */
xn[0] = .25;
xn[1] = .25;
xn[2] = 0.;
xx[0] = .5;
xx[1] = .5;
xx[2] = 0.;
vsy_ADTreeInsertExtent(adtree, 1, xn, xx);
xn[0] = .6;
xn[1] = .5;
xn[2] = 0.;
xx[0] = .7;
xx[1] = .8;
xx[2] = 0.;
vsy_ADTreeInsertExtent(adtree, 2, xn, xx);
xn[0] = .8;
xn[1] = .1;
xn[2] = 0.;
xx[0] = .9;
xx[1] = .9;
xx[2] = 0.;
vsy_ADTreeInsertExtent(adtree, 3, xn, xx);
/* point search */
x[0] = .5;
x[1] = .5;
x[2] = 0.;
tol = .1000;
vsy_ADTreeSetParamd(adtree, ADTREE_TOLERANCE, tol);
printf("search point= %f, %f, %f, tolerance= %f\n", x[0], x[1], x[2], tol);
vsy_ADTreeRefPointInit(adtree, x);
vsy_ADTreeGetInteger(adtree, ADTREE_NUMHITS, &nhits);
printf(" number of hits= %d\n", nhits);
while (vsy_ADTreeRefPointNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* extent search */
xn[0] = .6;
xn[1] = .55;
xn[2] = 0.;
xx[0] = .9;
xx[1] = .55;
xx[2] = 0.;
tol = .05;
printf("search extent, min= %f, %f, %f\n", xn[0], xn[1], xn[2]);
printf(" max= %f, %f, %f\n", xx[0], xx[1], xx[2]);
printf(" tolerance= %f\n", tol);
vsy_ADTreeSetParamd(adtree, ADTREE_TOLERANCE, tol);
vsy_ADTreeRefExtentInit(adtree, xn, xx);
vsy_ADTreeGetInteger(adtree, ADTREE_NUMHITS, &nhits);
printf(" number of hits= %d\n", nhits);
while (vsy_ADTreeRefExtentNext(adtree, &key), key) {
printf(" find key= %d\n", key);
}
/* delete object */
vsy_ADTreeEnd(adtree);
return 0;
}
10.20. Example 21, Purposefully left blank
10.21. Example 22, Test and Demonstrate the VSocket object
This example illustrates using a VSocket object to establish a TCP/IP communication socket between two processes, referred to as the server and the client. The socket requires that a hostname and a port number be specified.
The program shows how a server is made ready to accept client connections, and how the communication between client and server for each connection is made through a separate thread. The program spawns three other processes: two simple clients that send strings and numeric data to the server - main_client - and a client that instructs the server to shut itself down - main_stop.
Once the connection is defined with vsy_VSocketDef()
, and
then established with vsy_VSocketOpen()
, the server starts an infinite loop
where it attempts to establish new client connections with vsy_VSocketAccept()
.
Once a connection is
established memory is allocated from the heap to store information
associated with the connection and a thread is started to execute
the server function. This function exchanges messages with the client
using vsy_VSocketWriteString()
, vsy_VSocketWrite()
,
vsy_VSocketReadString()
, and vsy_VSocketRead()
. The string-specific
functions are an indication that character strings are being sent so the
data need not be swapped even if the binary representation of integers,
floats, and doubles is different between the server and the client. The
thread terminates whenever the client sends the bye command. When a stop
command is received by the server the
server breaks from the infinite loop and waits for the running threads to
terminate by using vsy_PTaskJoin()
. Once the thread terminates all heap data
associated with this connection is deallocated.
The main_client function sends commands to be displayed by the server who then sends an acknowledgement.
The main_stop function sends a single “stop” command to the server; once all clients terminate their communication with the server the server shuts itself down.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
#ifdef VKI_ARCH_WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#define BUFSIZE 256
static const Vchar* commands[2][5] = {{"client1", "int", "float", "double", "bye"}, {"client2", "int", "float", "double", "bye"}};
static Vint icval[2] = {27, -2};
static Vfloat fcval[2] = {-0.001f, 3.e-5f};
static Vdouble dcval[2] = {0.33, -2.56};
typedef struct {
vsy_VSocket* vsocket;
Vint cid;
Vchar firstbuf[BUFSIZE];
} exam22struct;
/* terminate thread */
static void
exam22term(exam22struct* inst)
{
free(inst);
}
static void
server(Vobject* obj)
{
exam22struct* inst = (exam22struct*)obj;
Vint size, iterm;
Vint ival, n;
Vfloat fval;
Vdouble dval;
Vchar buffer[BUFSIZE];
iterm = 0;
/* Infinite loop to receive commands from client */
for (n = 0;; ++n) {
/* Read first command from struct; otherwise, from socket */
if (n == 0) {
strcpy(buffer, inst->firstbuf);
}
else {
vsy_VSocketReadString(inst->vsocket, inst->cid, BUFSIZE, buffer, &size);
if (vsy_VSocketError(inst->vsocket))
return;
}
/* echo command */
printf("SERVER: client %d- %s", inst->cid, buffer);
/* Termination: set flag to quit later */
if (strstr(buffer, "bye")) {
iterm = 1;
/* int: read integer from socket and print */
}
else if (strstr(buffer, "int")) {
vsy_VSocketRead(inst->vsocket, inst->cid, sizeof(Vint), (Vchar*)&ival);
if (vsy_VSocketError(inst->vsocket))
return;
printf(" %d", ival);
/* float: read float from socket and print */
}
else if (strstr(buffer, "float")) {
vsy_VSocketRead(inst->vsocket, inst->cid, sizeof(Vfloat), (Vchar*)&fval);
if (vsy_VSocketError(inst->vsocket))
return;
printf(" %e", fval);
/* double: read double from socket and print */
}
else if (strstr(buffer, "double")) {
vsy_VSocketRead(inst->vsocket, inst->cid, sizeof(Vdouble), (Vchar*)&dval);
if (vsy_VSocketError(inst->vsocket))
return;
printf(" %e", dval);
}
printf("\n");
/* acknowledge receipt to client */
vsy_VSocketWriteString(inst->vsocket, inst->cid, (Vchar*)"ok");
if (vsy_VSocketError(inst->vsocket))
return;
/* bye: quit */
if (iterm == 1) {
vsy_VSocketClose(inst->vsocket, inst->cid);
break;
}
}
}
static void
main_server()
{
vsy_VSocket* vsocket;
vsy_List* list;
Vchar hostname[BUFSIZE], buffer[BUFSIZE];
Vint flag, cid, i, size;
exam22struct* inst;
/* Get info about this host */
vut_MachInfoHostName(&flag, hostname);
if (flag == 0) {
printf("SERVER: Unable to retrieve host name\n");
return;
}
/* Instance and set up VSocket */
vsocket = vsy_VSocketBegin();
vsy_VSocketSetParami(vsocket, VSOCKET_WAITTIME, 10);
vsy_VSocketSetParami(vsocket, VSOCKET_MAXCONNECTIONS, 1);
vsy_VSocketDef(vsocket, VSOCKET_SERVER, VSOCKET_NET);
vsy_VSocketSetNet(vsocket, 10000, hostname);
vsy_VSocketOpen(vsocket);
if (vsy_VSocketError(vsocket)) {
printf("SERVER: Unable to Open\n");
return;
}
/* Instance list to store client instances */
list = vsy_ListBegin();
for (i = 0; i < 5; ++i) {
vsy_VSocketAccept(vsocket, &cid);
if (cid == 0)
break;
vsy_VSocketReadString(vsocket, cid, BUFSIZE, buffer, &size);
/* check for stop server command */
if (strstr(buffer, "stop")) {
vsy_VSocketClose(vsocket, cid);
break;
}
/* establish new connection in thread */
inst = (exam22struct*)malloc(sizeof(exam22struct));
vsy_ListInsert(list, cid, (Vobject*)inst);
inst->vsocket = vsocket;
inst->cid = cid;
strcpy(inst->firstbuf, buffer);
server((Vobject*)inst);
}
/* Close connection and cleanup */
vsy_VSocketSetParami(vsocket, VSOCKET_WAITTIME, 1);
vsy_ListForEach(list, (Vfunc1*)exam22term);
vsy_VSocketClose(vsocket, 0);
vsy_ListEnd(list);
vsy_VSocketEnd(vsocket);
return;
}
static void
client(vsy_VSocket* vsocket, Vint id)
{
Vint iterm = 0, size = 0, n = 0;
Vchar buffer[BUFSIZE] = {0};
/* start command loop */
for (n = 0; n < 5; n++) {
/* send command to server */
vsy_VSocketWriteString(vsocket, 0, (Vchar*)commands[id - 1][n]);
if (vsy_VSocketError(vsocket))
return;
/* set termination flag */
if (strcmp(commands[id - 1][n], "bye") == 0) {
iterm = 1;
/* read and send int as binary */
}
else if (strcmp(commands[id - 1][n], "int") == 0) {
vsy_VSocketWrite(vsocket, 0, sizeof(Vint), (Vchar*)&icval[id - 1]);
if (vsy_VSocketError(vsocket))
return;
/* read and send float as binary */
}
else if (strcmp(commands[id - 1][n], "float") == 0) {
vsy_VSocketWrite(vsocket, 0, sizeof(Vfloat), (Vchar*)&fcval[id - 1]);
if (vsy_VSocketError(vsocket))
return;
/* read and send double as binary */
}
else if (strcmp(commands[id - 1][n], "double") == 0) {
vsy_VSocketWrite(vsocket, 0, sizeof(Vdouble), (Vchar*)&dcval[id - 1]);
if (vsy_VSocketError(vsocket))
return;
}
/* read receipt acknowledgement from server */
vsy_VSocketReadString(vsocket, 0, BUFSIZE, buffer, &size);
if (vsy_VSocketError(vsocket))
return;
if (strcmp(buffer, "ok") == 0) {
printf("CLIENT %d: ...information received by server from client\n", id);
}
/* terminate thread if "bye" */
if (iterm == 1)
break;
}
}
static void
main_client(Vint id)
{
vsy_VSocket* vsocket;
Vchar hostname[BUFSIZE];
Vint flag;
/* Get info about this host */
vut_MachInfoHostName(&flag, hostname);
if (flag == 0) {
printf("CLIENT %d: Unable to retrieve host name in client\n", id);
return;
}
/* Instance and set up VSocket */
vsocket = vsy_VSocketBegin();
vsy_VSocketSetParami(vsocket, VSOCKET_WAITTIME, 1000);
vsy_VSocketDef(vsocket, VSOCKET_CLIENT, VSOCKET_NET);
vsy_VSocketSetNet(vsocket, 10000, hostname);
vsy_VSocketOpen(vsocket);
if (vsy_VSocketError(vsocket)) {
vsy_VSocketEnd(vsocket);
return;
}
/* Exchange information with server */
client(vsocket, id);
/* Close connection and cleanup */
vsy_VSocketClose(vsocket, 0);
vsy_VSocketEnd(vsocket);
return;
}
static void
main_stop()
{
vsy_VSocket* vsocket;
Vchar hostname[BUFSIZE];
Vint flag;
/* Get info about this host */
vut_MachInfoHostName(&flag, hostname);
if (flag == 0) {
printf("STOP: Unable to retrieve host name\n");
return;
}
/* Instance and set up VSocket */
vsocket = vsy_VSocketBegin();
vsy_VSocketDef(vsocket, VSOCKET_CLIENT, VSOCKET_NET);
vsy_VSocketSetNet(vsocket, 10000, hostname);
vsy_VSocketOpen(vsocket);
/* Send command to server to stop itself */
printf("STOP: sending stop command to server\n");
vsy_VSocketWriteString(vsocket, 0, (Vchar*)"stop");
/* Close connection and cleanup */
vsy_VSocketClose(vsocket, 0);
vsy_VSocketEnd(vsocket);
return;
}
/*----------------------------------------------------------------------
Test and Demonstrate VSocket Object
Byte-swapping may need to be added for
heterogeneous machines with different
byte representation
----------------------------------------------------------------------*/
int
main(int argc, char* argv[])
{
Vchar sys[BUFSIZE];
Vint n;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
#ifdef VKI_ARCH_WIN32
STARTUPINFO si;
PROCESS_INFORMATION pi;
#endif
/* Check input */
if (argc == 1) {
for (n = 1; n <= 3; n++) {
#ifdef VKI_ARCH_WIN32
sprintf(sys, "%s %d", argv[0], n);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(NULL, sys, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
printf("SERVER: Unable to start child process %d\n", n);
exit(0);
}
#else
sprintf(sys, "%s %d &", argv[0], n);
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
#endif
system(sys);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif
}
main_server();
}
else if (argc == 2) {
sscanf(argv[1], "%d", &n);
if (n == 1 || n == 2) {
main_client(n);
}
else {
/* Wait 10 seconds before stopping server */
printf("SERVER: Waiting 10 seconds to launch stop server...\n");
#ifdef VKI_ARCH_WIN32
Sleep(10000);
#else
sleep(10);
#endif
main_stop();
}
}
return 0;
}
10.22. Example 23, Test and Demonstrate Quadruple Precision VQuad
This example illustrates the available methods to operate on quadruple
precision variables of type VQuad. Load and store operations are shown
using vut_VQuadLoad()
and vut_VQuadStore()
.
Comparison functions are demonstrated with
vut_VQuadEQ()
, vut_VQuadGE()
, vut_VQuadGT()
, vut_VQuadLE()
, and vut_VQuadLT()
.
All these functions return 1 for TRUE values or 0, for FALSE
values.
Basic arithmetic operations are shown with vut_VQuadAdd()
, vut_VQuadSub()
,
vut_VQuadMult()
, and vut_VQuadDiv()
. For convenience these functions’ return
value is the result of the arithmetic operation.
Unary operations are given by vut_VQuadAbs()
,
vut_VQuadHalf()
, vut_VQuadNeg()
, and vut_VQuadSqrt()
.
Three-component vector operations are shown with vut_VQuadMag3()
,
vut_VQuadDot3()
, vut_VQuadCross3()
, and vut_VQuadUnit3()
.
Finally, quadruple precision variables can be printed to a string with
vut_VQuadSPrintf()
.
#include <stdio.h>
#include <math.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and Demonstrate Quadruple Precision
----------------------------------------------------------------------*/
int
main()
{
Vdouble da, db;
Vquad qa, qb, qc, va[3], vb[3], vc[3];
Vint ierr;
Vchar bufa[256], bufb[256], bufc[256];
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* load and store operations */
da = 1.23;
db = -0.9;
printf("Double precision numbers:\n");
printf("da= %21.14e, db= %21.14e\n\n", da, db);
printf("sizeof(Vquad)= %d\n", (int)sizeof(Vquad));
qa = vut_VQuadLoad(da);
qb = vut_VQuadLoad(db);
vut_VQuadSPrintf(qa, 41, 1, bufa, &ierr);
vut_VQuadSPrintf(qb, 41, 1, bufb, &ierr);
printf("Quadruple precision numbers:\n");
printf("qa= %s, qb= %s\n\n", bufa, bufb);
printf("Double precision numbers:\n");
da = vut_VQuadStore(qa, &ierr);
db = vut_VQuadStore(qb, &ierr);
printf("da= %21.14e, db= %21.14e\n\n", da, db);
/* comparisons */
printf("Comparisons:\n");
if (vut_VQuadEQ(qa, qb)) {
printf("%s == %s\n", bufa, bufb);
}
else {
printf("%s != %s\n", bufa, bufb);
}
if (vut_VQuadGE(qa, qb)) {
printf("%s >= %s\n", bufa, bufb);
}
else {
printf("%s < %s\n", bufa, bufb);
}
if (vut_VQuadGT(qa, qb)) {
printf("%s > %s\n", bufa, bufb);
}
else {
printf("%s <= %s\n", bufa, bufb);
}
if (vut_VQuadLE(qa, qb)) {
printf("%s <= %s\n", bufa, bufb);
}
else {
printf("%s > %s\n", bufa, bufb);
}
if (vut_VQuadLT(qa, qb)) {
printf("%s < %s\n", bufa, bufb);
}
else {
printf("%s >= %s\n\n", bufa, bufb);
}
/* arithmetic operation */
printf("Arithmetic operations:\n");
qc = vut_VQuadSub(qa, qb, &ierr);
vut_VQuadSPrintf(qc, 41, 1, bufc, &ierr);
printf("%s - %s = %s\n", bufa, bufb, bufc);
qc = vut_VQuadMult(qa, qb, &ierr);
vut_VQuadSPrintf(qc, 41, 1, bufc, &ierr);
printf("%s * %s = %s\n", bufa, bufb, bufc);
qc = vut_VQuadDiv(qa, qb, &ierr);
vut_VQuadSPrintf(qc, 41, 1, bufc, &ierr);
printf("%s / %s = %s\n", bufa, bufb, bufc);
qa = vut_VQuadLoad(2.0);
vut_VQuadSPrintf(qa, 41, 1, bufa, &ierr);
qb = vut_VQuadSqrt(qa, &ierr);
vut_VQuadSPrintf(qb, 41, 1, bufb, &ierr);
printf("sqrt(%s) = %s\n", bufa, bufb);
qc = vut_VQuadMult(qb, qb, &ierr);
vut_VQuadSPrintf(qc, 41, 1, bufc, &ierr);
printf("%s * %s = %s\n\n", bufb, bufb, bufc);
qc = vut_VQuadNeg(qa);
vut_VQuadSPrintf(qc, 41, 1, bufc, &ierr);
printf("-(%s) = %s\n", bufa, bufc);
qa = vut_VQuadLoad(-2.0);
vut_VQuadSPrintf(qa, 41, 1, bufa, &ierr);
qb = vut_VQuadAbs(qc);
vut_VQuadSPrintf(qb, 41, 1, bufb, &ierr);
printf("abs(%s) = %s\n", bufc, bufb);
/* vector operation */
printf("Vector operations:\n");
va[0] = vut_VQuadLoad(0.);
va[1] = vut_VQuadLoad(3.);
va[2] = vut_VQuadLoad(4.);
vut_VQuadSPrintf(va[0], 41, 1, bufa, &ierr);
vut_VQuadSPrintf(va[1], 41, 1, bufb, &ierr);
vut_VQuadSPrintf(va[2], 41, 1, bufc, &ierr);
printf("va= %s\n %s\n %s\n", bufa, bufb, bufc);
vb[0] = vut_VQuadLoad(2.);
vb[1] = vut_VQuadLoad(3.);
vb[2] = vut_VQuadLoad(4.);
vut_VQuadSPrintf(vb[0], 41, 1, bufa, &ierr);
vut_VQuadSPrintf(vb[1], 41, 1, bufb, &ierr);
vut_VQuadSPrintf(vb[2], 41, 1, bufc, &ierr);
printf("va= %s\n %s\n %s\n", bufa, bufb, bufc);
qa = vut_VQuadDot3(va, va, &ierr);
vut_VQuadSPrintf(qa, 41, 1, bufa, &ierr);
printf("Dot3(va,va) = %s\n", bufa);
qa = vut_VQuadMag3(va, &ierr);
vut_VQuadSPrintf(qa, 41, 1, bufa, &ierr);
printf("Mag3(va) = %s\n", bufa);
vut_VQuadCross3(va, vb, vc, &ierr);
vut_VQuadSPrintf(vc[0], 41, 1, bufa, &ierr);
vut_VQuadSPrintf(vc[1], 41, 1, bufb, &ierr);
vut_VQuadSPrintf(vc[2], 41, 1, bufc, &ierr);
printf("va X vb = %s\n %s\n %s\n", bufa, bufb, bufc);
vut_VQuadUnit3(va, &ierr);
vut_VQuadSPrintf(va[0], 41, 1, bufa, &ierr);
vut_VQuadSPrintf(va[1], 41, 1, bufb, &ierr);
vut_VQuadSPrintf(va[2], 41, 1, bufc, &ierr);
printf("Unit3(va)= %s\n %s\n %s\n", bufa, bufb, bufc);
return 0;
}
10.23. Example 23cc, C++ Operator Overloading for Quadruple Precision VQuad
This example illustrates the overloading of basic arithmetic and comparison operations in C++. A new C++ class Vcquad is created and the basic methods are defined using the VQuad functions illustrated in Example 23. Once these operators are defined users can perform simple arithmetic calculations by treating a Vcquad variable just like a Vdouble or Vfloat, using the +, -, /, or * operators.
#include <stdio.h>
#include <math.h>
#include "sam/base/base.h"
class Vcquad {
public:
Vcquad(): a(vut_VQuadLoad(0.)) {}
Vcquad
operator=(Vdouble b);
Vcquad
operator+(Vcquad b);
Vcquad
operator-(Vcquad b);
Vcquad
operator-();
Vcquad
operator*(Vcquad b);
Vcquad
operator+=(Vcquad b);
Vcquad
operator-=(Vcquad b);
Vcquad
operator*=(Vcquad b);
Vcquad
operator/=(Vcquad b);
Vcquad
operator/(Vcquad b);
Vint
operator<(Vcquad b);
Vint
operator<=(Vcquad b);
Vint
operator>(Vcquad b);
Vint
operator>=(Vcquad b);
Vint
operator==(Vcquad b);
Vcquad
sqrt();
void
Printf();
private:
Vquad a;
};
Vcquad
Vcquad::operator=(Vdouble b)
{
Vcquad x;
a = vut_VQuadLoad(b);
return *this;
}
Vcquad
Vcquad::operator+(Vcquad b)
{
Vcquad x;
Vint ierr;
x.a = vut_VQuadAdd(a, b.a, &ierr);
return x;
}
Vcquad
Vcquad::operator-(Vcquad b)
{
Vcquad x;
Vint ierr;
x.a = vut_VQuadSub(a, b.a, &ierr);
return x;
}
Vcquad
Vcquad::operator-()
{
Vcquad x;
x.a = vut_VQuadNeg(a);
return x;
}
Vcquad
Vcquad::operator*(Vcquad b)
{
Vcquad x;
Vint ierr;
x.a = vut_VQuadMult(a, b.a, &ierr);
return x;
}
Vcquad
Vcquad::operator+=(Vcquad b)
{
Vint ierr;
a = vut_VQuadAdd(a, b.a, &ierr);
return *this;
}
Vcquad
Vcquad::operator-=(Vcquad b)
{
Vint ierr;
a = vut_VQuadSub(a, b.a, &ierr);
return *this;
}
Vcquad
Vcquad::operator*=(Vcquad b)
{
Vint ierr;
a = vut_VQuadMult(a, b.a, &ierr);
return *this;
}
Vcquad
Vcquad::operator/=(Vcquad b)
{
Vint ierr;
a = vut_VQuadDiv(a, b.a, &ierr);
return *this;
}
Vcquad
Vcquad::operator/(Vcquad b)
{
Vcquad x;
Vint ierr;
x.a = vut_VQuadDiv(a, b.a, &ierr);
return x;
}
Vint
Vcquad::operator<(Vcquad b)
{
return vut_VQuadLT(a, b.a);
}
Vint
Vcquad::operator>(Vcquad b)
{
return vut_VQuadGT(a, b.a);
}
Vint
Vcquad::operator>=(Vcquad b)
{
return vut_VQuadGE(a, b.a);
}
Vint
Vcquad::operator==(Vcquad b)
{
return vut_VQuadEQ(a, b.a);
}
Vcquad
Vcquad::sqrt()
{
Vcquad x;
Vint ierr;
x.a = vut_VQuadSqrt(a, &ierr);
return x;
}
void
Vcquad::Printf()
{
Vint ierr;
vut_VQuadPrintf(a, 41, 1, &ierr);
}
/*----------------------------------------------------------------------
C++ Operator Overloading for Quadruple Precision
----------------------------------------------------------------------*/
int
main()
{
Vcquad ca, cb, cc, v[3];
/* load and store operations */
ca = 1.23;
cb = 2.;
printf("ca = ");
ca.Printf();
printf("\n");
printf("cb = ");
cb.Printf();
printf("\n\n");
/* arithmetic operation */
cc = ca + cb;
printf("ca + cb = ");
cc.Printf();
printf("\n\n");
cc = ca - cb;
printf("ca - cb = ");
cc.Printf();
printf("\n\n");
cc = ca * cb;
printf("ca * cb = ");
cc.Printf();
printf("\n\n");
cc = ca / cb;
printf("ca / cb = ");
cc.Printf();
printf("\n\n");
cc = ca.sqrt();
printf("sqrt(ca)= ");
cc.Printf();
printf("\n\n");
cc = -ca;
printf("-ca= ");
cc.Printf();
printf("\n\n");
cc = ca;
cc += cb;
printf("ca + cb = ");
cc.Printf();
printf("\n\n");
cc = ca;
cc -= cb;
printf("ca - cb = ");
cc.Printf();
printf("\n\n");
cc = ca;
cc *= cb;
printf("ca * cb = ");
cc.Printf();
printf("\n\n");
cc = ca;
cc /= cb;
printf("ca / cb = ");
cc.Printf();
printf("\n\n");
/* comparisons */
if (ca < cb) {
printf("ca < cb\n");
}
else {
printf("ca >= cb\n");
}
if (cb < ca) {
printf("cb < ca\n");
}
else {
printf("cb >= ca\n");
}
if (ca == ca) {
printf("ca = ca\n");
}
/* vector operation */
v[0] = 3.;
v[1] = 4.;
v[2] = 5.;
cc = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
printf("v . v = ");
cc.Printf();
printf("\n\n");
return 0;
}
10.24. Example 24, Test and demonstrate Tree
This example demonstrates the use of the Tree module.
The Tree module is designed to hold pointers (CEETRON SAM type Vobject)
in a tree structure. Nodes are added to a parent node in
the tree using vsy_TreeAddNode()
. The parent node 0 specifically sets
the root node. A node index is returned by vsy_TreeAddNode()
, use
vsy_TreeSetValue()
to assign a pointer to the node index.
Trees lend themselves to recursive traversal. Use vsy_TreeFirstChild()
to initialize access to all children of a parent node, then
use vsy_TreeNextChild()
to access each child. A child node identifier
of zero is returned when all children have been accessed.
#include <stdio.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
static void
print_id(Vobject* obj)
{
Vint* val;
val = (Vint*)obj;
printf("parent= %d, value= %d\n", val[1], val[0]);
}
static void
print_tree(vsy_Tree* tree, Vint node)
{
Vobject* obj;
Vint child;
vsy_TreeGetValue(tree, node, &obj);
print_id(obj);
vsy_TreeFirstChild(tree, node, &child);
while (child != 0) {
print_tree(tree, child);
vsy_TreeNextChild(tree, child, &child);
}
}
/*----------------------------------------------------------------------
Test and demonstrate Tree
----------------------------------------------------------------------*/
int
main()
{
vsy_Tree* tree;
Vint root, c[3], child, g2_1, g2_2;
Vint value[1000][2];
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
tree = vsy_TreeBegin();
/* extract root node */
vsy_TreeAddNode(tree, 0, &root);
value[root][0] = root;
value[root][1] = 0;
vsy_TreeSetValue(tree, root, (Vobject*)&value[root]);
/* add 3 children to root */
vsy_TreeAddNode(tree, root, &c[0]);
value[c[0]][0] = c[0];
value[c[0]][1] = root;
vsy_TreeSetValue(tree, c[0], (Vobject*)&value[c[0]]);
vsy_TreeAddNode(tree, root, &c[1]);
value[c[1]][0] = c[1];
value[c[1]][1] = root;
vsy_TreeSetValue(tree, c[1], (Vobject*)&value[c[1]]);
vsy_TreeAddNode(tree, root, &c[2]);
value[c[2]][0] = c[2];
value[c[2]][1] = root;
vsy_TreeSetValue(tree, c[2], (Vobject*)&value[c[2]]);
/* add a child to c[2] */
vsy_TreeAddNode(tree, c[2], &child);
value[child][0] = child;
value[child][1] = c[2];
vsy_TreeSetValue(tree, child, (Vobject*)&value[child]);
/* add 2 grandchildren to c[2] */
vsy_TreeAddNode(tree, child, &g2_1);
value[g2_1][0] = g2_1;
value[g2_1][1] = child;
vsy_TreeSetValue(tree, g2_1, (Vobject*)&value[g2_1]);
vsy_TreeAddNode(tree, child, &g2_2);
value[g2_2][0] = g2_2;
value[g2_2][1] = child;
vsy_TreeSetValue(tree, g2_2, (Vobject*)&value[g2_2]);
/* list all children recursively */
printf("Tree after all insertions:\n");
vsy_TreeForEach(tree, print_id);
/* remove one node */
vsy_TreeDelNode(tree, child);
/* list all children recursively */
printf("\nTree after removing node %d:\n", child);
print_tree(tree, root);
/* re-insert a child to c[2] */
vsy_TreeAddNode(tree, c[2], &child);
value[child][0] = child;
value[child][1] = c[2];
vsy_TreeSetValue(tree, child, (Vobject*)&value[child]);
/* re-insert 2 grandchildren to c[2] */
vsy_TreeAddNode(tree, child, &g2_1);
value[g2_1][0] = g2_1;
value[g2_1][1] = child;
vsy_TreeSetValue(tree, g2_1, (Vobject*)&value[g2_1]);
vsy_TreeAddNode(tree, child, &g2_2);
value[g2_2][0] = g2_2;
value[g2_2][1] = child;
vsy_TreeSetValue(tree, g2_2, (Vobject*)&value[g2_2]);
printf("\nTree after reinsertion of children:\n");
vsy_TreeForEach(tree, print_id);
vsy_TreeEnd(tree);
return 0;
}
10.25. Example 25, Test and demonstrate Pred
This example demonstrates the use of the Pred module to accurately determine whether triangles and tetrahedra are proper, degenerate, or inverted; and whether a point lies inside, outside, or on a circle defined by three points or a sphere defined by four points.
#include <stdio.h>
#include <math.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate Pred
----------------------------------------------------------------------*/
int
main()
{
Vdouble x[4][3], e[3], xt[3][3], xl[2][3], xl0[2][2], xl1[2][2];
vsy_Pred* pred;
Vdouble retval;
Vint pass;
Vint code, ient, ierr;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
/* instance object */
pred = vsy_PredBegin();
/* push FPU control words */
vsy_PredPushFPU(pred);
/* check to see if Pred is exact */
vsy_PredExact(pred, &pass);
if (pass == 0) {
printf("Pred is unable to do exact arithmetic, check compiler options\n");
}
else {
printf("Pred is able to do exact arithmetic\n");
}
/* set tetrahedron vertices for right tetrahedron */
/* first node at origin */
x[0][0] = 0.;
x[0][1] = 0.;
x[0][2] = 0.;
/* second node on x-axis */
x[1][0] = 1.;
x[1][1] = 0.;
x[1][2] = 0.;
/* third node on y-axis */
x[2][0] = 0.;
x[2][1] = 1.;
x[2][2] = 0.;
/* fourth node on z-axis */
x[3][0] = 0.;
x[3][1] = 0.;
x[3][2] = 1.;
/* test point for insphere */
e[0] = 20.;
e[1] = .25;
e[2] = .25;
retval = vsy_PredInsphere(pred, x[0], x[1], x[2], x[3], e);
printf("Point outside sphere: retval= %e\n", retval);
e[0] = .2;
e[1] = .25;
e[2] = .25;
retval = vsy_PredInsphere(pred, x[0], x[1], x[2], x[3], e);
printf("Point inside sphere: retval= %e\n", retval);
e[0] = 0.;
e[1] = 0.;
e[2] = 0.;
retval = vsy_PredInsphere(pred, x[0], x[1], x[2], x[3], e);
printf("Point on sphere: retval= %e\n", retval);
/* compute orientation */
/* return value should be positive */
retval = vsy_PredOrient3d(pred, x[0], x[1], x[2], x[3]);
printf("Proper tetrahedron: retval= %e\n", retval);
/* move second point close to plane of 1,3 and 4th points */
/* return value should be positive */
x[1][0] = 1.e-100;
x[1][1] = 0.5;
x[1][2] = 0.5;
retval = vsy_PredOrient3d(pred, x[0], x[1], x[2], x[3]);
printf("Proper tetrahedron: retval= %e\n", retval);
/* move second point to plane of 1,3 and 4th points */
/* return value should be zero */
x[1][0] = 0.;
x[1][1] = 0.5;
x[1][2] = 0.5;
retval = vsy_PredOrient3d(pred, x[0], x[1], x[2], x[3]);
printf("Degenerate tetrahedron: retval= %e\n", retval);
/* move second point beyond plane of 1,3 and 4th points */
/* return value should be negative */
x[1][0] = -1.e-100;
x[1][1] = 0.5;
x[1][2] = 0.5;
retval = vsy_PredOrient3d(pred, x[0], x[1], x[2], x[3]);
printf("Inverted tetrahedron: retval= %e\n", retval);
/* compute line tri intersection status */
xt[0][0] = 0.;
xt[0][1] = 0.;
xt[0][2] = 0.;
/* second node on x-axis */
xt[1][0] = 1.;
xt[1][1] = 0.;
xt[1][2] = 0.;
/* third node on y-axis */
xt[2][0] = 0.;
xt[2][1] = 1.;
xt[2][2] = 0.;
/* line endpoints */
xl[0][0] = -1.;
xl[0][1] = 0.;
xl[0][2] = 0.;
xl[1][0] = 0.;
xl[1][1] = 2.;
xl[1][2] = 0.;
vsy_PredIntersectLineTri(pred, xt, xl, &code, &ient, &ierr);
printf("Line Tri no intersection, code= %d\n", code);
/* line end point in triangle interior */
xl[1][0] = .25;
xl[1][1] = .25;
xl[1][2] = 0.;
vsy_PredIntersectLineTri(pred, xt, xl, &code, &ient, &ierr);
printf("Line Tri coplanar intersection, code= %d\n", code);
/* line spans triangle */
xl[1][0] = .75;
xl[1][1] = .75;
xl[1][2] = 0.;
vsy_PredIntersectLineTri(pred, xt, xl, &code, &ient, &ierr);
printf("Line Tri coplanar intersection, code= %d\n", code);
/* two-dimension tests */
/* set circle points */
x[0][0] = -1.;
x[0][1] = 0.;
x[1][0] = 1.;
x[1][1] = 0.;
x[2][0] = 0.;
x[2][1] = 1.;
/* check point inside circle */
e[0] = 0.;
e[1] = 0.;
retval = vsy_PredIncircle(pred, x[0], x[1], x[2], e);
printf("Point inside circle: retval= %e\n", retval);
/* check point outside circle */
e[0] = 2.;
e[1] = 0.;
retval = vsy_PredIncircle(pred, x[0], x[1], x[2], e);
printf("Point outside circle: retval= %e\n", retval);
/* check point on circle */
e[0] = 0.;
e[1] = -1.;
retval = vsy_PredIncircle(pred, x[0], x[1], x[2], e);
printf("Point on circle: retval= %e\n", retval);
/* check properly defined triangle */
x[0][0] = 0.;
x[0][1] = 0.;
x[1][0] = 1.;
x[1][1] = 0.;
x[2][0] = 0.;
x[2][1] = 1.;
retval = vsy_PredOrient2d(pred, x[0], x[1], x[2]);
printf("Proper triangle: retval= %e\n", retval);
/* check degenerate triangle */
x[0][0] = 0.;
x[0][1] = 0.;
x[1][0] = 1.;
x[1][1] = 0.;
x[2][0] = 0.5;
x[2][1] = 0.;
retval = vsy_PredOrient2d(pred, x[0], x[1], x[2]);
printf("Degenerate triangle: retval= %e\n", retval);
/* check inverted triangle */
x[0][0] = 0.;
x[0][1] = 0.;
x[1][0] = 1.;
x[1][1] = 0.;
x[2][0] = 0.;
x[2][1] = -1.;
retval = vsy_PredOrient2d(pred, x[0], x[1], x[2]);
printf("Inverted triangle: retval= %e\n", retval);
/* compute line line intersection status */
xl0[0][0] = 0.;
xl0[0][1] = 0.;
xl0[1][0] = 1.;
xl0[1][1] = 0.;
xl1[0][0] = -1.;
xl1[0][1] = 0.;
xl1[1][0] = 2.;
xl1[1][1] = 0.;
vsy_PredIntersectLineLine(pred, xl0, xl1, &code, &ient, &ierr);
printf("Line Line intersection, code= %d, ient= %d\n", code, ient);
/* pop (restore) FPU control words */
vsy_PredPopFPU(pred);
vsy_PredEnd(pred);
return 0;
}
10.26. Example 26, Test and demonstrate StrUtil
This example demonstrates the use of the StrUtil module to convert wide character strings to UTF-8 encoding and back again.
#include <stdio.h>
#include <wchar.h>
#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/CEETRON_SAM_license.h"
/*----------------------------------------------------------------------
Test and demonstrate StrUtil
----------------------------------------------------------------------*/
int
main()
{
wchar_t euro[] = {L'U', L'n', L'i', L'c', L'o', L'd', L'e', L' ', L'E', L'u', L'r', L'o', L'=', L' ', 0x20ac, L'\0'};
Vchar str[256];
wchar_t wstr[256];
Vint numchar;
vsy_LicenseValidate(CEETRON_SAM_LICENSE);
printf("\nStrUtil test\n");
/* convert wide char to utf8 */
vut_StrUtilToUTF8(euro, 256, str);
numchar = vut_StrUtilLenUTF8(str);
printf("number of characters= %d\n", numchar);
printf("%s\n", str);
/* convert back to wide char */
vut_StrUtilFromUTF8(str, 256, wstr);
/* test */
if (wcscmp(wstr, euro)) {
printf("string comparison fails\n");
}
else {
printf("string comparison succeeds\n");
}
return 0;
}