.. index:: 
	single: Tutorial: Ring Extensions in C/C++; Tutorial: Ring Extensions in C/C++

==================================
Tutorial: Ring Extensions in C/C++
==================================

In this chapter we will see simple examples about using C code in Ring programs

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Hello World

Hello World
===========

Sample : ring/extensions/tutorial/helloworld

The file mylib.c contains

.. code-block:: c

	#include "ring.h"

	#include "stdlib.h"

	RING_FUNC(ring_myfunction)
	{	
		printf("Hello, World!");
	}

	RING_API void ringlib_init(RingState *pRingState)
	{
		ring_vm_funcregister("myfunction",ring_myfunction);
	}

As we see in the source code, we start with including the ring.h file which contains the definitions for Ring API

Then we use the RING_FUNC macro to define new functions, it's a good idea to start the function definition with ring_ to make these definitions unique and different than normal C functions

Then we have the function ringlib_init that will be called when the extension is loaded by the Ring VM

In this function we use the ring_vm_funcregister() function to register the new functions in Ring VM

Then we build the extension using :

buildvc.bat

The file buildvc.bat contains the next commands to build the extension using Visual C/C++


.. code-block:: none

	cls
	call ../../../src/locatevc.bat
	cl /c /DEBUG mylib.c -I"..\..\..\include"
	link /DEBUG mylib.obj  ..\..\..\lib\ring.lib /DLL /OUT:mylib.dll /SUBSYSTEM:CONSOLE,"5.01" 
	del mylib.obj

Then we test the function using

.. code-block:: none

	ring test.ring

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	loadlib("mylib.dll")

	? "Calling a C Function"
	myfunction()

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Build the extension on different platforms

Build the extension on different platforms
==========================================

Sample : ring/extensions/tutorial/helloworld2

This extension is the same as the first one but in this time, we support Windows, Linux and macOS.

We will use the next files

.. code-block:: none

	buildvc.bat
	buildgcc.sh
	buildclang.sh

Where we use buildvc.bat in Windows, buildgcc.sh in Linux and buildclang.sh in macOS

The file buildgcc.sh contains the next commands

.. code-block:: none

	gcc -c -fpic mylib.c -I $PWD/../../../include 
	gcc -shared -o libmylib.so mylib.o -L $PWD/../../../lib -lring
	sudo cp libmylib.so /usr/lib
	sudo cp libmylib.so /usr/lib64

The file buildclang.sh contains 

.. code-block:: none

	clang -c -fpic mylib.c -I $PWD/../../../include
	clang -dynamiclib -o libmylib.dylib mylib.o  -L $PWD/../../../lib  -lring
	cp libmylib.dylib /usr/local/lib

This time we use mylib.ring instead of using LoadLib() function directly

In mylib.ring we have the next code

.. code-block:: ring

	if iswindows()
		LoadLib("mylib.dll")
	but ismacosx()
		LoadLib("libmylib.dylib")
	else
		LoadLib("libmylib.so")
	ok

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Sum Two Numbers

Sum Two Numbers
===============

Sample : ring/extensions/tutorial/sumtwonumbers

In this extension we learn how to create a C function to sum two numbers

