Last active
August 29, 2015 14:10
-
-
Save njh/70e2ef7a6186ca67890f to your computer and use it in GitHub Desktop.
Combine the Paho MQTT-SN Embedded-C sources in a single file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# | |
# Script to combine the Paho MQTT-SN embedded-C library into a | |
# single source and header file | |
# | |
# Nicholas Humfrey | |
# Twitter: @njh | |
# | |
use strict; | |
# Clone/Update the git repo | |
if (-e 'org.eclipse.paho.mqtt-sn.embedded-c') { | |
system("cd 'org.eclipse.paho.mqtt-sn.embedded-c' && git pull") == 0 or | |
die "Failed to update the git repository"; | |
} else { | |
system("git clone 'git://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt-sn.embedded-c.git'") == 0 or | |
die "Failed to clone git repository"; | |
} | |
# The order of the header files is important | |
my @SOURCE_FILES = qw( | |
MQTTSNPacket.h | |
MQTTSNConnect.h | |
MQTTSNPublish.h | |
MQTTSNSubscribe.h | |
MQTTSNUnsubscribe.h | |
MQTTSNSearch.h | |
MQTTSNConnectClient.c | |
MQTTSNConnectServer.c | |
MQTTSNDeserializePublish.c | |
MQTTSNPacket.c | |
MQTTSNSearchClient.c | |
MQTTSNSearchServer.c | |
MQTTSNSerializePublish.c | |
MQTTSNSubscribeClient.c | |
MQTTSNSubscribeServer.c | |
MQTTSNUnsubscribeClient.c | |
MQTTSNUnsubscribeServer.c | |
); | |
my $boilerplate = ''; | |
my @includes = (); | |
my @defines = (); | |
my @definitions = (); | |
my @functions = (); | |
my @declarations = (); | |
my @enums = (); | |
my @typedefs = (); | |
foreach my $filename (@SOURCE_FILES) { | |
my $state = 'start'; | |
my $chunk = ''; | |
my $lastcomment = ''; | |
print "Parsing file: $filename\n"; | |
my $filepath = "./org.eclipse.paho.mqtt-sn.embedded-c/src/$filename"; | |
open(FILE, $filepath) or die "Failed to open file $filepath: $!"; | |
while(my $line = <FILE>) { | |
# Remove trailing whitespace | |
$line =~ s/[ \t]+$//g; | |
if ($state eq 'start' and $line =~ m|^\/\*{20,}$|) { | |
$chunk = $line; | |
$state = 'boilerplate'; | |
} elsif ($state eq 'boilerplate') { | |
$chunk .= $line; | |
if ($line =~ m|\*{20,}\/$|) { | |
$boilerplate = $chunk; | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $line =~ m|^/\*\*$|) { | |
$chunk = $line; | |
$state = 'doc'; | |
} elsif ($state eq 'doc') { | |
$chunk .= $line; | |
if ($line =~ m|\s+\*\/$|) { | |
$lastcomment = $chunk; | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $line =~ m|^[^ \t#\r/@][^\r]*\=|) { | |
$chunk = $line; | |
$state = 'definition'; | |
} elsif ($state eq 'definition') { | |
$chunk .= $line; | |
if ($line =~ m|^};\s*$|) { | |
push(@definitions, $chunk); | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $filepath =~ /\.h$/ and $line =~ m|^[^ \t#\r/@][^\r]*\(|) { | |
if ($line =~ /;$/) { | |
push(@declarations, $line); | |
} else { | |
$chunk = $line; | |
$state = 'declaration'; | |
} | |
} elsif ($state eq 'declaration') { | |
$chunk .= $line; | |
if ($line =~ m|;$|) { | |
push(@declarations, $chunk); | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $line =~ m|^enum|) { | |
$chunk = $line; | |
$state = 'enum'; | |
} elsif ($state eq 'enum') { | |
$chunk .= $line; | |
if ($line =~ m|^}.*;$|) { | |
push(@enums, $chunk); | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $line =~ m|^typedef|) { | |
$chunk = $line; | |
$state = 'typedef'; | |
} elsif ($state eq 'typedef') { | |
$chunk .= $line; | |
if ($line =~ m|^}.*;$|) { | |
push(@typedefs, $chunk); | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $filepath =~ /\.c$/ and $line =~ m|^[^ \t#\r/@][^\r]*\(|) { | |
$chunk = $line; | |
$state = 'function'; | |
} elsif ($state eq 'function') { | |
if ($line =~ /exit:/) { | |
$chunk .= "exit:\n"; | |
} elsif ($line !~ /^[\t ]+FUNC_/) { | |
$chunk .= $line; | |
} | |
if ($line =~ m|^}\s*$|) { | |
if ($lastcomment) { | |
$chunk = $lastcomment . $chunk; | |
$lastcomment = ''; | |
} | |
push(@functions, $chunk); | |
$state = 'body'; | |
} | |
} elsif ($state eq 'body' and $line =~ m|__cplusplus|) { | |
$state = 'cplusplus'; | |
} elsif ($state eq 'cplusplus') { | |
if ($line =~ m|^#endif|) { | |
$state = 'body'; | |
} | |
} elsif ($line =~ /^#include\s+".+"$/) { | |
# Ignore local includes | |
} elsif ($line =~ /^\s*$/) { | |
# Ignore blank lines | |
} elsif ($line =~ /^#if.+MQTTSN\w+_H_/) { | |
# Ignore header file if blocks | |
} elsif ($line =~ /^#define.+MQTTSN\w+_H_$/) { | |
# Ignore header file if blocks | |
} elsif ($line =~ /^#endif.+_H_/) { | |
# Ignore header file if blocks | |
} elsif ($line =~ /^#define/) { | |
my %existing = map { $_ => 1 } @defines; | |
unless(exists($existing{$line})) { | |
push(@defines, $line); | |
} | |
} elsif ($line =~ /^#include\s+<.+>$/) { | |
my %existing = map { $_ => 1 } @includes; | |
unless(exists($existing{$line})) { | |
push(@includes, $line); | |
} | |
} else { | |
print "Unknown line: $line"; | |
} | |
} | |
close(FILE); | |
if ($filepath =~ /\.h$/) { | |
push(@declarations, "\n"); | |
} | |
} | |
push(@includes, "#include <stdint.h>\n"); | |
open(OUTPUT, ">mqttsn.h") or die "Failed to open output file: $!"; | |
print OUTPUT $boilerplate; | |
print OUTPUT "\n"; | |
foreach my $include (@includes) { | |
print OUTPUT $include; | |
} | |
print OUTPUT "\n"; | |
foreach my $define (@defines) { | |
print OUTPUT $define; | |
} | |
print OUTPUT "\n"; | |
foreach my $enum (@enums) { | |
print OUTPUT "$enum\n"; | |
} | |
print OUTPUT "\n"; | |
foreach my $typedef (@typedefs) { | |
print OUTPUT "$typedef\n"; | |
} | |
print OUTPUT "\n"; | |
foreach my $declaration (@declarations) { | |
print OUTPUT $declaration; | |
} | |
close(OUTPUT); | |
open(OUTPUT, ">mqttsn.c") or die "Failed to open output file: $!"; | |
print OUTPUT $boilerplate; | |
print OUTPUT "\n"; | |
print OUTPUT "#include \"mqttsn.h\"\n"; | |
print OUTPUT "\n"; | |
foreach my $definition (@definitions) { | |
print OUTPUT $definition; | |
} | |
print OUTPUT "\n"; | |
foreach my $function (@functions) { | |
print OUTPUT "$function\n"; | |
} | |
close(OUTPUT); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment