我正在尝试在
mapnik-german-l10n
上构建 Ubuntu 22.04
但出现以下错误:
https://github.com/giggls/mapnik-german-l10n/blob/master/icutranslit/osml10n_translit.cpp
错误如下:
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
这是源代码:
/* 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" */
我尝试在
postgres.h
中搜索,但什么也没找到:
/usr/include/postgresql/16/server/postgres.h
哪个库包含这个“
VARSIZE
”和“SET_VARSIZE
”?
更新:
我发现
/usr/include/postgresql/15/server/postgres.h
包含“VARSIZE
”和“SET_VARSIZE
”,但/usr/include/postgresql/16/server/postgres.h
不包含。
这里是/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;
...
这里是/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;
看来“
postgresql 16
”已经从Section 1: variable-length datatypes (TOAST support)
中删除了“postgres.h
”。
如何在“
VARSIZE
”中设置“SET_VARSIZE
”和“osml10n_translit.cpp
”以使其在postgresql 16
中工作?
PostgreSQL v16 将这些定义移至
commit d952373a98中的
server/varatt.h
。所以你必须
#include "varatt.h"
从 v16 开始获取这些宏。