libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
Macros | Functions
helpers.h File Reference
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <math.h>
#include "lacf_getline_impl.h"
#include "parser_funcs.h"
#include "math_core.h"
#include "sysmacros.h"
#include "safe_alloc.h"
#include "time.h"
#include "types.h"
Include dependency graph for helpers.h:

Go to the source code of this file.

Macros

#define _LACF_GETLINE_INCLUDED
 
#define _LACF_PARSER_FUNCS_INCLUDED
 
#define IS_VALID_GEO_POS3(pos)
 
#define IS_VALID_GEO_POS2(pos)    (is_valid_lat((pos).lat) && is_valid_lon((pos).lon))
 
#define rel_hdg(hdg1, hdg2)   rel_hdg_impl(hdg1, hdg2, __FILE__, __LINE__)
 
#define DESTROY_STRLIST(comps, num)
 
#define P2ROUNDUP(x)   (-(-(x) & -(1 << highbit64(x))))
 
#define SET_BITFIELD_1(out_var, bit_mask, bit_value)
 

Functions

static bool_t is_valid_lat (double lat)
 
static bool_t is_valid_lat_polar (double lat)
 
static bool_t is_valid_lon (double lon)
 
static bool_t is_valid_elev (double elev)
 
static bool_t is_valid_alt_ft (double alt_ft)
 
static bool_t is_valid_alt_m (double alt_m)
 
static bool_t is_valid_spd (double spd)
 
static bool_t is_valid_hdg (double hdg)
 
double rel_hdg_impl (double hdg1, double hdg2, const char *file, int line)
 
static double normalize_hdg (double hdg)
 
static double normalize_hdg_rad (double hdg_rad)
 
static double normalize_lon (double lon)
 
bool_t is_valid_icao_code (const char *icao)
 
bool_t is_valid_iata_code (const char *iata)
 
const char * extract_icao_country_code (const char *icao)
 
bool_t is_valid_xpdr_code (int code)
 
bool_t is_valid_vor_freq (double freq_mhz)
 
static bool_t is_valid_vor_freq_hz (uint32_t freq_hz)
 
static bool_t is_valid_vor_freq_khz (uint32_t freq_khz)
 
bool_t is_valid_loc_freq (double freq_mhz)
 
static bool_t is_valid_loc_freq_hz (uint32_t freq_hz)
 
static bool_t is_valid_loc_freq_khz (uint32_t freq_khz)
 
bool_t is_valid_ndb_freq (double freq_khz)
 
static bool_t is_valid_ndb_freq_hz (uint32_t freq_hz)
 
bool_t is_valid_tacan_freq (double freq_mhz)
 
bool_t is_valid_rwy_ID (const char *rwy_ID)
 
void copy_rwy_ID (const char *src, char dst[4])
 
const char * airac_cycle2eff_date (int cycle)
 
time_t airac_cycle2eff_date2 (int cycle)
 
bool_t airac_cycle2exp_date (int cycle, char buf[16], time_t *cycle_end_p)
 
int airac_time2cycle (time_t t)
 
static ssize_t parser_get_next_line (FILE *fp, char **linep, size_t *linecap, unsigned *linenum)
 
static char * parser_get_next_quoted_str (FILE *fp)
 
ssize_t explode_line (char *line, char delim, char **comps, size_t capacity)
 
void append_format (char **str, size_t *sz, const char *format,...)
 
static void normalize_whitespace (char *str)
 
char ** strsplit (const char *input, const char *sep, bool_t skip_empty, size_t *num)
 
void free_strlist (char **comps, size_t num)
 
void unescape_percent (char *str)
 
char * mkpathname (const char *comp,...)
 
char * mkpathname_v (const char *comp, va_list ap)
 
void fix_pathsep (char *str)
 
char * path_last_comp_subst (const char *path, const char *replace)
 
char * path_last_comp (const char *path)
 
char * path_ext_subst (const char *path, const char *ext)
 
void path_normalize (char *path)
 
char * file2str (const char *comp,...)
 
char * file2str_ext (long *len_p, const char *comp,...)
 
char * file2str_name (long *len_p, const char *filename)
 
void * file2buf (const char *filename, size_t *bufsz)
 
ssize_t filesz (const char *filename)
 
void lacf_strlcpy (char *dest, const char *src, size_t cap)
 
static const char * lacf_basename (const char *str)
 
static ssize_t lacf_getline (char **lineptr, size_t *n, FILE *stream)
 
void strtolower (char *str)
 
void strtoupper (char *str)
 
static char * vsprintf_alloc (const char *fmt, va_list ap)
 
static char * sprintf_alloc (const char *fmt,...)
 
static int lacf_strncasecmp (const char *s1, const char *s2, size_t n)
 
static int lacf_strcasecmp (const char *s1, const char *s2)
 
static char * lacf_strcasestr (const char *haystack, const char *needle)
 
static int fixed_decimals (double x, int digits)
 
size_t utf8_char_get_num_bytes (const char *str)
 
size_t utf8_get_num_chars (const char *str)
 
static double roundmul (double x, double y)
 
