blackghost
blackghost

Reputation: 1825

c: Convert ipv6 address to string at compile time

This is a longshot, but I'm wondering if there are any tricks to convert a constant ipv6 address string into two 64 bit integers at compile time. (this is on an embedded system, and thus runtime and memory are both valuable commodities). Ideally the code would look something like:

const uint64_t addr[2] = { IPV6_TO_UINT64S("::ffff:192.168.1.1") };

which would produce:

const uint64_t addr[2] = { 0x0000000000000000ULL, 0x0000ffffc0a80101ULL };

Upvotes: 2

Views: 430

Answers (1)

Schwern
Schwern

Reputation: 164639

For this sort of thing I'd recommend writing a template header file (not C++ templates, but fill-in-the-blank templates), putting the human-readable values in a config file, and using a small program to fill in the blanks.

For example, the config file might be in JSON. (This is obviously overkill for a single value, I'm just showing the technique.)

{
    "addr": "::ffff:192.168.1.1"
}

You could use an existing template language, or make up your own. For something as simple as a C header file, you can get away with something very simple.

const uint64_t addr[2] = { %%addr%% };

And the code to read the config and process the template simple in a ubiquitous scripting language like Ruby.

#!/usr/bin/env ruby

require 'json'

template, config_file = ARGV[0..1]

# Load the config file
config = JSON.load( File.new(config_file) )

# Ensure missing config variables throw an error
config.default_proc = proc do |hash, key|
    throw "Config key '#{key}' is missing from #{config_file}"
end

# ...do whatever processing on the config variables you want...

# Fill in the template.
IO.foreach(template) { |line|
    puts line.gsub(/%%(.*?)%%/) { config[$1] }
}

I employ this technique in the y2038 library. It has to probe the system to determine the limits of time.h, then encode those limits into a custom header file. munge_config reads the configuration values (from the build system, not from a JSON config, but the result is the same: a hash), and fills in the template. This is the time64_limits.h.in template and an example of a resulting time64_limits.h header file.

Upvotes: 1

Related Questions