npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ioctl-enum

v1.0.7

Published

C++ macro oriented framework in single header file for easier export of ioctl numbers to JavaScript and TypeScript. Removes the need of building native C++ Node.js Addons

Downloads

18

Readme

ioctl-enum

C++ macro oriented framework in single header file for easier export of ioctl numbers to JavaScript and TypeScript. Removes the need of building native C++ Node.js Addons

npm version license

Installation

Install with npm:

$ npm install ioctl-enum

NPM

Usage

Before including the header file:

#include "node_modules/ioctl-enum/ioctl-enum.h"

Define for which language you want to export for: (JavaScript, TypeScript or both) (see FAQ why defines must be before including the header):

JavaScript

#define IOCTL_ENUM_JS

TypeScript

#define IOCTL_ENUM_TS

API

IOCTL_ENUM(name), name <String>

Give a name to your enum:

IOCTL_ENUM("SomeName");

IOCTL_ENUM_IOCTL(ioctl_key, ioctl_value), ioctl_key <String>, ioctl_value <unsigned long> (_IO, _IOR, _IOW, _IOWR)

Add ioctl numbers to your enum:

IOCTL_ENUM("IOCTL_NUMBER", IOCTL_NUMBER);

IOCTL_ENUM_EXPORT()

Export your enum to language/s you defined with IOCTL_ENUM_[J/T]S:

IOCTL_ENUM_EXPORT();

Compile the file with g++ and C++11 Standart turned on (see FAQ why only g++ can be used) and run it:

g++ -std=c++11 <program name>.c/cc/cpp
./a.out

This will generate SomeName.[j/t]s file/s depending on the language of your choice.

Example

Consider the following abient kernel device driver header:

// ara_tester_ioctl.h
#ifndef _ARA_TESTER_H
#define _ARA_TESTER_H

#ifdef __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/errno.h>
#include "ara_tester_axis.h"

static int on_open(struct inode* inode, struct file* file);
static int on_release(struct inode* inode, struct file* file);
static long on_unlocked_ioctl(struct file * file, unsigned int command, unsigned long arguemnt);
static int __init on_init(void);
static void on_exit(void);

#else

#include <sys/ioctl.h>

#endif

#define ARA_TESTER_MAGIC_NUMBER '?'

#define _ARA_TESTER_DEFINE_IOCTL(action, number) _IO##action(ARA_TESTER_MAGIC_NUMBER, number, unsigned long)

#define ARA_TESTER_PAUSE _IO(ARA_TESTER_MAGIC_NUMBER, 0)
#define ARA_TESTER_RESUME _IO(ARA_TESTER_MAGIC_NUMBER, 1)

#define ARA_TESTER_SET_DIR _ARA_TESTER_DEFINE_IOCTL(W, 2)
#define ARA_TESTER_SET_T_MAX _ARA_TESTER_DEFINE_IOCTL(W, 3)
#define ARA_TESTER_SET_T_MIN _ARA_TESTER_DEFINE_IOCTL(W, 4)
#define ARA_TESTER_SET_T_DELTA _ARA_TESTER_DEFINE_IOCTL(W, 5)
#define ARA_TESTER_SET_LINEAR _ARA_TESTER_DEFINE_IOCTL(W, 6)

#define ARA_TESTER_GET_ACTIVE _ARA_TESTER_DEFINE_IOCTL(R, 7)
#define ARA_TESTER_GET_PAUSE _ARA_TESTER_DEFINE_IOCTL(R, 8)
#define ARA_TESTER_GET_TOTAL _ARA_TESTER_DEFINE_IOCTL(R, 9)
#define ARA_TESTER_GET_COUNTER _ARA_TESTER_DEFINE_IOCTL(R, 10)
#define ARA_TESTER_GET_MOVMENT_STATE _ARA_TESTER_DEFINE_IOCTL(R, 11)
#define ARA_TESTER_EXEC _ARA_TESTER_DEFINE_IOCTL(R, 12)

#define ARA_TESTER_LAST_IOCTL 12

#endif

JavaScript:

// export_ioctl_js.cc
#define IOCTL_ENUM_JS
#include "node_modules/ioctl-enum/ioctl-enum.h"
#include <ara_tester_ioctl.h>

IOCTL_ENUM("ARA_TESTER");
IOCTL_ENUM_IOCTL("ARA_TESTER_PAUSE", ARA_TESTER_PAUSE);
IOCTL_ENUM_IOCTL("ARA_TESTER_RESUME", ARA_TESTER_RESUME);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_DIR", ARA_TESTER_SET_DIR);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_MAX", ARA_TESTER_SET_T_MAX);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_MIN", ARA_TESTER_SET_T_MIN);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_DELTA", ARA_TESTER_SET_T_DELTA);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_LINEAR", ARA_TESTER_SET_LINEAR);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_ACTIVE", ARA_TESTER_GET_ACTIVE);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_PAUSE", ARA_TESTER_GET_PAUSE);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_TOTAL", ARA_TESTER_GET_TOTAL);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_COUNTER", ARA_TESTER_GET_COUNTER);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_MOVMENT_STATE", ARA_TESTER_GET_MOVMENT_STATE);
IOCTL_ENUM_IOCTL("ARA_TESTER_EXEC", ARA_TESTER_EXEC);
IOCTL_ENUM_EXPORT();
g++ -std=c++11 export_ioctl_js.cc
./a.out
// ARA_TESTER.js
exports.ARA_TESTER = {
	ARA_TESTER_PAUSE: 16128,
	ARA_TESTER_RESUME: 16129,
	ARA_TESTER_SET_DIR: 1074282242,
	ARA_TESTER_SET_T_MAX: 1074282243,
	ARA_TESTER_SET_T_MIN: 1074282244,
	ARA_TESTER_SET_T_DELTA: 1074282245,
	ARA_TESTER_SET_LINEAR: 1074282246,
	ARA_TESTER_GET_ACTIVE: 2148024071,
	ARA_TESTER_GET_PAUSE: 2148024072,
	ARA_TESTER_GET_TOTAL: 2148024073,
	ARA_TESTER_GET_COUNTER: 2148024074,
	ARA_TESTER_GET_MOVMENT_STATE: 2148024075,
	ARA_TESTER_EXEC: 2148024076
};

And then require and use the generated object:

// In JavaScript
const { ARA_TESTER } = require('./ARA_TESTER');
console.log(ARA_TESTER.ARA_TESTER_EXEC);

TypeScript:

// export_ioctl_ts.cc
#define IOCTL_ENUM_TS
#include "node_modules/ioctl-enum/ioctl-enum.h"
#include <ara_tester_ioctl.h>

IOCTL_ENUM("ARA_TESTER");
IOCTL_ENUM_IOCTL("ARA_TESTER_PAUSE", ARA_TESTER_PAUSE);
IOCTL_ENUM_IOCTL("ARA_TESTER_RESUME", ARA_TESTER_RESUME);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_DIR", ARA_TESTER_SET_DIR);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_MAX", ARA_TESTER_SET_T_MAX);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_MIN", ARA_TESTER_SET_T_MIN);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_T_DELTA", ARA_TESTER_SET_T_DELTA);
IOCTL_ENUM_IOCTL("ARA_TESTER_SET_LINEAR", ARA_TESTER_SET_LINEAR);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_ACTIVE", ARA_TESTER_GET_ACTIVE);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_PAUSE", ARA_TESTER_GET_PAUSE);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_TOTAL", ARA_TESTER_GET_TOTAL);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_COUNTER", ARA_TESTER_GET_COUNTER);
IOCTL_ENUM_IOCTL("ARA_TESTER_GET_MOVMENT_STATE", ARA_TESTER_GET_MOVMENT_STATE);
IOCTL_ENUM_IOCTL("ARA_TESTER_EXEC", ARA_TESTER_EXEC);
IOCTL_ENUM_EXPORT();
g++ -std=c++11 export_ioctl_ts.cc
./a.out
// ARA_TESTER.ts
export const enum ARA_TESTER {
	ARA_TESTER_PAUSE = 16128,
	ARA_TESTER_RESUME = 16129,
	ARA_TESTER_SET_DIR = 1074282242,
	ARA_TESTER_SET_T_MAX = 1074282243,
	ARA_TESTER_SET_T_MIN = 1074282244,
	ARA_TESTER_SET_T_DELTA = 1074282245,
	ARA_TESTER_SET_LINEAR = 1074282246,
	ARA_TESTER_GET_ACTIVE = 2148024071,
	ARA_TESTER_GET_PAUSE = 2148024072,
	ARA_TESTER_GET_TOTAL = 2148024073,
	ARA_TESTER_GET_COUNTER = 2148024074,
	ARA_TESTER_GET_MOVMENT_STATE = 2148024075,
	ARA_TESTER_EXEC = 2148024076
};

And then require and use the generated const enum:

// In TypeScript
import { ARA_TESTER } from './ARA_TESTER';
console.log(ARA_TESTER.ARA_TESTER_EXEC);

Both:

