Code: Select all
#define add_me(a,b) return a+b
if(42==add_me(40,2)) //and that translate to if(42==42)
Code: Select all
#define add_me(a,b) return a+b
if(42==add_me(40,2)) //and that translate to if(42==42)
Macros in C do text substitution, so the above would actually be translated into:hckr83 wrote:I'm attempting to make a macro and well I need to know how you would return a function from a macro like this:
Code: Select all
#define add_me(a,b) return a+b if(42==add_me(40,2)) //and that translate to if(42==42)
Code: Select all
if(42==return 40+2)
Code: Select all
#define add_me(a,b) (a+b)
Code: Select all
if(42==(40+2))
Code: Select all
#define linked_GetObject(pointer,number_wanted,name_of_next,name_of_prev,tmp_int)\
tmp=number_wanted;\
if(number_wanted>0){\
for(;tmp_int!=0;tmp_int--){\
pointer=pointer->name_of_next; \
}\
}else{\
if(number_wanted!=0){\
for(;tmp_int!=0;tmp_int++){\
pointer=pointer->name_of_prev; \
}\
}\
}
Code: Select all
#define linked_GetObject(pointer,number_wanted,name_of_next,name_of_prev,tmp_int,ReturnValue)\
tmp=number_wanted;\
if(number_wanted>0){\
for(;tmp_int!=0;tmp_int--){\
pointer=pointer->name_of_next; \
}\
}else{\
if(number_wanted!=0){\
for(;tmp_int!=0;tmp_int++){\
pointer=pointer->name_of_prev; \
}\
}\
ReturnValue = pointer;
} else ReturnValue = NULL; //Just incase ;)
Code: Select all
void *linked_GetObject(void *data,void *prev,void *next,signed int number){
signed int tmp;
unsigned int diff_next=(next-data);
unsigned int diff_prev=(prev-data);
void **ptr;
tmp=number;
if(number==0){return data;}
if(number>0){
for(;tmp!=0;tmp--){
data=data+diff_next;
ptr=data;
data=*ptr;
}
}else{ //tmp is less than 0, or negative
for(;tmp!=0;tmp++){
data=data+diff_prev;
ptr=data;
data=*ptr; //C doesn't allow you to jsut specify void **, have to make a whole new variable!
}
}
return data;
}
//to do this just do next_object=linked_GetObject(current_object,¤t_object->next,¤t_object->prev,1);
//to you can even go backwards! just do -1 or -2.. prev is only used if you do negative
Code: Select all
typedef struct
{
void *prev;
void *next;
} linked_object;
typedef struct
{
linked_object link;
unsigned int blah;
} test_object;
//Why were you passing next/prev, they are in there already!
void *linked_GetObject2(linked_object *start,signed int number)
{
unsigned int tmp;
linked_object *ptrCur;
ptrCur = start;
tmp=number;
if(number==0){return start;}
if(number>0){
for(;tmp!=0;tmp--){
ptrCur=ptrCur->next;
}
}else{ //tmp is less than 0, or negative
for(;tmp!=0;tmp++){
ptrCur=ptrCur->prev;
}
}
return ptrCur;
}
int main()
{
test_object *blah;
test_object *ptr;
test_object *again;
test_object *now;
test_object *bah;
test_object *test;
signed int tmp;
blah=malloc(sizeof(test_object));
ptr=malloc(sizeof(test_object));
again=malloc(sizeof(test_object));
now=malloc(sizeof(test_object));
bah=malloc(sizeof(test_object));
blah->prev=NULL;
blah->next=ptr;
ptr->prev=blah;
ptr->next=again;
again->prev=ptr;
again->next=now;
now->prev=again;
now->next=bah;
bah->prev=now;
bah->next=NULL;
test=ptr;
test=linked_GetObject2(&test.link,2); //here!
if(test==now){return 0;}else{return 1;} //this should be 0
}
Mine works with ANY struct that has linked_object as the first element in it. There has to be some consistancy in order for it to work, they have to have prev/next in the same location, otherwise how will the function know where they are located. You could use templates if you aren't against using C++ in your kernel, that is a much prettier solution, but that won't compile in a C compiler . Here is an example with my code using more than one type...hckr83 wrote:thanks, but I want to be able to use this on any struct(not just ones I make..)
Code: Select all
typedef struct
{
void *prev;
void *next;
} linked_object;
typedef struct
{
linked_object link;
unsigned int blah;
} test_object;
typedef struct
{
linked_object link;
unsigned char Stuff[10];
} test_object2;
//Why were you passing next/prev, they are in there already!
void *linked_GetObject2(linked_object *start,signed int number)
{
unsigned int tmp;
linked_object *ptrCur;
ptrCur = start;
tmp=number;
if(number==0){return start;}
if(number>0){
for(;tmp!=0;tmp--){
ptrCur=ptrCur->next;
}
}else{ //tmp is less than 0, or negative
for(;tmp!=0;tmp++){
ptrCur=ptrCur->prev;
}
}
return ptrCur;
}
int main()
{
test_object *blah;
test_object *ptr;
test_object2 *again;
test_object *now;
test_object *bah;
test_object2 *test;
signed int tmp;
blah=malloc(sizeof(test_object));
ptr=malloc(sizeof(test_object));
again=malloc(sizeof(test_object2));
now=malloc(sizeof(test_object));
bah=malloc(sizeof(test_object));
blah->prev=NULL;
blah->next=ptr;
ptr->prev=blah;
ptr->next=again;
again->prev=ptr;
again->next=now;
now->prev=again;
now->next=bah;
bah->prev=now;
bah->next=NULL;
test2=(test_object2*)ptr; //Lets cast, because it's another type!
test=linked_GetObject2(&test.link,2); //here!
if(test==now){return 0;}else{return 1;} //this should be 0
}
Code: Select all
typedef struct
{
void *prev;
void *next;
void *data;
} linked_object;
typedef struct
{
unsigned int blah;
} test_object;
typedef struct
{
unsigned char Stuff[10];
} test_object2;
//Why were you passing next/prev, they are in there already!
void *linked_GetObject(linked_object *start,signed int number)
{
unsigned int tmp;
linked_object *ptrCur;
ptrCur = start;
tmp=number;
if(number==0){return start;}
if(number>0){
for(;tmp!=0;tmp--){
ptrCur=ptrCur->next;
}
}else{ //tmp is less than 0, or negative
for(;tmp!=0;tmp++){
ptrCur=ptrCur->prev;
}
}
return ptrCur->data; //return the object, not the list item!
}
linked_object *head=NULL, *tail = NULL;
void AddToList(void *data_ptr)
{
linked_object *ptrNew;
if (tail == NULL) //No list yet!
{
head = malloc(sizeof(linked_object));
tail = head;
head->prev = 0;
head->next = 0;
head->data = data_ptr;
}
else //Ok, we already have something!
{
ptrNew = malloc(sizeof(linked_object));
ptrNew->prev = tail;
ptrNew->next = NULL;
tail->next = ptrNew;
tail = ptrNew;
ptrNew->data = data_ptr;
}
}
int main()
{
test_object obj1;
test_object obj2;
test_object2 obj3;
test_object2 obj4;
test_object2 *ptr;
AddToList(&obj1);
AddToList(&obj2);
AddToList(&obj3);
AddToList(&obj4);
ptr = linked_GetObject(obj1,2);
}
That depends on your compiler, if it supports templates or not. If it does, it doesn't require any extra library functions specific to your OS or anything like that.hckr83 wrote:how would you do it with templates, and also, would you be able to use templates in normal C code?(like call the function made in c++ or something?)
Code: Select all
template <T>
T *linked_GetObject(T *ptrT, signed int number)
{
unsigned int tmp;
T *ptrCur;
ptrCur = ptrT;
tmp=number;
if(number==0){return ptrCur;}
if(number>0){
for(;tmp!=0;tmp--){
ptrCur=ptrCur->next;
}
}else{ //tmp is less than 0, or negative
for(;tmp!=0;tmp--){
ptrCur=ptrCur->prev;
}
}
return ptrCur; //return the object, not the list item!
}
Code: Select all
template <T>
class GenericData
{
public:
T Data;
GenericData* next;
GenericData* prev;
};
template <T>
class GenericList
{
public:
GenericData<T> *Head, *Tail;
public:
GenericList(void)
{
Head = Tail = 0;
};
~GenericList(void)
{
ClearList();
};
void AddToList(T Data)
{
GenericData<T> *ptrNew;
if (Head == 0) //Nothing yet?
{
Head = malloc(sizeof(GenericData<T>)); //Avoid new operator
Tail = Head;
Head->Prev = Head->Next = 0;
}
else
{
ptrNew = malloc(sizeof(GenericData<T>)); //Avoid new operator
ptrNew->Prev = Tail;
ptrNew->Next = 0;
Tail->Next = ptrNew;
Tail = ptrNew;
}
Tail->Data = Data;
}
T GetByIndex(int Index) //Get an element based on it's index!
{
GenericData<T> *ptrCur = Head;
while (Index-- && ptrCur) //Make sure ptrCur != NULL!!!!
ptrCur = ptrCur->Next;
return ptrCur->Data;
}
};
typdef struct
{
int TestNum;
float x,y;
} object_type1;
GenericList<object_type1*> Object1List; //store a list of pointers to this type!
int main(void)
{
object_type1 *ptrObj1, *ptrObj2, *ptrObj3, *ptrRet;
ptrObj1 = malloc(sizeof(object_type1));
ptrObj2 = malloc(sizeof(object_type1));
ptrObj3 = malloc(sizeof(object_type1));
Object1List.AddToList(ptrObj1);
Object1List.AddToList(ptrObj2);
Object1List.AddToList(ptrObj3);
ptrRet = GetByIndex(1); //Returns ptrObj2!
}