I'm trying to build the mapnik-german-l10n
on Ubuntu 22.04
but got the following error:
https://github.com/giggls/mapnik-german-l10n/blob/master/icutranslit/osml10n_translit.cpp
Here is the error:
make -C icutranslit
make[1]: Entering directory '/home/test/mapnik-german-l10n-master/icutranslit'
g++ -fpic -fno-exceptions -I/usr/include/postgresql/16/server -c osml10n_translit.cpp
osml10n_translit.cpp: In function ‘Datum osml10n_translit(FunctionCallInfo)’:
osml10n_translit.cpp:46:26: error: ‘VARSIZE’ was not declared in this scope
46 | inbuf=(char *) malloc((VARSIZE(t) - VARHDRSZ +1)*sizeof(char));
| ^~~~~~~
osml10n_translit.cpp:47:26: error: ‘VARDATA’ was not declared in this scope
47 | memcpy(inbuf, (void *) VARDATA(t), VARSIZE(t) - VARHDRSZ);
| ^~~~~~~
osml10n_translit.cpp:72:3: error: ‘SET_VARSIZE’ was not declared in this scope
72 | SET_VARSIZE(new_text, VARHDRSZ + bufLen);
| ^~~~~~~~~~~
make[1]: *** [Makefile:13: osml10n_translit.o] Error 1
make[1]: Leaving directory '/home/test/mapnik-german-l10n-master/icutranslit'
make: *** [Makefile:30: icutranslit] Error 2
Here is the source code:
/* needed in icu >= 62 */
#define U_USING_ICU_NAMESPACE 1
#include <iostream>
#include <unicode/unistr.h>
#include <unicode/translit.h>
extern "C" {
#include <postgres.h>
#include <stdlib.h>
#include <string.h>
#include <mb/pg_wchar.h>
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(osml10n_translit);
Datum osml10n_translit(PG_FUNCTION_ARGS) {
Transliterator *latin_tl;
UErrorCode status = U_ZERO_ERROR;
char *inbuf,*outbuf;
if (GetDatabaseEncoding() != PG_UTF8) {
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("requires UTF8 database encoding")));
}
text *t = PG_GETARG_TEXT_P(0);
inbuf=(char *) malloc((VARSIZE(t) - VARHDRSZ +1)*sizeof(char));
memcpy(inbuf, (void *) VARDATA(t), VARSIZE(t) - VARHDRSZ);
inbuf[VARSIZE(t) - VARHDRSZ]='\0';
UnicodeString ustr(inbuf);
latin_tl = Transliterator::createInstance("Any-Latin", UTRANS_FORWARD, status);
if (latin_tl == 0) {
ereport(ERROR,(errcode(ERRCODE_SYSTEM_ERROR),
errmsg("ERROR: Transliterator::createInstance() failed")));
PG_RETURN_TEXT_P("");
}
latin_tl->transliterate(ustr);
int32_t bufLen = 100;
outbuf = (char *) malloc((bufLen + 1)*sizeof(char));
status=U_ZERO_ERROR;
bufLen = ustr.extract(outbuf,bufLen,NULL,status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
outbuf = (char *) realloc(outbuf, bufLen + 1);
bufLen = ustr.extract(outbuf,bufLen,NULL,status);
}
outbuf[bufLen] = '\0';
text *new_text = (text *) palloc(VARHDRSZ + bufLen);
SET_VARSIZE(new_text, VARHDRSZ + bufLen);
memcpy((void *) VARDATA(new_text), /* destination */
(void *) outbuf,bufLen);
free(inbuf);
free(outbuf);
delete latin_tl;
PG_RETURN_TEXT_P(new_text);
}
} /* extern "C" */
I have tried to search in postgres.h
but found nothing:
/usr/include/postgresql/16/server/postgres.h
Which library contains this "VARSIZE
" and "SET_VARSIZE
"?
Update:
I found that /usr/include/postgresql/15/server/postgres.h
contains the "VARSIZE
" and "SET_VARSIZE
", but the /usr/include/postgresql/16/server/postgres.h
does not.
Here is the source code of /usr/include/postgresql/15/server/postgres.h
/* ----------------------------------------------------------------
* Section 1: variable-length datatypes (TOAST support)
* ----------------------------------------------------------------
*/
...
/*
* In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(),
* VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR(). Elsewhere, call
* PG_DETOAST_DATUM(), VARDATA() and VARSIZE(). Directly fetching an int16,
* int32 or wider field in the struct representing the datum layout requires
* aligned data. memcpy() is alignment-oblivious, as are most operations on
* datatypes, such as text, whose layout struct contains only char fields.
*
* Code assembling a new datum should call VARDATA() and SET_VARSIZE().
* (Datums begin life untoasted.)
*
* Other macros here should usually be used only by tuple assembly/disassembly
* code and code that specifically wants to work with still-toasted Datums.
*/
#define VARDATA(PTR) VARDATA_4B(PTR)
#define VARSIZE(PTR) VARSIZE_4B(PTR)
#define VARSIZE_SHORT(PTR) VARSIZE_1B(PTR)
#define VARDATA_SHORT(PTR) VARDATA_1B(PTR)
#define VARTAG_EXTERNAL(PTR) VARTAG_1B_E(PTR)
#define VARSIZE_EXTERNAL(PTR) (VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR)))
#define VARDATA_EXTERNAL(PTR) VARDATA_1B_E(PTR)
...
/* ----------------------------------------------------------------
* Section 2: Datum type + support macros
* ----------------------------------------------------------------
*/
...
typedef uintptr_t Datum;
/*
* A NullableDatum is used in places where both a Datum and its nullness needs
* to be stored. This can be more efficient than storing datums and nullness
* in separate arrays, due to better spatial locality, even if more space may
* be wasted due to padding.
*/
typedef struct NullableDatum
{
#define FIELDNO_NULLABLE_DATUM_DATUM 0
Datum value;
#define FIELDNO_NULLABLE_DATUM_ISNULL 1
bool isnull;
/* due to alignment padding this could be used for flags for free */
} NullableDatum;
...
Here is the source code of /usr/include/postgresql/16/server/postgres.h
/* ----------------------------------------------------------------
* Section 1: Datum type + support functions
* ----------------------------------------------------------------
*/
/*
* A Datum contains either a value of a pass-by-value type or a pointer to a
* value of a pass-by-reference type. Therefore, we require:
*
* sizeof(Datum) == sizeof(void *) == 4 or 8
*
* The functions below and the analogous functions for other types should be used to
* convert between a Datum and the appropriate C type.
*/
typedef uintptr_t Datum;
/*
* A NullableDatum is used in places where both a Datum and its nullness needs
* to be stored. This can be more efficient than storing datums and nullness
* in separate arrays, due to better spatial locality, even if more space may
* be wasted due to padding.
*/
typedef struct NullableDatum
{
#define FIELDNO_NULLABLE_DATUM_DATUM 0
Datum value;
#define FIELDNO_NULLABLE_DATUM_ISNULL 1
bool isnull;
/* due to alignment padding this could be used for flags for free */
} NullableDatum;
It seems that "postgresql 16
" has removed the "Section 1: variable-length datatypes (TOAST support)
" from the postgres.h
.
How to set "VARSIZE
" and "SET_VARSIZE
" in "osml10n_translit.cpp
" for making it to work in postgresql 16
?
PostgreSQL v16 moved these definitions to server/varatt.h
in commit d952373a98. So you have to
#include "varatt.h"
to get these macros from v16 on.