How to check shader and program error in cl-opengl? - common-lisp

I'm learning opengl ES 2.0. I'm learning to check errors in C, but I don't know as make the same in cl-opengl, because I don't see any function like gl:get-shaderiv or gl:get-programiv, so, how to make the same that the code below do? However in cl-opengl.
// Check the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if(!compiled) {
GLint info
Len = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1) {
char* infoLog = malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
esLogMessage("Error compiling shader:\n%s\n", infoLog);
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
// Check the link status
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
if(!linked) {
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1) {
char* infoLog = malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
esLogMessage("Error linking program:\n%s\n", infoLog);
free(infoLog);
}
glDeleteProgram(programObject);
return FALSE;
}

There are two ways for get it:
First:
(gl:get-shader shader :compile-status)
or you can use the second option:
%gl:get-shader-iv
In this way you need allocate manually a pointer for &compiled.

Related

Having issues when attempting to declare constant variable in arduino

I am making a fairly simple script for sound on my arduino. Here's my script:
#include <digitalWriteFast.h>
struct AudioHandler {
//Alter these as you require
const int pin = 2;
float frequency = 1;
float dutyCycle = 1;
//These are internal variables that you shouldn't touch
unsigned long prevMicros = 0;
bool onHalf = true; //This just asks which half of the wave the sound is on
//This just checks the time and asks if it should switch to the other half of the wave
void updateSound() {
if ((micros() - prevMicros > (1000000 / frequency) * dutyCycle) && (onHalf)) {
prevMicros = micros();
onHalf = false;
digitalWriteFast(pin,false);
} else if ((micros() - prevMicros > (1000000 / frequency) * (1 - dutyCycle)) && (!onHalf)) {
prevMicros = micros();
onHalf = true;
digitalWriteFast(pin,true);
}
}
};
AudioHandler test_1;
AudioHandler test_2;
AudioHandler test_3;
AudioHandler test_4;
void setup() {
pinModeFast(3,OUTPUT); test_1.frequency = 65.41; test_1.dutyCycle = 0.5;
pinModeFast(4,OUTPUT); test_2.frequency = 82.41; test_2.dutyCycle = 0.5;
pinModeFast(5,OUTPUT); test_3.frequency = 98.00; test_3.dutyCycle = 0.5;
pinModeFast(6,OUTPUT); test_4.frequency = 130.81; test_4.dutyCycle = 0.5;
//I need to set the pin, but couldn't figure out how to do it in struct declaration
//Also, this
int *pinPointer_1; pinPointer_1 = &test_1.pin; *pinPointer_1 = 3;
int *pinPointer_2; pinPointer_2 = &test_2.pin; *pinPointer_2 = 4;
int *pinPointer_3; pinPointer_3 = &test_3.pin; *pinPointer_3 = 5;
int *pinPointer_4; pinPointer_4 = &test_4.pin; *pinPointer_4 = 6;
}
void loop() {
test_1.updateSound();
test_2.updateSound();
test_3.updateSound();
test_4.updateSound();
}
Effectively my script SHOULD work fine, but the arduino IDE is complaining:
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
C:\Users\aj200\Documents\GitHub\My-Projects\My-Projects\Active Projects\Sound_PWM_Help\Sound_PWM_Help.ino: In member function 'updateSound':
Sound_PWM_Help:19:7: error: call to 'NonConstantUsed' declared with attribute error:
digitalWriteFast(pin,false);
^
Sound_PWM_Help:24:7: error: call to 'NonConstantUsed' declared with attribute error:
digitalWriteFast(pin,true);
^
lto-wrapper.exe: fatal error: C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc returned 1 exit status
compilation terminated.
c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
exit status 1
call to 'NonConstantUsed' declared with attribute error:
In theory, this should be complete and functional. HOWEVER, for some reason the arduino compiler is saying that the variable "pin" is not constant (digitalWriteFast(pin,state) requires constant value annoyingly). What am I missing here?
Thanking you in advance,
Andrey
Why don't you create a struct constructor to assign the pins. Then a setup method could define them as pins using pinModeFast()
This is my take on this. Compiled successfully for Arduino Uno and Leonardo but untested for now. To me, it looks cleaner and easier to follow and grow
#include <digitalWriteFast.h>
struct AudioHandler {
//Alter these as you require
int _pin;
float frequency;
float dutyCycle;
AudioHandler(int pin){
_pin = pin;
}
//These are internal variables that you shouldn't touch
unsigned long prevMicros = 0;
bool onHalf = true; //This just asks which half of the wave the sound is on
//This just checks the time and asks if it should switch to the other half of the wave
void updateSound() {
if ((micros() - prevMicros > (1000000 / frequency) * dutyCycle) && (onHalf)) {
prevMicros = micros();
onHalf = false;
digitalWriteFast(_pin, LOW); // Changed from false
} else if ((micros() - prevMicros > (1000000 / frequency) * (1 - dutyCycle)) && (!onHalf)) {
prevMicros = micros();
onHalf = true;
digitalWriteFast(_pin, HIGH); // Changed from true
}
}
void setup(int freq, int duty){
pinModeFast(_pin, OUTPUT);
frequency = freq;
dutyCycle = duty;
}
};
// Instantiate your audio handlers passing the pin number according to the constructor
AudioHandler test_1 = AudioHandler(3);
AudioHandler test_2 = AudioHandler(4);
AudioHandler test_3 = AudioHandler(5);
AudioHandler test_4 = AudioHandler(6);
void setup() {
// Set them up passing frequency and duty cycle
test_1.setup(65.41,0.5);
test_2.setup(82.41, 0.5);
test_3.setup(98.00, 0.5);
test_4.setup(130.81,0.5);
}
void loop() {
test_1.updateSound();
test_2.updateSound();
test_3.updateSound();
test_4.updateSound();
}