This extension is an update to the (Hello World 2) extension in : ring/extensions/tutorial/helloworld2 folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_sumtwonumbers)
	{
		double nNum1,nNum2,nSum;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! (RING_API_ISNUMBER(1) && RING_API_ISNUMBER(2)) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Sum Numbers 
			nNum1 = RING_API_GETNUMBER(1);
			nNum2 = RING_API_GETNUMBER(2);
			nSum  = nNum1 + nNum2 ;
		// Return Output
			RING_API_RETNUMBER(nSum);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("sumtwonumbers",ring_sumtwonumbers);

The previous code is written to check errors, and to be easy to understand

We can write short code like

.. code-block:: c

		RING_API_RETNUMBER(RING_API_GETNUMBER(1) + RING_API_GETNUMBER(2));

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8


.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Say Hello

Say Hello
=========

Sample : ring/extensions/tutorial/sayhello

In this extension we learn how to create a C function that get a name as string then say hello.

This extension is an update to the (sumtwonumbers) extension in : ring/extensions/tutorial/sumtwonumbers folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_sayhello)
	{
		// Check Parameters Count
			if (RING_API_PARACOUNT != 1) {
				RING_API_ERROR(RING_API_MISS1PARA);
				return;
			}
		// Check Parameters Type
			if ( ! RING_API_ISSTRING(1) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		printf("Hello %s\n",RING_API_GETSTRING(1));
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("sayhello",ring_sayhello);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud


.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Sum List of Numbers

Sum List of Numbers
===================

Sample : ring/extensions/tutorial/sumlist

In this extension we learn how to create a C function that sum list of numbers.

This extension is an update to the (sayhello) extension in : ring/extensions/tutorial/sayhello folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_sumlist)
	{
		List *pList;
		int x,nSum;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 1) {
				RING_API_ERROR(RING_API_MISS1PARA);
				return;
			}
		// Check Parameters Type
			if ( ! RING_API_ISLIST(1) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Sum List Numbers 
			nSum = 0;
			pList = RING_API_GETLIST(1);
			for(x=1 ; x <= ring_list_getsize(pList) ; x++) {
				if ( ring_list_isdouble(pList,x) ) {
					nSum += (int) ring_list_getdouble(pList,x) ;
				}
			}
		// Return Output 
			RING_API_RETNUMBER(nSum);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("sumlist",ring_sumlist);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55


.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Increment List Items

Increment List Items
====================

Sample : ring/extensions/tutorial/incrementlist

In this extension we learn how to create a C function that increment the list items.

This extension is an update to the (sumlist) extension in : ring/extensions/tutorial/sumlist folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_inclist)
	{
		List *pList;
		int x,nSum;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Increment List Items
			nSum = 0;
			pList = RING_API_GETLIST(1);
			for(x=1 ; x <= ring_list_getsize(pList) ; x++) {
				if ( ring_list_isdouble(pList,x) ) {
					ring_list_setdouble(pList,x,
						ring_list_getdouble(pList,x)+
						RING_API_GETNUMBER(2)) ;
				}	
			}
		// Return Output
			RING_API_RETLIST(pList);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("inclist",ring_inclist);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: ring

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Filter List Items

Filter List Items
=================

Sample : ring/extensions/tutorial/filterlist

In this extension we learn how to create a C function that filter the list items.

This extension is an update to the (incrementlist) extension in : ring/extensions/tutorial/incrementlist folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_filterlist)
	{
		List *pList;
		int x;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Filter List Items
			pList = RING_API_GETLIST(1);
			for(x = ring_list_getsize(pList) ; x >= 1 ; x--) 
				if ( ring_list_isdouble(pList,x) ) 
					if ( ! (ring_list_getdouble(pList,x) >
							 RING_API_GETNUMBER(2)) )
						ring_list_deleteitem(pList,x) ;
		// Return Output
			RING_API_RETLIST(pList);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("filterlist",ring_filterlist);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Replicate List Items

Replicate List Items
====================

Sample : ring/extensions/tutorial/replicatelist

In this extension we learn how to create a C function that add more items to the list.

This extension is an update to the (filterlist) extension in : ring/extensions/tutorial/filterlist folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_replicatelist)
	{
		List *pList;
		int x,y,nTimes,nSize;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Replicate List Items
			pList = RING_API_GETLIST(1);
			nSize = ring_list_getsize(pList);
			nTimes = (int) RING_API_GETNUMBER(2);
			if (nTimes < 1) {
				RING_API_ERROR("Error: The second parameter must be >= 1 \n");
				return;
			}
			for(x = 1 ; x <= nTimes ; x++) 
				for(y = 1 ; y <= nSize ; y++) 
					if ( ring_list_isdouble(pList,y) ) 
						ring_list_adddouble(pList,
							ring_list_getdouble(pList,y));
		// Return Output
			RING_API_RETLIST(pList);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("replicatelist",ring_replicatelist);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

	aList = 1:3
	? "Replicate list (1:3) three times then print the items (We expect 12 items)"
	? replicatelist(aList,3)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

	Replicate list (1:3) three times then print the items (We expect 12 items)
	1
	2
	3
	1
	2
	3
	1
	2
	3
	1
	2
	3

	
.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Generate List

Generate List
=============

Sample : ring/extensions/tutorial/generatelist

In this extension we learn how to create a C function that create new list and add items to the list.

This extension is an update to the (replicatelist) extension in : ring/extensions/tutorial/replicatelist folder

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_generatelist)
	{
		List *pList;
		int x,nSize;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 1) {
				RING_API_ERROR(RING_API_MISS1PARA);
				return;
			}
		// Check Parameters Type
			if ( ! RING_API_ISNUMBER(1) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Create the List
			pList = RING_API_NEWLIST;
		// Generate List Items
			nSize = (int) RING_API_GETNUMBER(1);
			if (nSize < 1) {
				RING_API_ERROR("Error: The list size must be >= 1 \n");
				return;
			}
			for(x = 1 ; x <= nSize ; x++) 
				ring_list_adddouble(pList,(double) x);
		// Return Output
			RING_API_RETLIST(pList);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("generatelist",ring_generatelist);

The file test.ring contains

.. code-block:: ring

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

	aList = 1:3
	? "Replicate list (1:3) three times then print the items (We expect 12 items)"
	? replicatelist(aList,3)

	? "Create list contains 5 items using C code"
	aList = GenerateList(5)
	? aList

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

	Replicate list (1:3) three times then print the items (We expect 12 items)
	1
	2
	3
	1
	2
	3
	1
	2
	3
	1
	2
	3

	Create list contains 5 items using C code
	1
	2
	3
	4
	5

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Display List

Display List
============

Sample : ring/extensions/tutorial/displaylist

In this extension we learn how to create a C function that display all of the list items including nested lists

In mylib.c we update the file to add

.. code-block:: c

	void mylib_displaylist(List *pList);

	RING_FUNC(ring_displaylist)
	{
		List *pList;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 1) {
				RING_API_ERROR(RING_API_MISS1PARA);
				return;
			}
		// Check Parameters Type
			if ( ! RING_API_ISLIST(1) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Get the List
			pList = RING_API_GETLIST(1);
		// Display the List Items including Nested Lists
			mylib_displaylist(pList);
	}

	void mylib_displaylist(List *pList) {
		int x;
		for (x=1; x <= ring_list_getsize(pList); x++) {
			if ( ring_list_isdouble(pList,x) ) {
				printf("Number : %f \n", ring_list_getdouble(pList,x) ) ;
			} else if ( ring_list_isstring(pList,x) ) {
				printf("String : %s \n", ring_list_getstring(pList,x) ) ;
			} else if ( ring_list_islist(pList,x) ) {
				printf("Sub List..\n");
				mylib_displaylist( ring_list_getlist(pList,x) );		
			}
		}
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("displaylist",ring_displaylist);

The file test.ring contains

.. code-block:: ring

	load "stdlib.ring"

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

	aList = 1:3
	? "Replicate list (1:3) three times then print the items (We expect 12 items)"
	? replicatelist(aList,3)

	? "Create list contains 5 items using C code"
	aList = GenerateList(5)
	? aList

	? "Create List (3,2)"
	aList = newList(3,2)
	aList[1][1] = "R 1 C 1"
	aList[1][2] = "R 1 C 2"
	aList[2][1] = "R 2 C 1"
	aList[2][2] = "R 2 C 2"
	aList[3][1] = "R 3 C 1"
	aList[3][2] = "R 3 C 2"
	? "Print the List using Ring"
	? aList
	? "Print the List by calling C Code"
	displayList(aList)

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

	Replicate list (1:3) three times then print the items (We expect 12 items)
	1
	2
	3
	1
	2
	3
	1
	2
	3
	1
	2
	3

	Create list contains 5 items using C code
	1
	2
	3
	4
	5

	Create List (3,2)
	Print the List using Ring
	R 1 C 1
	R 1 C 2
	R 2 C 1
	R 2 C 2
	R 3 C 1
	R 3 C 2

	Print the List by calling C Code
	Sub List..
	String : R 1 C 1
	String : R 1 C 2
	Sub List..
	String : R 2 C 1
	String : R 2 C 2
	Sub List..
	String : R 3 C 1
	String : R 3 C 2

	
.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Update Table

Update Table
============

Sample : ring/extensions/tutorial/updatetable

In this extension we learn how to create a C function that update a table contains rows and columns

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_updatetable)
	{
		List *pList, *pRow;
		int nRow,nCol;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Get the List (Represent a Table)
			pList = RING_API_GETLIST(1);
		// Update the Table Rows and Columns
		for (nRow = 1 ; nRow <= ring_list_getsize(pList) ; nRow++ ) {
			if ( ring_list_islist(pList,nRow) ) {
			pRow = ring_list_getlist(pList,nRow);
			for (nCol = 1 ; nCol <= ring_list_getsize(pRow) ; nCol++ ) {
				if ( ring_list_isdouble(pRow,nCol) ) {
					ring_list_setdouble(pRow,nCol,RING_API_GETNUMBER(2));
				} else {
					RING_API_ERROR("Error : We expect numbers!\n");
					return ;
				}
			}
			} else {
				RING_API_ERROR("Error : The parameter is not a table! \n");
				return ;
			}
		}
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("updatetable",ring_updatetable);

The file test.ring contains

.. code-block:: ring

	load "stdlib.ring"

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

	aList = 1:3
	? "Replicate list (1:3) three times then print the items (We expect 12 items)"
	? replicatelist(aList,3)

	? "Create list contains 5 items using C code"
	aList = GenerateList(5)
	? aList

	? "Create List (3,2)"
	aList = newList(3,2)
	aList[1][1] = "R 1 C 1"
	aList[1][2] = "R 1 C 2"
	aList[2][1] = "R 2 C 1"
	aList[2][2] = "R 2 C 2"
	aList[3][1] = "R 3 C 1"
	aList[3][2] = "R 3 C 2"
	? "Print the List using Ring"
	? aList
	? "Print the List by calling C Code"
	displayList(aList)
	? ""

	? "Create List (2,2)"
	aList = newList(2,2)
	? "Update the list using C code - set all cells to 10"
	UpdateTable(aList,10)
	? "aList[1][1] : " + aList[1][1]
	? "aList[1][2] : " + aList[1][2]
	? "aList[2][1] : " + aList[2][1]
	? "aList[2][2] : " + aList[2][2]

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

	Replicate list (1:3) three times then print the items (We expect 12 items)
	1
	2
	3
	1
	2
	3
	1
	2
	3
	1
	2
	3

	Create list contains 5 items using C code
	1
	2
	3
	4
	5

	Create List (3,2)
	Print the List using Ring
	R 1 C 1
	R 1 C 2
	R 2 C 1
	R 2 C 2
	R 3 C 1
	R 3 C 2

	Print the List by calling C Code
	Sub List..
	String : R 1 C 1
	String : R 1 C 2
	Sub List..
	String : R 2 C 1
	String : R 2 C 2
	Sub List..
	String : R 3 C 1
	String : R 3 C 2

	Create List (2,2)
	Update the list using C code - set all cells to 10
	aList[1][1] : 10
	aList[1][2] : 10
	aList[2][1] : 10
	aList[2][2] : 10

.. index:: 
	pair: Tutorial: Ring Extensions in C/C++; Create Table

Create Table
============

Sample : ring/extensions/tutorial/createtable

In this extension we learn how to create a C function that create a table contains rows and columns

In mylib.c we update the file to add

.. code-block:: c

	RING_FUNC(ring_createtable)
	{
		List *pList, *pRow;
		int x,y,nRows,nCols;
		// Check Parameters Count
			if (RING_API_PARACOUNT != 2) {
				RING_API_ERROR(RING_API_MISS2PARA);
				return;
			}
		// Check Parameters Type
			if ( ! ( RING_API_ISNUMBER(1) && RING_API_ISNUMBER(2) ) ) {
				RING_API_ERROR(RING_API_BADPARATYPE);
				return;
			}
		// Create the List
			pList = RING_API_NEWLIST;
		// Create the table items
			nRows = (int) RING_API_GETNUMBER(1);
			nCols = (int) RING_API_GETNUMBER(2);
			if ( (nRows < 1) || (nCols < 1) ) {
			RING_API_ERROR("Error: The table rows and columns must be >= 1 \n");
			return;
			}
			for(x = 1 ; x <= nRows ; x++) {
				pRow = ring_list_newlist(pList);
				for(y = 1 ; y <= nCols ; y++) 
					ring_list_adddouble(pRow,0.0);
			}
		// Return Output
			RING_API_RETLIST(pList);
	}

Then we register the new function

.. code-block:: c

	ring_vm_funcregister("createtable",ring_createtable);

The file test.ring contains

.. code-block:: ring

	load "stdlib.ring"

	? "Loading Library"
	load "mylib.ring"

	? "Calling a C Function"
	myfunction()

	? "Sum Two Numbers (3,5)"
	? SumTwoNumbers(3,5)

	? "Say Hello"
	SayHello("Mahmoud")

	? "Sum List contains numbers from 1 to 10"
	aList = 1:10
	? SumList(aList)

	? "Increment List Items"
	? inclist(aList,10)

	? "Filter List Items (Items > 15)"
	? filterlist(aList,15)

	aList = 1:3
	? "Replicate list (1:3) three times then print the items (We expect 12 items)"
	? replicatelist(aList,3)

	? "Create list contains 5 items using C code"
	aList = GenerateList(5)
	? aList

	? "Create List (3,2)"
	aList = newList(3,2)
	aList[1][1] = "R 1 C 1"
	aList[1][2] = "R 1 C 2"
	aList[2][1] = "R 2 C 1"
	aList[2][2] = "R 2 C 2"
	aList[3][1] = "R 3 C 1"
	aList[3][2] = "R 3 C 2"
	? "Print the List using Ring"
	? aList
	? "Print the List by calling C Code"
	displayList(aList)
	? ""

	? "Create List (2,2)"
	aList = newList(2,2)
	? "Update the list using C code - set all cells to 10"
	UpdateTable(aList,10)
	? "aList[1][1] : " + aList[1][1]
	? "aList[1][2] : " + aList[1][2]
	? "aList[2][1] : " + aList[2][1]
	? "aList[2][2] : " + aList[2][2]
	? ""

	? "Create List (3,3) using C code"
	aList = CreateTable(3,3)
	? "aList[1][1] : " + aList[1][1]
	? "aList[1][2] : " + aList[1][2]
	? "aList[1][3] : " + aList[1][3]
	? "aList[2][1] : " + aList[2][1]
	? "aList[2][2] : " + aList[2][2]
	? "aList[2][3] : " + aList[2][3]
	? "aList[3][1] : " + aList[3][1]
	? "aList[3][2] : " + aList[3][2]
	? "aList[3][3] : " + aList[3][3]

Then we test the function using

.. code-block:: none

	ring test.ring

Output

.. code-block:: none

	Loading Library
	Calling a C Function
	Hello, World!
	Sum Two Numbers (3,5)
	8
	Say Hello
	Hello Mahmoud
	Sum List contains numbers from 1 to 10
	55
	Increment List Items
	11
	12
	13
	14
	15
	16
	17
	18
	19
	20


	Filter List Items (Items > 15)
	16
	17
	18
	19
	20

	Replicate list (1:3) three times then print the items (We expect 12 items)
	1
	2
	3
	1
	2
	3
	1
	2
	3
	1
	2
	3

	Create list contains 5 items using C code
	1
	2
	3
	4
	5

	Create List (3,2)
	Print the List using Ring
	R 1 C 1
	R 1 C 2
	R 2 C 1
	R 2 C 2
	R 3 C 1
	R 3 C 2

	Print the List by calling C Code
	Sub List..
	String : R 1 C 1
	String : R 1 C 2
	Sub List..
	String : R 2 C 1
	String : R 2 C 2
	Sub List..
	String : R 3 C 1
	String : R 3 C 2

	Create List (2,2)
	Update the list using C code - set all cells to 10
	aList[1][1] : 10
	aList[1][2] : 10
	aList[2][1] : 10
	aList[2][2] : 10

	Create List (3,3) using C code
	aList[1][1] : 0
	aList[1][2] : 0
	aList[1][3] : 0
	aList[2][1] : 0
	aList[2][2] : 0
	aList[2][3] : 0
	aList[3][1] : 0
	aList[3][2] : 0
	aList[3][3] : 0
