All Projects → jacketizer → Libnmea

jacketizer / Libnmea

Licence: mit
Lightweight C library for parsing NMEA 0183 sentences

Programming Languages

c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to Libnmea

Internettools
XPath/XQuery 3.1 interpreter for Pascal with compatibility modes for XPath 2.0/XQuery 1.0/3.0, custom and JSONiq extensions, XML/HTML parsers and classes for HTTP/S requests
Stars: ✭ 82 (-43.84%)
Mutual labels:  parser, library
Simplepie
A simple Atom/RSS parsing library for PHP.
Stars: ✭ 1,389 (+851.37%)
Mutual labels:  parser, library
Rst
PHP library to parse reStructuredText documents
Stars: ✭ 90 (-38.36%)
Mutual labels:  parser, library
Parjs
JavaScript parser-combinator library
Stars: ✭ 145 (-0.68%)
Mutual labels:  parser, parse
Typin
Declarative framework for interactive CLI applications
Stars: ✭ 126 (-13.7%)
Mutual labels:  parser, library
Parser
Generate a JSON documentation for a SFC Vue component. Contribute: https://gitlab.com/vuedoc/parser#contribute
Stars: ✭ 74 (-49.32%)
Mutual labels:  parser, parse
Argumentum
C++ command line parsing library
Stars: ✭ 92 (-36.99%)
Mutual labels:  parser, library
Anglesharp.css
👼 Library to enable support for cascading stylesheets in AngleSharp.
Stars: ✭ 27 (-81.51%)
Mutual labels:  parser, library
Commonmark Java
Java library for parsing and rendering CommonMark (Markdown)
Stars: ✭ 1,675 (+1047.26%)
Mutual labels:  parser, library
Laravel Parse
A Parse SDK bridge for Laravel 5
Stars: ✭ 116 (-20.55%)
Mutual labels:  parse, library
Anglesharp.js
👼 Extends AngleSharp with a .NET-based JavaScript engine.
Stars: ✭ 68 (-53.42%)
Mutual labels:  parser, library
Json Autotype
Automatic Haskell type inference from JSON input
Stars: ✭ 139 (-4.79%)
Mutual labels:  parser, parse
Sharpmath
A small .NET math library.
Stars: ✭ 36 (-75.34%)
Mutual labels:  parser, library
Cat
Plain C library for parsing AT commands for use in host devices.
Stars: ✭ 77 (-47.26%)
Mutual labels:  parser, library
Substitution Schedule Parser
Java library for parsing schools' substitution schedules. Supports multiple different systems mainly used in the German-speaking countries, including Untis, svPlan, and DAVINCI
Stars: ✭ 33 (-77.4%)
Mutual labels:  parser, library
Postcss Less
PostCSS Syntax for parsing LESS
Stars: ✭ 93 (-36.3%)
Mutual labels:  parser, parse
Algebra Latex
Parse and calculate latex formatted math
Stars: ✭ 20 (-86.3%)
Mutual labels:  parser, parse
Go Deb Version
A golang library for parsing deb package versions
Stars: ✭ 21 (-85.62%)
Mutual labels:  parser, library
Netcopa
Network Configuration Parser
Stars: ✭ 112 (-23.29%)
Mutual labels:  parser, parse
Phplrt
PHP Language Recognition Tool
Stars: ✭ 127 (-13.01%)
Mutual labels:  parser, library

C Library for Parsing NMEA 0183 Sentences

Build Status Memory Leaks License

Libnmea is a lightweight C library that parses NMEA 0183 sentence strings into structs. It is written in a modular architecture that dynamically loads a parser module for each implemented sentence type. This way, new sentences can easily be added to the library without modifying the core code. It is also possible to statically link the parser modules at build time to enable libnmea to be used in environments where a dynamic loader isn't available.

If you find any sentence missing, please add it by contributing to the code. I am open to suggestions regarding the code and architecture, so if you have any ideas or improvements, please tell me or submit a merge request :-).

Supported sentences: GPGGA, GPGLL, GPGSA, GPGSV, GPRMC, GPTXT, and GPVTG.

To build

$ make && make check

When running make, the library will be built to a local build directory (./build).

Installation

Run make install to install libnmea. The files will be installed in /usr/ by default. Use the environment variable PREFIX to set a different installation prefix.

Ex. to build and install the library and header files locally, in the ./target directory, run the following commands:

$ make
$ PREFIX=target make install

Try it

When the library is built and installed, you can compile the example programs:

$ make examples
$ echo -ne "\$GPGLL,4916.45,N,12311.12,W,225444,A,*1D\r\n" | build/parse_stdin

If the library was installed with a custom prefix, you may have to set the following environment variables before running make:

export LIBRARY_PATH="<prefix>/lib"
export C_INCLUDE_PATH="<prefix>/include"
export LD_LIBRARY_PATH="<prefix>/lib"

Additionally, set NMEA_PARSER_PATH variable before running the program:

export NMEA_PARSER_PATH="<prefix>/lib/nmea/"

Note that the trailing slash is required!

How to use it

First, include nmea.h and the header files for the desired sentence types:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <nmea.h>
#include <nmea/gpgll.h>
#include <nmea/gpgga.h>

