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-
}

home Back to Home
Neil Rieck
Waterloo, Ontario, Canada.