Current section
Files
Jump to
Current section
Files
src/msgtype_tmp.sh
#!/bin/bash
msgtypename=$1
pkgname=${msgtypename%%/*}
typename=${msgtypename##*/}
typename_low=$(echo "$typename" | sed -e "s/\([A-Z]\)/_\L\1/g" -e "s/_//")
filename=${pkgname}/msg/${typename_low}
structname=${pkgname}__msg__${typename}
funcname=${pkgname}_msg_${typename_low}
declare -A member_set
declare -A member_read
set_structmember()
{
local membertype=$1
local data=$2
local res=$3
local tmp=$4
if [[ $membertype =~ __msg__ ]]; then
setread_structmembers "$membertype" "$tmp" "$res."
cat << __DOC__
int ${tmp}_arity;
const ERL_NIF_TERM* ${tmp};
if(!enif_get_tuple(env,${data},&${tmp}_arity,&${tmp})) {
return enif_make_badarg(env);
}
${member_set[$membertype]}
__DOC__
elif [ $membertype = "bool" ]; then
cat << __DOC__
unsigned ${tmp};
if(!enif_get_atom_length(env,${data},&${tmp},ERL_NIF_LATIN1)) {
return enif_make_badarg(env);
}
if(${tmp} == 4) ${res} = true;
else if(${tmp} == 5) ${res} = false;
__DOC__
elif [[ $membertype =~ int ]]; then
cat << __DOC__
${membertype} ${tmp};
if(!enif_get_int(env,${data},&${tmp})) {
return enif_make_badarg(env);
}
${res} = ${tmp};
__DOC__
elif [[ $membertype =~ float|double ]]; then
cat << __DOC__
${membertype} ${tmp};
if(!enif_get_double(env,${data},&${tmp})) {
return enif_make_badarg(env);
}
${res} = ${tmp};
__DOC__
elif [ $membertype = "rosidl_runtime_c__String" ]; then
cat << __DOC__
unsigned ${tmp}_length;
if(!enif_get_list_length(env,${data},&${tmp}_length)) {
return enif_make_badarg(env);
}
char* ${tmp} = (char*) malloc(${tmp}_length + 1);
if(!enif_get_string(env,${data},${tmp},${tmp}_length + 1,ERL_NIF_LATIN1)) {
return enif_make_badarg(env);
}
__STRING__ASSIGN(&(${res}),${tmp});
free(${tmp});
__DOC__
elif [ $membertype = "rosidl_runtime_c__U16String" ]; then
cat << __DOC__
unsigned ${tmp}_length;
if(!enif_get_list_length(env,${data},&${tmp}_length)) {
return enif_make_badarg(env);
}
char* ${tmp} = (char*) malloc(${tmp}_length + 1);
if(!enif_get_string(env,${data},${tmp},${tmp}_length + 1,ERL_NIF_LATIN1)) {
return enif_make_badarg(env);
}
__U16STRING__ASSIGN(&(${data}),${tmp});
free(${tmp});
__DOC__
fi
}
read_structmember()
{
local membertype=$1
local res=$2
if [[ $membertype =~ __msg__ ]]; then
setread_structmembers "$membertype" "$tmp" "$res."
cat << __DOC__
${member_read[$membertype]}
__DOC__
elif [ $membertype = "bool" ]; then
cat <<< " enif_make_atom(env,(${res}?\"true\":\"false\"))"
elif [[ $membertype =~ int ]]; then
cat <<< " enif_make_int(env,${res})"
elif [[ $membertype =~ float|double ]]; then
cat <<< " enif_make_double(env,${res})"
elif [ $membertype = "rosidl_runtime_c__String" ]; then
cat <<< " enif_make_string(env,${res}.data,ERL_NIF_LATIN1)"
elif [ $membertype = "rosidl_runtime_c__U16String" ]; then
cat <<< " enif_make_string(env,(char*)(${res}.data),ERL_NIF_LATIN1)"
fi
}
setread_structmembers()
{
# argument : structname, tuplename, resourcename
local structname=$1
local pkgname=${structname%%__*}
local typename=${structname##*__}
local typename_low=$(echo "$typename" | sed -e "s/\([A-Z]\)/_\L\1/g" -e "s/_//")
local pkgdir=$(ros2 pkg prefix ${pkgname})
local dec=false
local i=0
local membertype
local membername
local arraynumber
local data=$2
local res=$3
member_set[$structname]=$()
member_read[$structname]=$()
while read line
do
if [ "$line" = "} ${structname};" ]; then
break
elif [ "$line" = "typedef struct ${structname}" ]; then
dec=true
elif ${dec} && [ "$line" != "{" ]; then
membertype=$(echo "${line% *}" | sed -e "s/ //g")
membername=$(echo "${line##* }" | sed -e "s/;//")
if [[ $membername =~ \[.*\] ]]; then
arraynumber=$(echo "$membername" | sed -e "s/^.*\[\(.*\)\]$/\1/")
membername=$(echo "$membername" | sed -e "s/^\(.*\)\[.*\]$/\1/")
member_set[$structname]=$(cat <<- __DOC__
${member_set[$structname]}
unsigned ${data}_${i}_length;
if(!enif_get_list_length(env,${data}[${i}],&${data}_${i}_length) || ${data}_${i}_length != ${arraynumber}) {
return enif_make_badarg(env);
}
ERL_NIF_TERM ${data}_${i}_list = ${data}[${i}];
ERL_NIF_TERM ${data}_${i}_head;
ERL_NIF_TERM ${data}_${i}_tail;
__DOC__
)
member_read[$structname]=$(cat <<- __DOC__
${member_read[$structname]},
enif_make_list(env,${arraynumber}
__DOC__
)
for j in `seq 0 $(($arraynumber - 1))`; do
member_set[$structname]=$(cat <<- __DOC__
${member_set[$structname]}
if(!enif_get_list_cell(env,${data}_${i}_list,&${data}_${i}_head,&${data}_${i}_tail)) {
return enif_make_badarg(env);
}
${data}_${i}_list = ${data}_${i}_tail;
$(set_structmember "$membertype" "${data}_${i}_head" "${res}${membername}[${j}]" "${data}_${i}_${j}")
__DOC__
)
member_read[$structname]=$(cat <<- __DOC__
${member_read[$structname]},
$(read_structmember "$membertype" "${res}${membername}[${j}]")
__DOC__
)
done
member_read[$structname]=$(cat <<- __DOC__
${member_read[$structname]})
__DOC__
)
else
member_set[$structname]=$(cat <<- __DOC__
${member_set[$structname]}
$(set_structmember "$membertype" "${data}[${i}]" "${res}${membername}" "${data}_${i}")
__DOC__
)
member_read[$structname]=$(cat <<- __DOC__
${member_read[$structname]},
$(read_structmember "$membertype" "${res}${membername}")
__DOC__
)
fi
let i++
fi
done < ${pkgdir}/include/${pkgname}/msg/detail/${typename_low}__struct.h
member_set[$structname]=$(cat <<- __DOC__
if(${data}_arity != ${i}) {
return enif_make_badarg(env);
}${member_set[$structname]}
__DOC__
)
member_read[$structname]=$(cat <<- __DOC__
enif_make_tuple(env,${i}${member_read[$structname]})
__DOC__
)
}
setread_structmembers "$structname" "data" "res->"
cat << __DOC__ > src/${filename}_nif.c
#include <erl_nif.h>
#ifdef DASHING
#include <rosidl_generator_c/message_type_support_struct.h>
#define __STRING__ASSIGN rosidl_generator_c__String__assign
#define __U16STRING__ASSIGN rosidl_generator_c__U16String__assign_from_char
#elif FOXY
#include <rosidl_runtime_c/message_type_support_struct.h>
#define __STRING__ASSIGN rosidl_runtime_c__String__assign
#define __U16STRING__ASSIGN rosidl_runtime_c__U16String__assign_from_char
#endif
#include <${filename}.h>
#include "${filename}_nif.h"
#include "total_nif.h"
ERL_NIF_TERM nif_get_typesupport_${funcname}(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 0) {
return enif_make_badarg(env);
}
void* res;
rosidl_message_type_support_t** res_ts;
ERL_NIF_TERM ret;
res = enif_alloc_resource(rt_void,sizeof(rosidl_message_type_support_t*));
if(res == NULL) {
return enif_make_badarg(env);
}
ret = enif_make_resource(env,res);
enif_release_resource(res);
res_ts = (rosidl_message_type_support_t**) res;
*res_ts = ROSIDL_GET_MSG_TYPE_SUPPORT(${pkgname},msg,${typename});
return ret;
}
ERL_NIF_TERM nif_create_empty_msg_${funcname}(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 0) {
return enif_make_badarg(env);
}
void* res;
ERL_NIF_TERM ret;
res = enif_alloc_resource(rt_void,sizeof(${structname}));
if(res == NULL) {
return enif_make_badarg(env);
}
ret = enif_make_resource(env,res);
enif_release_resource(res);
return ret;
}
ERL_NIF_TERM nif_init_msg_${funcname}(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 1) {
return enif_make_badarg(env);
}
void* res;
ERL_NIF_TERM ret;
if(!enif_get_resource(env,argv[0],rt_void,(void**)&res)) {
return enif_make_badarg(env);
}
ret = enif_make_resource(env,res);
${structname}__init((${structname}*) res);
return ret;
}
ERL_NIF_TERM nif_setdata_${funcname}(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 2) {
return enif_make_badarg(env);
}
void* res_tmp;
${structname}* res;
if(!enif_get_resource(env,argv[0],rt_void,(void**)&res_tmp)) {
return enif_make_badarg(env);
}
res = (${structname}*) res_tmp;
int data_arity;
const ERL_NIF_TERM* data;
if(!enif_get_tuple(env,argv[1],&data_arity,&data)) {
return enif_make_badarg(env);
}
${member_set[$structname]}
return enif_make_atom(env,"ok");
}
ERL_NIF_TERM nif_readdata_${funcname}(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 1) {
return enif_make_badarg(env);
}
void* res_tmp;
${structname}* res;
if(!enif_get_resource(env,argv[0],rt_void,(void**)&res_tmp)) {
return enif_make_badarg(env);
}
res = (${structname}*) res_tmp;
return ${member_read[$structname]};
}
__DOC__
exit 0