int
main(void)
{
	/* ... */
	return 0;
}

To parse an NMEA sentence string, use nmea_parse():

// Sentence string to be parsed
char sentence[] = "$GPGLL,4916.45,N,12311.12,W,225444,A,*1D\r\n";

// Pointer to struct containing the parsed data
nmea_s *data;

// Parse it...
data = nmea_parse(sentence, strlen(sentence), 0);
if (NULL == data) {
	exit(EXIT_FAILURE);
}

The parsed data can be found in the data variable and for example printed to screen:

if (NMEA_GPGGA == data->type) {
	nmea_gpgga_s *gpgga = (nmea_gpgga_s *) data;

	printf("GPGGA Sentence\n");
	printf("Number of satellites: %d\n", gpgga->n_satellites);
	printf("Altitude: %d %c\n", gpgga->altitude, gpgga->altitude_unit);
}

if (NMEA_GPGLL == data->type) {
	nmea_gpgll_s *gpgll = (nmea_gpgll_s *) data;

	printf("GPGLL Sentence\n");
	printf("Longitude:\n");
	printf("  Degrees: %d\n", gpgll->longitude.degrees);
	printf("  Minutes: %f\n", gpgll->longitude.minutes);
	printf("  Cardinal: %c\n", (char) gpgll->longitude.cardinal);
	printf("Latitude:\n");
	printf("  Degrees: %d\n", gpgll->latitude.degrees);
	printf("  Minutes: %f\n", gpgll->latitude.minutes);
	printf("  Cardinal: %c\n", (char) gpgll->latitude.cardinal);
}

Free the memory used by the data variable:

nmea_free(data);

Compile with -lnmea:

$ gcc example.c -lnmea -o example

Environment variables

Run time:

NMEA_PARSER_PATH - The path where the parser libraries are located. Default is /usr/lib/nmea. If a custom prefix was used when installing, they will be located in PREFIX/lib/nmea. This variable isn't used when libnmea is built with static parser module loading (see next chapter).

Build time:

NMEA_STATIC - If defined, it forces libnmea to be built with static parser module loading (see next chapter). It should contain a comma seperated list of parser modules to be included in the build, ex: NMEA_STATIC=GPRMC,GPGGA.

Static build

It is possible to statically link the parser modules at build time which is useful when a dynamic loader isn't available. To do this, the environment variable NMEA_STATIC must be defined along with a comma-seperated list of selected parser modules to include in the library. Note that both dynamic and static module loading cannot be utilized at the same time.

$ NMEA_STATIC=GPGLL,GPRMC make

Run tests

After make, run the tests against the build directory:

$ make check

To run the unit tests against the installation directory, run the following command:

$ make unit-tests

To check for memory leaks, run:

$ make check-memory-leaks

Library functions

Check nmea.h for more detailed info about functions. The header files for the sentences (ex: nmea/gpgll.h) contains the struct definitions for each sentence.

Implement a new sentence type

To create a new sentence parser, create the following files and replace the <TYPE> with the sentence type word in uppercase letters and <type> in lowercase. Make sure that the sentence type is defined in src/nmea.h and add it to src/nmea/parser_static.h.

src/parsers/.h:

#ifndef INC_NMEA_<TYPE>_H
#define INC_NMEA_<TYPE>_H

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <nmea.h>

typedef struct {
	nmea_s base;
	/* sentence values */
} nmea_<type>_s;

/* Value indexes */
#define NMEA_<TYPE>_<index>	0
/* more value indexes... */

#endif  /* INC_NMEA_<TYPE>_H */

src/parsers/.c:

#include "../nmea/parser_types.h"
#include "<type>.h"
#include "parse.h"

int
init(nmea_parser_s *parser)
{
	/* Declare what sentence type to parse */
	NMEA_PARSER_TYPE(parser, NMEA_<TYPE>);
	NMEA_PARSER_PREFIX(parser, "<TYPE>");
	return 0;
}

int
allocate_data(nmea_parser_s *parser)
{
	parser->data = malloc(sizeof (nmea_<type>_s));
	return 0;
}

int
set_default(nmea_parser_s *parser)
{
	memset(parser->data, 0, sizeof (nmea_<type>_s));
	return 0;
}

int
free_data(nmea_s *data)
{
	free(data);
	return 0;
}

int
parse(nmea_parser_s *parser, char *value, int val_index)
{
	nmea_gpgll_s *data = (nmea_<type>_s *) parser->data;

	switch (val_index) {
	case NMEA_<TYPE>_<index>:
		/* Parse some value */
		data->some_value = value;
		break;

	default:
		break;
	}

	return 0;
}

Contributing

Contributions are more than welcome. Be sure to read this chapter before submitting a merge request.

Coding style

The code should conform to the KNF formatting guidelines.

Example indent command:

$ indent -st -bad -bap -bbb -bc -blf -bli0 -br -brs -bs -cbi0 -ce -cli0 -cs -nbfda -npcs -nprs -nsob -saf -saw -sai src/nmea/nmea.c

Use hard tabs. Example vim options:

:set noexpandtab
:set preserveindent
:set softtabstop=0
:set shiftwidth=4
:set tabstop=4

Testing

Every merge request must pass all the tests.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].