Just add both defines before any including:

#define IOCTL_ENUM_JS
#define IOCTL_ENUM_TS

For full working example code visit: (https://github.com/NoHomey/nodejs-ioctl-example)

Warning

Add ioctl-enum's ioctls exporting to your building. Generate the TypeScript enum/ JavaScript object for each machine your project will be running at, ioctl-enum just uses the result of _IO, _IOR, _IOW, _IOWR macros wich is unsigned long C number and it differs at different Unixes, Distributions and versions. Just like you would build the native C++ Addon that wrapps the ioctl numbers on each machine !!!

This is why:

// Ran on my laptop (Ubuntu 16.04)
// ARA_TESTER.ts
export const enum ARA_TESTER {
	ARA_TESTER_PAUSE = 16128,
	ARA_TESTER_RESUME = 16129,
	ARA_TESTER_SET_DIR = 1074282242,
	ARA_TESTER_SET_T_MAX = 1074282243,
	ARA_TESTER_SET_T_MIN = 1074282244,
	ARA_TESTER_SET_T_DELTA = 1074282245,
	ARA_TESTER_SET_LINEAR = 1074282246,
	ARA_TESTER_GET_ACTIVE = 2148024071,
	ARA_TESTER_GET_PAUSE = 2148024072,
	ARA_TESTER_GET_TOTAL = 2148024073,
	ARA_TESTER_GET_COUNTER = 2148024074,
	ARA_TESTER_GET_MOVMENT_STATE = 2148024075,
	ARA_TESTER_EXEC = 2148024076
};
// Ran on my Raspberry Pi 2 B+ (Raspbian May 2016 2016-05-27 4.4.1.17)
// ARA_TESTER.ts
export const enum ARA_TESTER {
	ARA_TESTER_PAUSE = 16128,
	ARA_TESTER_RESUME = 16129,
	ARA_TESTER_SET_DIR = 1074020098,
	ARA_TESTER_SET_T_MAX = 1074020099,
	ARA_TESTER_SET_T_MIN = 1074020100,
	ARA_TESTER_SET_T_DELTA = 1074020101,
	ARA_TESTER_SET_LINEAR = 1074020102,
	ARA_TESTER_GET_ACTIVE = 2147761927,
	ARA_TESTER_GET_PAUSE = 2147761928,
	ARA_TESTER_GET_TOTAL = 2147761929,
	ARA_TESTER_GET_COUNTER = 2147761930,
	ARA_TESTER_GET_MOVMENT_STATE = 2147761931,
	ARA_TESTER_EXEC = 2147761932
};

FAQ

Why using ioctl-enum instead of writing C++ addon ?

A: Well beacuse just for exporting N ioctl numbers to Node.js you will write alot of code for just creating a JavaScript Object why not let ioctl-enum do it for you ? Also exporting with ioctl-enum is going to cost you N + 4 lines of code just to export you ioctls so you can controll your device driver from Node.js.

Q: Why defines must be before including the header file ?

A: Because they tell the framework for which language to implement exporting functionality. The header file is structured like this:

#define IOCTL_ENUM_OPERATION_SINGLE(arg1, arg2) /* ... */

#ifdef IOCTL_ENUM_X

#define _IOCTL_ENUM_OPERATION_X()   _IOCTL_ENUM_OPERATION_SINGLE(arg1, arg2)

#else

IOCTL_ENUM_OPERATION_X()   _IOCTL_ENUM_DO_NOP()

#endif

#define IOCTL_ENUM_OPERATION() \
	_IOCTL_ENUM_OPERATION_X(); \
	_IOCTL_ENUM_OPERATION_Y() \

Which is the only way to simulate the language agnostic construction:

if(X) {
/* ... */
}

Also this way the code is modular it's easy to add more exporting formats for more languages (eg. JSON).

Q: Why g++ is the only supported compiler ?

A: Alot of gcc and respectively g++ hacks are used in to make the framework as easy to use as possible (eg. operators #, ##) Also g++ is avalible for all unixes and unix is the platform where ioctls are used in first place so there shouldn't be a problem whith g++ beeing required.

Q: Which versions of g++ are supported ?

A: g++ with version above 4.8 is garanted to work since it's C++11 future complete. Earlier versions may work as well infact any version that supports std::to_string will work.

Q: How ioctl-enum works ?

A: Using IOCTL_ENUM, IOCTL_ENUM_IOCTL and IOCTL_ENUM_EXPORT forms a whole C++ program that has it's own int main function wich generates strings as you use IOCTL_ENUM and IOCTL_ENUM_IOCTL and than writes these strings to files when you call IOCTL_ENUM_EXPORT.

Under the hood: this is how int main function would looked like if ioctl numbers from exaple were exported both to JavaScript and TypeScript:

int main(void) {
	std::ofstream out_file;
	std::string enum_name = "ARA_TESTER";
	std::string f_name;
	std::string tmp;
	std::string str_js = "exports.";
	str_js += enum_name;
	str_js += " = {\n";
	std::string str_ts = "export const enum ";
	str_ts += enum_name;
	str_ts += "{\n";;
	str_js += "\t";
	str_js += "ARA_TESTER_PAUSE";
	str_js += ": ";
	str_js += std::to_string((((0U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((0)) << 0) | ((0) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_PAUSE";
	str_ts += " = ";
	str_ts += std::to_string((((0U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((0)) << 0) | ((0) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_RESUME";
	str_js += ": ";
	str_js += std::to_string((((0U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((1)) << 0) | ((0) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_RESUME";
	str_ts += " = ";
	str_ts += std::to_string((((0U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((1)) << 0) | ((0) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_SET_DIR";
	str_js += ": ";
	str_js += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((2)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_SET_DIR";
	str_ts += " = ";
	str_ts += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((2)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_SET_T_MAX";
	str_js += ": ";
	str_js += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((3)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_SET_T_MAX";
	str_ts += " = ";
	str_ts += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((3)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_SET_T_MIN";
	str_js += ": ";
	str_js += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((4)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_SET_T_MIN";
	str_ts += " = ";
	str_ts += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((4)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_SET_T_DELTA";
	str_js += ": ";
	str_js += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((5)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_SET_T_DELTA";
	str_ts += " = ";
	str_ts += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((5)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_SET_LINEAR";
	str_js += ": ";
	str_js += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((6)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_SET_LINEAR";
	str_ts += " = ";
	str_ts += std::to_string((((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((6)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_GET_ACTIVE";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((7)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_GET_ACTIVE";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((7)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_GET_PAUSE";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((8)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_GET_PAUSE";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((8)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_GET_TOTAL";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((9)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_GET_TOTAL";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((9)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_GET_COUNTER";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((10)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_GET_COUNTER";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((10)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_GET_MOVMENT_STATE";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((11)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_GET_MOVMENT_STATE";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((11)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	str_js += "\t";
	str_js += "ARA_TESTER_EXEC";
	str_js += ": ";
	str_js += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((12)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_js += ",\n";
	str_ts += "\t";
	str_ts += "ARA_TESTER_EXEC";
	str_ts += " = ";
	str_ts += std::to_string((((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) | (((12)) << 0) | ((((sizeof(unsigned long)))) << ((0 +8)+8))));
	str_ts += ",\n";
	tmp = str_js;
	tmp.pop_back();
	tmp.pop_back();
	tmp += "\n};\n";
	f_name = enum_name;
	f_name += ".";
	f_name += "js";
	out_file.open(f_name.c_str());
	out_file << tmp;
	out_file.close();
	tmp = str_ts;
	tmp.pop_back();
	tmp.pop_back();
	tmp += "\n};\n";
	f_name = enum_name;
	f_name += ".";
	f_name += "ts";
	out_file.open(f_name.c_str());
	out_file << tmp;
	out_file.close();
	return 0;
};

You can check for fun yours with the following Node.js code:

// get_main.js 
// node get_main.js export_ioctl_both.cc 
var fs = require('fs');
var { exec } = require('child_process');
var program = process.argv[2];
exec(`g++ -std=c++11 -E ${program}`, {maxBuffer: 100000000000}, (err, out) => {
    if (err) {
        console.error(err);
    } else {
        var remove = '\n\# [0-9]+ \"' + program + '\"( [0-9]+ [0-9]+)?\n';
        out = out.substr(out.indexOf("int main"), out.length);
        out = out.replace(new RegExp(remove, 'g'), '');
        out = out.replace(/; /g, ';\n');
        out = out.replace(/ std::ofstream/g, '\nstd::ofstream');
        for(var c of 'stdfor') {
            out = out.replace(new RegExp('\n' + c, 'g'), '\n\t' + c);
        }
        console.log(out);
    }
});

Q: Why ioctl_enum.h ends with two new lines?

A: Because last charecter in it is \ and according to C and C++ standart:

If a source file that is not empty does not end in a new-line character, or ends in a new-line character immediately preceded by a backslash character, the behavior is undefined.

Also gcc and g++ respectivly both warns about this, so to be able to have fully generated int main this is a requirement.