Downloading Image to a specific folder using gp_filesystem_get_file()

Trying my hands on libgphoto2 library examples and while going through simple-capture.c file. Can i download foo.jpg captured image to a specified folder on my computer?
As far as i understood, in capture_to_file() camera_file_path.folder is the folder in which the file can be found on the camera. So open() should specify the host(computer) location. But nothing worked, i get following error:
You need to specify a folder starting with /store_xxxxxxxxx/
Am i missing something here? Any help would be appreciated, thanks!
I got this working.
Written small application for multiple cameras. Including main() for about question.
int main(int argc, char **argv)
{
CameraList *list;
Camera **cams;
int retval, count, i;
GPContext *context;
FILE *f;
char *data;
unsigned long size;
const char *name, *value;
/*
* Create context
*/
context = sample_create_context();
/*
* Setup Images DB directory.
*/
char* home = getenv("HOME");
if (home == NULL)
{
printf("Error: Unable to fetch home env! \n");
exit(1);
}
char* path = "/Desktop/mw/";
size_t len = strlen(home) + strlen(path) + 1;
char* imgdb = malloc(len);
if (imgdb == NULL)
{
printf("Error: Unable to malloc(). \n");
exit(1);
}
strcpy(imgdb, home);
strcat(imgdb, path);
directory_exists_or_create(imgdb);
/*
* Logs
*/
gp_log_add_func(GP_LOG_ERROR, errordumper, NULL);
/*
* Detect all the cameras that can be autodetected
*/
retval = gp_list_new(&list);
if (retval < GP_OK)
{
printf("Unable to create camera list.\n");
return 1;
}
count = sample_autodetect(list, context);
if (count < GP_OK)
{
printf("No cameras detected.\n");
return 1;
}
/*
* Now open all the cameras we autodetected for usage.
*/
printf("Number of cameras: %d\n", count);
cams = calloc(sizeof(Camera*), count);
for (i = 0; i < count; i++)
{
gp_list_get_name(list, i, &name);
gp_list_get_value(list, i, &value);
retval = sample_open_camera(&cams[i], name, value, context);
if (retval < GP_OK)
{
fprintf(stderr, "Camera %s on port %s failed to open\n", name, value);
}
}
if (argc > 0)
{
while ((++argv)[0])
{
if (argv[0][0] == '-')
{
switch (argv[0][1])
{
case 'h':
case 'H':
{
/* Now call a simple function in each of those cameras. */
for (i = 0; i < count; i++)
{
CameraText text;
char *owner;
retval = gp_camera_get_summary (cams[i], &text, context);
if (retval < GP_OK)
{
fprintf (stderr, "Failed to get summary.\n");
continue;
}
gp_list_get_name (list, i, &name);
gp_list_get_value (list, i, &value);
printf("%-30s %-16s\n", name, value);
printf("Summary:\n%s\n", text.text);
/* Query a simple string configuration variable. */
retval = get_config_value_string (cams[i], "owner", &owner, context);
if (retval >= GP_OK)
{
printf("Owner: %s\n", owner);
free (owner);
}
else
{
printf("Owner: No owner found.\n");
}
}
}
/* Graceful exit from the program */
goto exit_;;
default:
printf("Unknown option -%c\n\n", argv[0][1]);
break;
}
}
}
}
/* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the
* init function seems to traverse the entire filesystem on the camera. This
* is partly why it takes so long.
* (Marcus: the ptp2 driver does this by default currently.)
*/
printf("Cameras init. Takes about 10 seconds each.\n");
for (i = 0; i < count; i++)
{
retval = gp_camera_init(cams[i], context);
if (retval != GP_OK)
{
printf(" Camera [%d] init failed with retval %d\n", i, retval);
exit (1);
}
}
printf(" ----------------\n");
printf(" Sampler is ready \n");
printf(" ----------------\n");
printf("Usage : \n");
printf(" ESC - Exit the program\n");
printf(" i/I - Insert new product barcode manually\n");
#if defined(BARCODE_ENABLED)
printf(" b/B - Insert new product barcode using barcode-scanner\n");
#endif
char get_key;
char exit_key = 0;
char bcr_buf[128] = {0};
int hemispheres_counts = 0;
int rotar_steps = 0;
do
{
get_key = getchar();
switch (get_key)
{
// Gracefull Exit
case _ESC_:
exit_key = 1;
break;
// Manual insert mode
case 'i':
case 'I':
printf("ACTION: Type in the name.\n");
scanf("%128s", bcr_buf);
process:
press_enter();
printf("ACTION: Shall we start? press return key.\n");
press_enter();
hemispheres_counts = 0;
rotar_steps = 0;
char product_filename[256] = {0};
strcpy(product_filename, imgdb);
strcat(product_filename, bcr_buf);
if (directory_exists_or_create(product_filename))
{
printf("\n\n!!! ATTENTION: The product already exists !!!\n\n");
printf("\nEnter options:\n");
printf(" ESC - Exit the program\n");
printf(" i/I - Insert new product barcode manually\n");
#if defined(BARCODE_ENABLED)
printf(" b/B - Insert new product barcode using barcode-scanner\n");
#endif
break;
}
while (hemispheres_counts < MAX_HEMISPHERES)
{
while (rotar_steps < MAX_ROTAR_STEPS)
{
for (i = 0; i < count; i++)
{
capture_to_memory(cams[i], context, (const char**)&data, &size);
char fname[64] = {0};
char mk_filename[256] = {0};
strcpy(mk_filename, product_filename);
snprintf(fname, sizeof(fname), "/%d-%d-%d.jpg", i, hemispheres_counts, rotar_steps);
strcat(mk_filename, fname);
printf("file name %s\n", mk_filename);
f = fopen(mk_filename, "wb");
if (f)
{
retval = fwrite (data, size, 1, f);
if (retval != size)
{
printf(" fwrite size %ld, written %d\n", size, retval);
}
fclose(f);
}
else
{
printf(" fopen *.jpg failed. %s\n", strerror(errno));
}
usleep(500*1000);
}
rotar_steps++;
}
rotar_steps = 0;
hemispheres_counts++;
if (hemispheres_counts < MAX_HEMISPHERES)
{
printf("Flip the product and hit 'RETURN' key\n");
press_enter(); // This expect some input from user, thats it.
printf("Started capturing other hemisphere!\n");
} else {
printf("Sampling Done for barcode: %s\n", bcr_buf);
printf(" -------------------------------------\n");
printf("\nEnter options:\n");
printf(" ESC - Exit the program\n");
printf(" i/I - Insert new product barcode manually\n");
#if defined(BARCODE_ENABLED)
printf(" b/B - Insert new product barcode using barcode-scanner\n");
#endif
break;
}
}
break;
}
} while (exit_key != 1);
exit_:
/*
* Release all the resources.
*/
printf("\nReleasing all the resources ... \n");
for (i = 0; i < count; i++)
{
gp_camera_exit(cams[i], context);
}
if (cams) {
free(cams);
}
free(imgdb);
#if defined(BARCODE_ENABLED)
close_bcr();
#endif
printf("Done.\n");
return 0;
}