static double floormul (double x, double y)
 
bool_t file_exists (const char *path, bool_t *isdir)
 
bool_t create_directory (const char *dirname)
 
bool_t create_directory_recursive (const char *dirname)
 
bool_t remove_directory (const char *dirname)
 
bool_t remove_file (const char *filename, bool_t notfound_ok)
 
char * lacf_dirname (const char *filename)
 
void lacf_qsort_r (void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
 
static bool_t lacf_gmtime_r (const time_t *tim, struct tm *tm)
 

Detailed Description

This file contains helper functions mostly concerned with text and string processing.

Definition in file helpers.h.

Macro Definition Documentation

◆ _LACF_GETLINE_INCLUDED

#define _LACF_GETLINE_INCLUDED

Definition at line 49 of file helpers.h.

◆ _LACF_PARSER_FUNCS_INCLUDED

#define _LACF_PARSER_FUNCS_INCLUDED

Definition at line 51 of file helpers.h.

◆ DESTROY_STRLIST

#define DESTROY_STRLIST (   comps,
  num 
)
Value:
do { \
free_strlist((comps), (num)); \
(comps) = NULL; \
(num) = 0; \
} while (0)

Invokes the free_strlist() function on the macro arguments and then sets both arguments to NULL and 0 respectively, to help prevent inadvertent reuse.

Definition at line 450 of file helpers.h.

◆ IS_VALID_GEO_POS2

#define IS_VALID_GEO_POS2 (   pos)     (is_valid_lat((pos).lat) && is_valid_lon((pos).lon))

Same as IS_VALID_GEO_POS3(), but for 2-space geographic coordinates without elevation.

See also
is_valid_lat()
is_valid_lon()

Definition at line 86 of file helpers.h.

◆ IS_VALID_GEO_POS3

#define IS_VALID_GEO_POS3 (   pos)
Value:
(is_valid_lat((pos).lat) && is_valid_lon((pos).lon) && \
is_valid_elev((pos).elev))
static bool_t is_valid_lat(double lat)
Definition helpers.h:93
static bool_t is_valid_lon(double lon)
Definition helpers.h:111
Returns
True if pos is a validate geographic coordinate (the latitude, longitude and elevation are sensible values). This is using the is_valid_lat(), is_valid_lon() and is_valid_elev() functions. Please note that this only accepts elevation values between -2000 and +30000. If your elevations are in, e.g. feet, 30000 is a very low max elevation value to check against. In that case, you should use IS_VALID_GEO_POS2(), or write a custom check macro that uses the is_valid_alt_ft() check function instead.
See also
is_valid_lat()
is_valid_lon()
is_valid_elev()
is_valid_alt_ft()

Definition at line 77 of file helpers.h.

◆ P2ROUNDUP

#define P2ROUNDUP (   x)    (-(-(x) & -(1 << highbit64(x))))
Returns
x rounded up to the nearest power-of-2.

Definition at line 736 of file helpers.h.

◆ rel_hdg

#define rel_hdg (   hdg1,
  hdg2 
)    rel_hdg_impl(hdg1, hdg2, __FILE__, __LINE__)

Calculates relative heading from hdg1 to hdg2. Both heading values MUST be valid headings (pass the is_valid_hdg() check), otherwise an assertion failure is triggered.

Returns
The number of degrees to turn from hdg1 to hdg2 "the shortest way". That means, if hdg2 is "to the right" of hdg1 (i.e. less than +180 degrees), the return value is in the positive range of +0 to +180 inclusive. Conversely, if the target is to the left, the return value will be between -0 and -180 inclusive. Please note that due to angle wrapping, you cannot simply add the result of rel_hdg() onto another heading and expect the result to be valid, such as:
double new_hdg = hdg1 + rel_hdg(hdg1, hdg2);
#define rel_hdg(hdg1, hdg2)
Definition helpers.h:198
The value in new_hdg could well be >360 or <0 in this case. To properly add headings together and end up with something that passes the is_valid_hdg() test again, you always want to re-normalize the result using normalize_hdg():
double new_hdg = normalize_hdg(hdg1 + rel_hdg(hdg1, hdg2));
// new_hdg will now be equivalent to hdg2
static double normalize_hdg(double hdg)
Definition helpers.h:215
See also
normalize_hdg()

Definition at line 198 of file helpers.h.

◆ SET_BITFIELD_1

#define SET_BITFIELD_1 (   out_var,
  bit_mask,
  bit_value 
)
Value:
do { \
if (bit_value) \
(out_var) |= (bit_mask); \
else \
(out_var) &= ~(bit_mask); \
} while (0)

Helper macro to either set or reset a bit field in an integer.

Parameters
out_varThe integer variable where the bitfield will be set or reset.
bit_maskA mask of the bitfield to be manipulated. These are the bits that will be set or reset.
bit_valueAn condition value. If non-zero, the bits in bit_mask will be set to 1 in out_var. If zero, the bits in bit_mask will be reset to 0 in out_var.

Example

