OpenVMS Source Code Demos
basic_calling_c_demo2_part2
//========================================================================================
// title : basic_calling_c_demo2_part2.c
// author : Neil Rieck (https://neilrieck.net) (mailto:n.rieck@bell.net)
// notes : 1) This file contains code for two functions which will be called from BASIC.
// This means there is no main() or transfer address to call from a CLI
// 2) VMS-BASIC-1.7 up-cases everything written to the symbol table. This means
// all C symbols must be up-cased as well. This is done by actually using
// upper case or compiling with C with switch /NAMES=(UPPERCASE,TRUNCATED)
// history:
// ver who when what
// --- --- -------- ----------------------------------------------------------------------
// 100 NSR 20141110 original effort
// NSR 20141111 added function basic_calling_c_demo_c7 to test malloc()
// NSR 20170823 tweaked one of the printf formatters
//========================================================================================
#define __NEW_STARLET 1 // enable strict starlet (>= OpenVMS70)
#include <stdio.h> //
#include <stdlib.h> //
#include <string.h> //
#include <descrip.h> // for VMS string descriptors
//
//==============================================================================
// function: basic_calling_c_demo_c5
// what : pass an array of strings from BASIC to C (for r/o processing)
// BASIC declaration:
// external long function basic_calling_c_demo_c5( &
// long by ref, &
// string dim() by ref )
//==============================================================================
long basic_calling_c_demo_c5( long *p1 ,
struct dsc$descriptor_s *p2 ) {
//
// function begins
//
printf("c function: basic_calling_c_demo_c5\n");
//
// display p1 and make sure it is greater than zero
//
printf("-i-p1 = %d\n", *p1); // display p1 (number of elements)
if (*p1==0) {
printf("-e-error, p1 not greater than zero\n");
return(0); // -w-
}
if (*p1<0) {
printf("-e-error, p1 not positive\n");
return(0); // -w-
}
//
// display array strings
//
for (char i=0; i<*p1; i++) { // scan the array of descriptors
printf("-i-p2 (%d) address : %p\n", i, p2); // address of this descriptor hacking
printf("-i-p2 (%d) length : %d\n", i, p2->dsc$w_length); // data: which is a length hacking
printf("-i-p2 (%d) address2: %p\n", i, p2->dsc$a_pointer); // data: which is an address hacking
printf("-i-p2 (%d) data : ",i); //
if ((p2->dsc$w_length>0) && // if not zero-length
(p2->dsc$a_pointer!=0)) { // and some memory was assigned
fwrite(p2->dsc$a_pointer,1,p2->dsc$w_length,stdout);
}
printf("\n"); // EOL
p2++; // advance pointer
}
//
return (1); // -s-
}
//==============================================================================
// function: basic_calling_c_demo_c6
// what : pass an array of pre-extended strings from BASIC to C,
// assign data to the strings in C, then pass back to BASIC
// BASIC declaration:
// external long function basic_calling_c_demo_c6( &
// string by desc, &
// string by desc, &
// long by ref, &
// string dim() by ref, &
// long dim() by ref )
//==============================================================================
long basic_calling_c_demo_c6( struct dsc$descriptor_s *p1 ,
struct dsc$descriptor_s *p2 ,
long *p3 ,
struct dsc$descriptor_s *p4 ,
long *p5 ) {
char test0[] = "apple";
char test1[] = "orange";
char test2[] = "pear";
char test3[] = "this string is longer";
char test4[] = "this string is a little longer";
//
// function begins
//
printf("c function: basic_calling_c_demo_c6\n");
//
// display p3 and make sure it is greater than zero
//
printf("-i-p3 = %d\n", *p3); // display p3 (number of elements available)
if (*p3==0) {
printf("-e-error, p3 not greater than zero\n");
return(0); // -w-
}
if (*p3<0) {
printf("-e-error, p3 not positive\n");
return(0); // -w-
}
//
// store data in the array of pre-extended strings
//
for (char i=0; i<*p3; i++) { // scan the array of descriptors
long junk;
if (i==0) { //
junk = strlen(test0); // measure proposed data length
if (p4->dsc$w_length >= junk) { // if room exists...
sprintf(p4->dsc$a_pointer,"%s",test0); // ...then store here
*p5 = junk; // save data length here
}else{ //
printf("-e-no room to store string %d\n",i);
*p5 = 0; // signal "no data here"
}
}
if (i==1) { //
junk = strlen(test1); //
if (p4->dsc$w_length >= junk) { //
sprintf(p4->dsc$a_pointer,"%s",test1); //
*p5 = junk; //
}else{ //
printf("-e-no room to store string %d\n",i);
*p5 = 0; // signal "no data here"
} //
}
if (i==2) { //
junk = strlen(test2); //
if (p4->dsc$w_length >= junk) { //
sprintf(p4->dsc$a_pointer,"%s",test2); //
*p5 = junk; //
}else{ //
printf("-e-no room to store string %d\n",i);
*p5 = 0; // signal "no data here"
} //
}
if (i==3) { //
junk = strlen(test3); //
if (p4->dsc$w_length >= junk) { //
sprintf(p4->dsc$a_pointer,"%s",test3); //
*p5 = junk; //
}else{ //
printf("-e-no room to store string %d\n",i);
*p5 = 0; // signal "no data here"
} //
} //
if (i==4) { //
junk = strlen(test4); //
if (p4->dsc$w_length >= junk) { //
sprintf(p4->dsc$a_pointer,"%s",test4); //
*p5 = junk; //
}else{ //
printf("-e-no room to store string %d\n",i);
*p5 = 0; // signal "no data here"
} //
} //
p4++; // advance pointer for next pass
p5++; // ditto
} //
//
return (1); // -s-
}
//==============================================================================
// function: basic_calling_c_demo_c7
// what : pass an array of null strings from BASIC to C,
// assign data to the strings, then pass back to BASIC
// BASIC declaration:
// external long function basic_calling_c_demo_c6( &
// string by desc, &
// string by desc, &
// long by ref, &
// string dim() by ref)
//==============================================================================
long basic_calling_c_demo_c7( struct dsc$descriptor_s *p1 ,
struct dsc$descriptor_s *p2 ,
long *p3 ,
struct dsc$descriptor_s *p4 ) {
char test0[] = "apple";
char test1[] = "orange";
char test2[] = "pear";
char test3[] = "this string is longer";
char test4[] = "this string is a little longer";
//
// function begins
//
printf("c function: basic_calling_c_demo_c7\n");
//
// display p3 and make sure it is greater than zero
//
printf("-i-p3 = %d\n", *p3); // display p3 (number of elements available)
if (*p3==0) {
printf("-e-error, p3 not greater than zero\n");
return(0); // -w-
}
if (*p3<0) {
printf("-e-error, p3 not positive\n");
return(0); // -w-
}
//
// store data in the array of pre-extended strings
//
for (char i=0; i<*p3; i++) { // scan the array of descriptors
long junk;
if (i==0) {
junk = strlen(test0); // measure the length
p4->dsc$a_pointer = malloc(junk+1); // allocate some memory
if (p4->dsc$a_pointer!=0) { // if memory was allocated then
p4->dsc$w_length = junk; // ...save amount here
strncpy(p4->dsc$a_pointer,test0,junk); // ...save data
} else { //
p4->dsc$w_length = 0; //
printf("-e-malloc at iteration %d\n",i); //
}
}
if (i==1) {
junk = strlen(test1); // measure the length
p4->dsc$a_pointer = malloc(junk+1); //
if (p4->dsc$a_pointer!=0) {
p4->dsc$w_length = junk; //
strncpy(p4->dsc$a_pointer,test1,junk); //
} else { //
p4->dsc$w_length = 0;
printf("-e-malloc at iteration %d\n",i); //
}
}
if (i==2) {
junk = strlen(test2); // measure the length
p4->dsc$a_pointer = malloc(junk+1); //
if (p4->dsc$a_pointer!=0) {
p4->dsc$w_length = junk; //
strncpy(p4->dsc$a_pointer,test2,junk); //
} else { //
p4->dsc$w_length = 0;
printf("-e-malloc at iteration %d\n",i); //
}
}
if (i==3) {
junk = strlen(test3); // measure the length
p4->dsc$a_pointer = malloc(junk+1); //
if (p4->dsc$a_pointer!=0) {
p4->dsc$w_length = junk; //
strncpy(p4->dsc$a_pointer,test3,junk); //
} else { //
p4->dsc$w_length = 0;
printf("-e-malloc at iteration %d\n",i); //
}
}
if (i==4) {
junk = strlen(test4); // measure the length
p4->dsc$a_pointer = malloc(junk+1); //
if (p4->dsc$a_pointer!=0) {
p4->dsc$w_length = junk; //
strncpy(p4->dsc$a_pointer,test4,junk); //
} else { //
p4->dsc$w_length = 0;
printf("-e-malloc at iteration %d\n",i); //
}
}
p4++; // advance pointer
}
//
return (1); // -s-
}
Back to
Home
Neil Rieck
Waterloo, Ontario, Canada.