undirected Graph adjacency list implementation using C

Code :
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct list
{
int data;
struct list * next;//self referenced structure
}slist;
void displayList(slist * start)
{
slist * temp;
if(start==NULL)
{
printf("Empty Linked List");
return;
}
for(temp=start;temp!=NULL;temp=temp->next)
printf("%d ",temp->data);
return;
}
void insertLast(slist * * start,slist * node)
{
slist * temp;
if(start==NULL){
(* start)=node;
return;
}
temp=(* start);
while((temp->next)!= NULL)
temp=temp->next;
temp->next=node;
return;
}
int main()
{
int i,j;
//slist * node;
char Ans;
/*printf("Write the number of vertices\n");
scanf("%d",&N);*/
slist * start[N];
for(i=0;i<N;i++)
start[i]=NULL;
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
{
printf("Is there a connection between V[%d] and V[%d]\n",(i+1),(j+1));
scanf(" %c",&Ans);
if(Ans=='y'||Ans=='Y')
{
slist * node1=(slist *)malloc(sizeof(slist));
node1->data=(j+1); node1->next=NULL;
insertLast(&start[i],node1);enter code here
slist * node2=(slist *)malloc(sizeof(slist));
node2->data=(i+1); node2->next=NULL;
insertLast(&start[j],node2);
}
}
}
for(i=0;i<N;i++)
{
displayList(start[i]);
printf("\n");
}
return 0;
}
The above code is showing segmentation fault at the line where while((temp->next)!=NULL) is written whereas while creation of linked lists, the same insertLast worked just fine. What is the fault in the code?
Your program crashed as you are checking if start is NULL or not. But that does not guarantee that *start is also not NULL. In such situation, temp gets NULL and in while loop temp->next actually trying to access next element of NULL pointer and that is why the crash.
Changing this line -
if(start==NULL)
to
if(*start==NULL)
in insertLast() will fix the crash.
I also recommend to use a debugger like gdb to debug such issues.