#define FOO_FEATURE_FLAG 0x1
#define BAR_FEATURE_FLAG 0x2
int feature_flags = 0;
SET_BITFIELD_1(feature_flags, FOO_FEATURE_FLAG, B_TRUE);
// feature_flags will now be 0x1 (FOO_FEATURE_FLAG set)
SET_BITFIELD_1(feature_flags, BAR_FEATURE_FLAG, B_TRUE);
// feature_flags will now be 0x3 (FOO_FEATURE_FLAG | BAR_FEATURE_FLAG)
SET_BITFIELD_1(feature_flags, FOO_FEATURE_FLAG, B_FALSE);
// feature_flags will now be 0x2 (BAR_FEATURE_FLAG)
#define SET_BITFIELD_1(out_var, bit_mask, bit_value)
Definition helpers.h:779

A more natural way to use this macro is to use the return value of a check function the third argument:

SET_BITFIELD_1(feature_flags, FOO_FEATURE_FLAG, foo_feature_is_on());
// feature_flags will now either have FOO_FEATURE_FLAG bit set or
// cleared, depending on the return value of foo_feature_is_on().

Definition at line 779 of file helpers.h.

Function Documentation

◆ airac_cycle2eff_date()

const char * airac_cycle2eff_date ( int  cycle)

Translates an AIRAC cycle number into a shorthand start date string, from which the AIRAC cycle becomes "effective."