select() message queue failed as bad address(EFAULT) on AIX 6.1.0.0

On AIX 6.1.0.0, select() system call support for message queue, see http://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/select.htm?lang=en
But the below code return failed with errno 14(EFAULT) after select() called:
int msgid = msgget(MQ_KEY, IPC_CREAT|06666);
if (-1 == msgid) {
if (errno != EEXIST) {
ETRACE("msgget() failed: key[%d], errno[%d]", MQ_KEY, errno);
return -1;
}
msgid = msgget(MQ_KEY, 0);
if (-1 == msgid) {
ETRACE("msgget() failed: key[%d], errno[%d]", MQ_KEY, errno);
return -1;
}
}
DTRACE("msgget() success: msgid[%d]", msgid);
/* time out */
struct timeval to;
to.tv_sec = 10;
to.tv_usec = 0;
/* select list */
struct {
int msgids[1];
} rlist, wlist, elist;
rlist.msgids[0] = msgid;
wlist.msgids[0] = msgid;
elist.msgids[0] = msgid;
/* number of list */
int nlist = 1 << 16;
/* int ret = select(nlist, (struct fd_set*)&rlist, (struct fd_set*)&wlist, (struct fd_set*)&elist, &to); */
int ret = select(nlist, (struct fd_set*)&rlist, NULL, NULL, &to);
if (0 == ret) {
WTRACE("select() timeout: ret[%d]", ret);
}
else if (ret < 0) {
ETRACE("select() failed: ret[%d], errno[%d]", ret, errno);
}
else {
ITRACE("select() success");
}
return 0;
Message queue support in select() and poll() is an AIX extension that is no longer enabled by default when compiling on AIX 5.3 and later versions. To enable it, compile with -D_MSGQSUPPORT (or #define _MSGQSUPPORT 1 before the first #include).
It is not mentioned on the select() manual page but the option is mentioned on the poll() manual page, and the same flag enables message queue support for both functions.

How do I loop mount programmatically?

I have recently written a guide on how to mount partitions from image files on Raspberry Pi.SE. The instructions are rather complicated and I have a bit of time, so want to replace them by a C program. I have successfully listed the partitions of the image and calculated to appropriate offsets.
In the original instructions, we needed to run
$ sudo mount -o loop,offset=80740352 debian6-19-04-2012.img /mnt
I now need to do this in code. I have found the mount function and libmount in util-linux.
I have now found loopdev.c in util-linux. Is there an easy way to create loop devices or do I have to learn from this code and use ioctl?
The following function binds the loop device device to file at offset. It returns 0 on success, 1 otherwise.
int loopdev_setup_device(const char * file, uint64_t offset, const char * device) {
int file_fd = open(file, O_RDWR);
int device_fd = -1;
struct loop_info64 info;
if(file_fd < 0) {
fprintf(stderr, "Failed to open backing file (%s).\n", file);
goto error;
}
if((device_fd = open(device, O_RDWR)) < 0) {
fprintf(stderr, "Failed to open device (%s).\n", device);
goto error;
}
if(ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
fprintf(stderr, "Failed to set fd.\n");
goto error;
}
close(file_fd);
file_fd = -1;
memset(&info, 0, sizeof(struct loop_info64)); /* Is this necessary? */
info.lo_offset = offset;
/* info.lo_sizelimit = 0 => max avilable */
/* info.lo_encrypt_type = 0 => none */
if(ioctl(device_fd, LOOP_SET_STATUS64, &info)) {
fprintf(stderr, "Failed to set info.\n");
goto error;
}
close(device_fd);
device_fd = -1;
return 0;
error:
if(file_fd >= 0) {
close(file_fd);
}
if(device_fd >= 0) {
ioctl(device_fd, LOOP_CLR_FD, 0);
close(device_fd);
}
return 1;
}
References
linux/loop.h
piimg

Resources