Parameters
cycleThe AIRAC cycle number, e.g. 2210.
Returns
A statically allocated string (which you don't need to free), describing the cycle start date in a human-readable format. For example, AIRAC cycle 2210 will return "06-OCT".

Definition at line 485 of file helpers.c.

◆ airac_cycle2eff_date2()

time_t airac_cycle2eff_date2 ( int  cycle)

Translates an AIRAC cycle number into the start time_t (Unixtime) from which the AIRAC cycle goes into effect.

Definition at line 499 of file helpers.c.

◆ airac_cycle2exp_date()

bool_t airac_cycle2exp_date ( int  cycle,
char  buf[16],
time_t *  cycle_end_p 
)

Translates an AIRAC cycle into the end date, at which the cycle expires. That is the last day on which the cycle is still valid. This will always be the 1 day before the next cycle becomes effective.

Parameters
cycleThe AIRAC cycle for which to determine the expiry date.
bufOptional output string, which will be filled with a short human-readable date description. For example, AIRAC cycle 2210 will return "02-NOV" here. If you don't need this, set this argument to NULL.
cycle_end_pOptional output parameter, which will be filled with the time_t (Unixtime) of the last second when the AIRAC cycle is still effective, i.e. 23:59:59 UTC of the last day of the AIRAC cycle. 1 second later, the next AIRAC cycle becomes effective. If you don't need this value, set this to NULL.
Returns
B_TRUE if the AIRAC cycle expiry time is known, B_FALSE otherwise.

Definition at line 526 of file helpers.c.

◆ airac_time2cycle()

int airac_time2cycle ( time_t  t)
Returns
The AIRAC cycle number which should be effective at a given time_t (Unixtime). If the cycle is unknown, returns -1 instead.

Definition at line 557 of file helpers.c.

◆ append_format()

void append_format ( char **  str,
size_t *  sz,
const char *  format,
  ... 
)

Appends a printf-like formatted string to the end of *str, reallocating the buffer as needed to contain it. The value of *str is modified to point to the appropriately reallocated buffer.

You should free the string using lacf_free() when you are done.

Example

char *str = NULL;
size_t sz = 0;
int foo = 5;
float bar = 10.5;
append_format(&str, &sz, "Hello World: %d. ", foo);
append_format(&str, &sz, "How are you %.1f?", bar);
// str = "Hello World: 5. How are you 10.5?"
void append_format(char **str, size_t *sz, const char *format,...)
Definition helpers.c:731

Definition at line 731 of file helpers.c.

◆ copy_rwy_ID()

void copy_rwy_ID ( const char *  src,
char  dst[4] 
)

Copies a runway identifier from an unknown source to a 4-character runway identifier buffer. This also performs the following transformations on the runway identifier:

  1. if the runway identifier had a trailing 'T', it is stripped
  2. if the runway was a US single-digit runway number, a '0' is prepended

The function performs no validity checking other than making sure that the output buffer is not overflown. The caller is responsible for validating the result after copy_rwy_ID() returns using is_valid_rwy_ID().

Definition at line 411 of file helpers.c.

◆ create_directory()

bool_t create_directory ( const char *  dirname)

Creates an empty directory at dirname with default permissions.

Definition at line 1261 of file helpers.c.

◆ create_directory_recursive()

bool_t create_directory_recursive ( const char *  dirname)

Same as create_directory(), but creates all intermediate directories on the way as well.

Definition at line 1292 of file helpers.c.

◆ explode_line()

ssize_t explode_line ( char *  line,
char  delim,
char **  comps,
size_t  capacity 
)
Deprecated:
Use strsplit() instead.

Breaks up a line into components delimited by a character.

Parameters
lineThe input line to break up. The buffer will be modified to insert NULs in between the components so that they can each be treated as a separate string.
delimThe delimiter character (e.g. ',').
compsA list of pointers that will be set to point to the start of each substring.
capacityThe component capacity of comps. If more input components are encountered than is space in comps, the array is not overflown.
Returns
The number of components in the input string (at least 1). If the comps array was too small, returns the number of components that would have been needed to process the input string fully as a negative value.

Definition at line 588 of file helpers.c.

◆ extract_icao_country_code()

const char * extract_icao_country_code ( const char *  icao)
Returns
The country code corresponding to an ICAO airport code. The returned string's storage is statically allocated and thus doesn't need to be freed. If the ICAO country code is not known, returns NULL instead. Also returns NULL if the passed string isn't a valid ICAO airport code.
See also
is_valid_icao_code()

Definition at line 358 of file helpers.c.

◆ file2buf()

void * file2buf ( const char *  filename,
size_t *  bufsz 
)

Reads the contents of a file and returns them in a memory buffer. Please note that this function has no limit on the size of file it will read, so you must use it with care so as not to overload the memory subsystem by trying to read a giant file which won't fit into memory.

Parameters
filenameThe full path to the file to be read.
bufszMandatory return argument, which will be filled with the number of bytes in the file.
Returns
The file's contents allocated into a memory buffer. Use lacf_free() to free the the buffer when done. If an error occurred trying to read the file, the function returns NULL instead and the errno variable will contain the exact error which occurred.

Definition at line 1134 of file helpers.c.

◆ file2str()

char * file2str ( const char *  comp,
  ... 
)
Deprecated:
Use file2str_name() instead.

Definition at line 1036 of file helpers.c.

◆ file2str_ext()

char * file2str_ext ( long *  len_p,
const char *  comp,
  ... 
)
Deprecated:
Use file2str_name() instead.

Definition at line 1055 of file helpers.c.

◆ file2str_name()

char * file2str_name ( long *  len_p,
const char *  filename 
)

Reads the contents of a file and returns them. Please note that this function should ONLY be used for text files which are less than 256MB in size. Use file2buf() to read larger files, or files containing binary data.

Parameters
len_pMandatory return argument, which will be filled with the actual length of the file in bytes (minus a terminating NUL byte). This can be larger than a simple strlen() on the return value might suggest, if the file contains a stray NUL byte somewhere inside.
filenameThe full path to the file to be read.
Returns
The contents of the file as a C string. The string is always guaranteed to be NUL-terminated. You must free this string using lacf_free() when done. If the file cannot be read, this function returns NULL instead and the errno variable will contain the exact error which occurred.
See also
file2buf()

Definition at line 1087 of file helpers.c.

◆ file_exists()

bool_t file_exists ( const char *  filename,
bool_t *  isdir 
)
Returns
B_TRUE if the file exists, B_FALSE otherwise.
Parameters
filenameThe full path to the file to check.
isdirOptional return parameter which if not NULL, will be set to indicate whether the file is a directory.

Definition at line 1222 of file helpers.c.

◆ filesz()

ssize_t filesz ( const char *  filename)
Returns
The size of the file at path filename in bytes. If the file does not exist, or the size cannot be determined, this returns -1 instead. This function doesn't open the file for reading, so don't assume that filesz() returning a valid size indicates file read access.

Definition at line 1174 of file helpers.c.

◆ fix_pathsep()

void fix_pathsep ( char *  str)

For some inexplicable reason, on Windows X-Plane can return paths via the API which are a mixture of Windows- & Unix-style path separators. This function fixes that by flipping all path separators to the appropriate type used on the host OS. This also eliminates duplicate path separators, which tends to break Windows UNC path resolution.

Definition at line 892 of file helpers.c.

◆ fixed_decimals()

static int fixed_decimals ( double  x,
int  digits 
)
static

Calculates the number of digits after a decimal point for a printf format string to make the number appear with a fixed number of digits as a whole.

Parameters
xThe input number that is to be formatted. This should be the same number as that which will be used in the printf format value.
digitsThe number of digits that the final number should have.

Example:

Say we want a number to take up room for 4 digits, adding decimal digits after the point as necessary to padd the number:

  • 0.001 becomes "0.00" - rounding is applied as appropriate
  • 0.01 becomes "0.01"
  • 0.1 becomes "0.10"
  • 1 becomes "5.00"
  • 10 becomes "10.0"
  • 100 becomes "100" - this is rounded to less than 4 digits, since adding a '.0' at the end would overflow the desired length.
  • 1000 remains as "1000"

For numbers greater than 9999, the final number will have more than 4 digits. Use the fixed_decimals() function to achieve the above effect in a printf format as follows:

double foo = 1.1;
printf("The number is %.*f\n", fixed_decimals(foo, 4), foo);
// this prints "The number is 1.10"
static int fixed_decimals(double x, int digits)
Definition helpers.h:718

Definition at line 718 of file helpers.h.

◆ floormul()

static double floormul ( double  x,
double  y 
)
static

Rounds x DOWN to the nearest multiple of y

Definition at line 745 of file helpers.h.

◆ free_strlist()

void free_strlist ( char **  comps,
size_t  num 
)

Frees a string array returned by strsplit().

Parameters
compsThe components array returned by strsplit().
numThe number of string components in comps as returned by strsplit() in the num return parameter.

Definition at line 703 of file helpers.c.

◆ is_valid_alt_ft()

static bool_t is_valid_alt_ft ( double  alt_ft)
static
Returns
True if alt_ft is a valid altitude value. That means the value is not NAN and is between MIN_ALT (-2000) and MAX_ALT (100000) inclusive. The range check is really just to make sure the value is within sensible limits.
See also
is_valid_elev()

Definition at line 139 of file helpers.h.

◆ is_valid_alt_m()

static bool_t is_valid_alt_m ( double  alt_m)
static

Variant of is_valid_alt_ft() but expects the input altitude to be in meters.

See also
is_valid_alt_ft()

Definition at line 149 of file helpers.h.

◆ is_valid_elev()

static bool_t is_valid_elev ( double  elev)
static
Returns
True if elev is a valid elevation value in meters. That means the value is not NAN and is between MIN_ELEV (-2000) and MAX_ELEV (30000) inclusive. The range check is really just to make sure the value is within sensible limits.
See also
is_valid_alt_ft()

Definition at line 123 of file helpers.h.

◆ is_valid_hdg()

static bool_t is_valid_hdg ( double  hdg)
static
Returns
True if hdg is a valid heading value. That means the value is not NAN and is between 0 and 360 (inclusive).

Definition at line 169 of file helpers.h.

◆ is_valid_iata_code()

bool_t is_valid_iata_code ( const char *  iata)

Checks if a string is a valid IATA airport code. ICAO airport codes always:

  • are 3 characters long
  • are all upper case
  • contain only the letters A-Z
  • may not start with Q

Definition at line 336 of file helpers.c.

◆ is_valid_icao_code()

bool_t is_valid_icao_code ( const char *  icao)

Checks if a string is a valid ICAO airport code. ICAO airport codes always:

  • are 4 characters long
  • are all upper case
  • contain only the letters A-Z
  • may not start with I, J, Q or X

Definition at line 312 of file helpers.c.

◆ is_valid_lat()

static bool_t is_valid_lat ( double  lat)
static
Returns
True if lat is a valid latitude value. That means the value is not NAN and lay between -90 and +90 (inclusive).

Definition at line 93 of file helpers.h.

◆ is_valid_lat_polar()

static bool_t is_valid_lat_polar ( double  lat)
static
Deprecated:
Synonym for is_valid_lat().

Definition at line 102 of file helpers.h.

◆ is_valid_loc_freq()

bool_t is_valid_loc_freq ( double  freq_mhz)
Returns
True if freq_mhz is a valid localizer station frequency in MHz:
  • sits in the 108.10-111.95 MHz band (inclusive) with correct channel spacing and
  • is NOT a VOR frequency

Definition at line 261 of file helpers.c.

◆ is_valid_loc_freq_hz()

static bool_t is_valid_loc_freq_hz ( uint32_t  freq_hz)
static

Same as is_valid_loc_freq(), but takes an integer frequency in Hz instead of a floating-point value in MHz.

See also
is_valid_loc_freq()

Definition at line 322 of file helpers.h.

◆ is_valid_loc_freq_khz()

static bool_t is_valid_loc_freq_khz ( uint32_t  freq_khz)
static

Same as is_valid_loc_freq(), but takes an integer frequency in kHz instead of a floating-point value in MHz.

See also
is_valid_loc_freq()

Definition at line 332 of file helpers.h.

◆ is_valid_lon()

static bool_t is_valid_lon ( double  lon)
static
Returns
True if lon is a valid longitude value. That means the value is not NAN and lay between -180 and +180 (inclusive).

Definition at line 111 of file helpers.h.

◆ is_valid_ndb_freq()

bool_t is_valid_ndb_freq ( double  freq_khz)
Returns
True if freq_khz is a valid NDB station frequency in kHz. NDBs do not have fixed spacing, so this only checks for whether the frequency is in a reasonable range (177 - 1750 kHz).

Definition at line 297 of file helpers.c.

◆ is_valid_ndb_freq_hz()

static bool_t is_valid_ndb_freq_hz ( uint32_t  freq_hz)
static

Same as is_valid_ndb_freq(), but takes an integer frequency in Hz instead of a floating-point value in kHz.

See also
is_valid_loc_freq()

Definition at line 343 of file helpers.h.

◆ is_valid_rwy_ID()

bool_t is_valid_rwy_ID ( const char *  rwy_ID)

Checks a runway ID for correct formatting. Runway IDs are 2- or 3-character strings conforming to the following format:

  • Two-digit runway heading between 01 and 36. Headings less than 10 are always prefixed by a '0'. "00" is NOT valid.
  • An optional parallel runway discriminator, one of 'L', 'R', 'C' or 'T'.

Definition at line 379 of file helpers.c.

◆ is_valid_spd()

static bool_t is_valid_spd ( double  spd)
static
Returns
True if spd is a valid speed value. That means the value is not NAN and is between 0 and MAX_SPD (1000) inclusive. This expects the speed value to be in knots.

Definition at line 160 of file helpers.h.

◆ is_valid_tacan_freq()

bool_t is_valid_tacan_freq ( double  freq_mhz)
Deprecated:
Rough guess for whether freq_mhz is a valid TACAN frequency.

Definition at line 280 of file helpers.c.

◆ is_valid_vor_freq()

bool_t is_valid_vor_freq ( double  freq_mhz)
Returns
True if freq_mhz is a valid VOR station frequency in MHz:
  • sits in the 108.00-117.95 MHz band (inclusive) with correct channel spacing and
  • is NOT a localizer frequency

Definition at line 233 of file helpers.c.

◆ is_valid_vor_freq_hz()

static bool_t is_valid_vor_freq_hz ( uint32_t  freq_hz)
static

Same as is_valid_vor_freq(), but takes an integer frequency in Hz instead of a floating-point value in MHz.

See also
is_valid_vor_freq()

Definition at line 300 of file helpers.h.

◆ is_valid_vor_freq_khz()

static bool_t is_valid_vor_freq_khz ( uint32_t  freq_khz)
static

Same as is_valid_vor_freq(), but takes an integer frequency in kHz instead of a floating-point value in MHz.

See also
is_valid_vor_freq()

Definition at line 310 of file helpers.h.

◆ is_valid_xpdr_code()

bool_t is_valid_xpdr_code ( int  code)
Returns
True if code is a valid transponder code in decimal format:
  • The code's numerical value is between 0 and 7777 inclusive
  • Each digit is between 0 and 7 inclusive

Definition at line 217 of file helpers.c.

◆ lacf_basename()

static const char * lacf_basename ( const char *  str)
static

Portable version of the POSIX basename() function.

See also
basename()

Definition at line 491 of file helpers.h.

◆ lacf_dirname()

char * lacf_dirname ( const char *  filename)

Portable version of the POSIX dirname() function.

See also
dirname()

Definition at line 1489 of file helpers.c.

◆ lacf_getline()

static ssize_t lacf_getline ( char **  lineptr,
size_t *  n,
FILE *  stream 
)
static

Portable version of the POSIX getline() function.

See also
getline()

Definition at line 511 of file helpers.h.

◆ lacf_gmtime_r()

static bool_t lacf_gmtime_r ( const time_t *  tim,
struct tm *  tm 
)
static

This function is a portable and thread-safe version of the gmtime() function. The problem with plain standard C gmtime() is that it is not thread-safe, because the returned argument is a pointer into a shared memory buffer, allocated inside of the standard C library. As such, time calls occurring in other threads might clobber the buffer.

The lacf_gmtime_r() function calls the platform-specific thread-safe version of gmtime(). On macOS and Linux, this uses the gmtime_r() function, whereas on Windows, this uses the _gmtime64_s() function.

Parameters
timPointer to a time_t, which is to be converted.
tmPointer to a struct tm structure, which will be filled with the broken-down UTC time corresponding to tim.
Returns
True if the underlying gmtime_r() call succeeded.
See also
gmtime()

Definition at line 846 of file helpers.h.

◆ lacf_qsort_r()

void lacf_qsort_r ( void *  base,
size_t  nmemb,
size_t  size,
int(*)(const void *, const void *, void *)  compar,
void *  arg 
)

Portable version of glibc's qsort_r() function. This is a thread-safe and reentrant version of standard C's qsort() function.

See also
qsort_r()

Definition at line 1650 of file helpers.c.

◆ lacf_strcasecmp()

static int lacf_strcasecmp ( const char *  s1,
const char *  s2 
)
static

Portable version of BSD & POSIX strcasecmp(). This is a case-insensitive variant strcmp().

See also
strcmp()
strcasecmp()

Definition at line 634 of file helpers.h.

◆ lacf_strcasestr()

static char * lacf_strcasestr ( const char *  haystack,
const char *  needle 
)
static

Portable version of BSD & POSIX strcasestr(). This is a case-insensitive variant strstr().

See also
strstr() and strcasestr()

Definition at line 645 of file helpers.h.

◆ lacf_strlcpy()

void lacf_strlcpy ( char *  dest,
const char *  src,
size_t  cap 
)

Portable version of BSD's strlcpy() function. You should use this when copying a string into a fixed-length buffer, to guarantee that the output is always NUL-terminated.

See also
strlcpy()

Definition at line 1667 of file helpers.c.

◆ lacf_strncasecmp()

static int lacf_strncasecmp ( const char *  s1,
const char *  s2,
size_t  n 
)
static

Portable version of BSD & POSIX strncasecmp(). This is a case-insensitive variant strncmp().

See also
strcmp()
strcasecmp()

Definition at line 593 of file helpers.h.

◆ mkpathname()

char * mkpathname ( const char *  comp,
  ... 
)

Allocates a file path string from individual path components. The components are provided as separate filename arguments and the list needs to be terminated with a NULL argument. The returned string must be freed using lacf_free(). The path components are separated using the appropriate path separator for the host platform ('\' on Windows, '/' on macOS and Linux).

Definition at line 833 of file helpers.c.

◆ mkpathname_v()

char * mkpathname_v ( const char *  comp,
va_list  ap 
)

Same as mkpathname() but takes a va_list argument to allow for nesting inside of another variadic function.

Definition at line 850 of file helpers.c.

◆ normalize_hdg()

static double normalize_hdg ( double  hdg)
static

Renormalizes a heading value that lies outside of the 0-360 inclusive range. Basically this takes care of undoing "angle wrapping".

Example:

normalize_hdg(90) => 90
normalize_hdg(-90) => 270
normalize_hdg(400) => 40
normalize_hdg(NAN) => NAN

Definition at line 215 of file helpers.h.

◆ normalize_hdg_rad()

static double normalize_hdg_rad ( double  hdg_rad)
static

Renormalizes a heading value that lies outside of the 0-2PI inclusive range. Basically this takes care of undoing "angle wrapping".

Example:

normalize_hdg(M_PI / 2) => M_PI / 2
normalize_hdg(-M_PI / 2) => M_PI / 2
normalize_hdg(2.5 * M_PI) => 0.5 * M_PI
normalize_hdg(NAN) => NAN

Definition at line 246 of file helpers.h.

◆ normalize_lon()

static double normalize_lon ( double  lon)
static

Renormalizes a longitude value. This is similar to normalize_hdg(), but instead of resolving angle wrapping into the 0-360 range, this resolves the output to be between -180..+180 (inclusive):

normalize_lon(100) => 100
normalize_lon(200) => -160
normalize_lon(300) => -60
normalize_lon(400) => 40
static double normalize_lon(double lon)
Definition helpers.h:279

Definition at line 279 of file helpers.h.

◆ normalize_whitespace()

static void normalize_whitespace ( char *  str)
static

Converts all whitespace in a string into plain ASCII space characters. This allows for easier splitting of a string at whitespace boundaries using functions such as strsplit(). First run the input to be split through normalize_whitespace() to make sure that any tabs are converted into plain ASCII spaces first and then use strsplit() to separate the line using the " " separator as the field delimeter.

Definition at line 434 of file helpers.h.

◆ parser_get_next_line()

static ssize_t parser_get_next_line ( FILE *  fp,
char **  linep,
size_t *  linecap,
unsigned *  linenum 
)
static

Grabs the next non-empty, non-comment line from a file, having stripped away all leading and trailing whitespace. Any tab characters are also replaced with spaces. Comments are lines that start with a '#' character. Also, any text following a '#' on a line is stripped away and considered a comment.

This function is useful for writing a custom config file parser. It can also be used to consume X-Plane OBJ and similar files, or generally any text-based data file which uses '#' for comments. See also conf_create_empty(), conf_read_file() and the conf.h file for a fully-featured config system already included with libacfutils.

Parameters
fpFile from which to retrieve the line.
linepLine buffer which will hold the new line. If the buffer pointer is set to NULL, it will be allocated. If it is not long enough, it will be expanded.
linecapThe capacity of *linep. If set to zero a new buffer is allocated.
linenumThe current line number. Will be advanced by 1 for each new line read.
Returns
The number of characters in the line (after stripping whitespace) without the terminating NUL.
See also
conf_create_empty()
conf_read_file()

Definition at line 387 of file helpers.h.

◆ parser_get_next_quoted_str()

static char * parser_get_next_quoted_str ( FILE *  fp)
static

Legacy bridge to parser_get_next_quoted_str2() function without the optional second argument.

See also
parser_get_next_quoted_str2()

Definition at line 416 of file helpers.h.

◆ path_ext_subst()

char * path_ext_subst ( const char *  path,
const char *  ext 
)

Takes ‘path’ and substitutes its path extension (any characters following the last '.') with ext. If the path doesn't contain a path extension, it is appended. The newly allocated path is returned to the caller. The caller is responsible for freeing this path using lacf_free().

Definition at line 973 of file helpers.c.

◆ path_last_comp()

char * path_last_comp ( const char *  path)

Returns the last path component of the path. If the path contains no separators, returns the entire input path. The returned value is a pointer into path, and so shouldn't be freed by the caller.

Definition at line 952 of file helpers.c.

◆ path_last_comp_subst()

char * path_last_comp_subst ( const char *  path,
const char *  replace 
)

Strips the last path component from path and replaces with with replace. Example:

char *result = path_last_comp_subst("/foo/bar", "baz");
// result = "/foo/baz"
char * path_last_comp_subst(const char *path, const char *replace)
Definition helpers.c:924

The returned value must be freed using lacf_free().

Definition at line 924 of file helpers.c.

◆ path_normalize()

void path_normalize ( char *  path)

Locates all instances of '//', '\', '..' and '.' and eliminates them from the path, resolving directory returns as necessary. This also first flips all path separators to the platform-appropriate type using fix_pathsep(). The path argument is modified in place.

Definition at line 1013 of file helpers.c.

◆ rel_hdg_impl()

double rel_hdg_impl ( double  hdg1,
double  hdg2,
const char *  file,
int  line 
)

Do not call directly. Use the rel_hdg() macro instead.

Definition at line 194 of file helpers.c.

◆ remove_directory()

bool_t remove_directory ( const char *  dirname)

Removes a directory, including all its contents.

Returns
B_TRUE if successful, B_FALSE otherwise.

Definition at line 1382 of file helpers.c.

◆ remove_file()

bool_t remove_file ( const char *  filename,
bool_t  notfound_ok 
)

Removes a single file.

Parameters
filenameFull path to the file to be removed. Please note that this must be a file and not a directory. Use remove_directory() to remove directories instead.
notfound_okIf set to B_TRUE, the function will return with a success indication, even if the file doesn't exist. Otherwise, the file not existing is considered an error.
Returns
B_TRUE if removing the file was successful (or the file didn't exist, provided that notfound_ok was set to B_TRUE).

Definition at line 1459 of file helpers.c.

◆ roundmul()

static double roundmul ( double  x,
double  y 
)
static

Rounds x to the nearest multiple of y

Definition at line 739 of file helpers.h.

◆ sprintf_alloc()

static char * sprintf_alloc ( const char *  fmt,
  ... 
)
static

Convenience function which allocates a new string of sufficient storage to hold a printf-formatted string. This removes the need to run the standard library C sprintf once to find out the length of a string, allocate storage, and then run it again to fill the storage.

Parameters
fmtFormat string conforming to printf() formatting syntax. The remaining arguments must match the requirements of the format string.
Returns
A newly allocated string holding the result of the printf operation. Please note that the allocation is done using the caller's heap allocator, so you should use the normal free() function to free the associated memory, NOT lacf_free().

Definition at line 572 of file helpers.h.

◆ strsplit()

char ** strsplit ( const char *  input,
const char *  sep,
bool_t  skip_empty,
size_t *  num 
)

Splits up an input string by a separator into individual components.

Parameters
inputThe input string to be split up.
sepThe separator string. The function looks for sequences of sep in input and any portions of the input which occur between separators are split out.
skip_emptyThis flag indicates whether to skip empty components (i.e. two occurences of the separator string which are next to each other). If set to B_TRUE, the resulting array will not contain empty strings where two consecutive separators were in the input.
numA mandatory return parameter, which will be set to the number of components in the output array.
Returns
An array of strings and the number of components in the ‘num’ return parameter. The array of strings must be freed by the caller using the free_strlist() function.

Example usage with skip_empty set to B_FALSE:

const char *input = "foo,bar,,baz";
size_t num;
char **comps = strsplit(input, ",", B_FALSE, &num);
// comps = { "foo", "bar", "", "baz" } and num = 4
// Free the result when done
free_strlist(comps, num);
char ** strsplit(const char *input, const char *sep, bool_t skip_empty, size_t *num)
Definition helpers.c:650
void free_strlist(char **comps, size_t num)
Definition helpers.c:703

Example of effect of skip_empty argument:

const char *input = "foo,bar,,baz";
size_t num;
char **comps = strsplit(input, ",", B_TRUE, &num);
// comps = { "foo", "bar", "baz" } and num = 3
// Free the result when done
free_strlist(comps, num);

Definition at line 650 of file helpers.c.

◆ strtolower()

void strtolower ( char *  str)

Converts all characters in str to lowercase using tolower().

Definition at line 773 of file helpers.c.

◆ strtoupper()

void strtoupper ( char *  str)

Converts all characters in str to uppercase using toupper().

Definition at line 783 of file helpers.c.

◆ unescape_percent()

void unescape_percent ( char *  str)

Unescapes a string that uses 'XX' escape sequences, where 'XX' are two hex digits denoting the ASCII code of the character to be inserted in place of the escape sequence. The argument str is shortened appropriately.

Definition at line 753 of file helpers.c.

◆ utf8_char_get_num_bytes()

size_t utf8_char_get_num_bytes ( const char *  str)

Given a pointer to a single UTF-8-encoded character, returns the number of bytes occupied by the character. Please note that this doesn't go through the entire string, but instead only looks at a single character. Use utf_get_num_chars() to count the number of characters in an entire UTF-8 string

Definition at line 797 of file helpers.c.

◆ utf8_get_num_chars()

size_t utf8_get_num_chars ( const char *  str)

Counts the number of characters in a UTF-8-encoded string. Please note that due to the multi-byte nature of UTF-8, this can be less than the number of bytes occupied by the string. The input string MUST be NUL-terminated.

Definition at line 816 of file helpers.c.

◆ vsprintf_alloc()

static char * vsprintf_alloc ( const char *  fmt,
va_list  ap 
)
static

Variant of sprintf_alloc(), but which takes a va_list argument list as its second argument, to allow nesting it in other variadic functions.

Parameters
fmtFormat string conforming to printf() formatting syntax. The remaining arguments must match the requirements of the format string.
apArgument list containing all the arguments required by fmt.
Returns
A newly allocated string holding the result of the printf operation. Please note that the allocation is done using the caller's heap allocator, so you should use the normal free() function to free the associated memory, NOT lacf_free().

Definition at line 540 of file helpers.h.