src/backend/utils/adt/json.c
/*
 * Report a CONTEXT line for bogus JSON input.
 *
 * lex->token_terminator must be set to identify the spot where we detected
 * the error.  Note that lex->token_start might be NULL, in case we recognized
 * error at EOF.
 *
 * The return value isn't meaningful, but we make it non-void so that this
 * can be invoked inside ereport().
 */
Report a CONTEXT line for bogus JSON input.
lex->token_terminator must be set to identify the spot where we detected
the error.  Note that lex->token_start might be NULL, in case we recognized
error at EOF.

The return value isn't meaningful, but we make it non-void so that this
can be invoked inside ereport().
Report a CONTEXT line for bogus JSON input . lex - > token_terminator must be set to identify the spot where we detected the error . Note that lex - > token_start might be NULL in case we recognized error at EOF . The return value isn ' t meaningful but we make it non - void so that this can be invoked inside ereport () .
static int
report_json_context(JsonLexContext *lex)
{
	const char *context_start;
	const char *context_end;
	const char *line_start;
	int			line_number;
	char	   *ctxt;
	int			ctxtlen;
	const char *prefix;
	const char *suffix;
	context_start = lex->input;
	context_end = lex->token_terminator;
	line_start = context_start;
	line_number = 1;
	for (;;)
	{
		if (context_start < context_end && *context_start == '\n')
		{
			context_start++;
			line_start = context_start;
			line_number++;
			continue;
		}
		if (context_end - context_start < 50)
			break;
		if (IS_HIGHBIT_SET(*context_start))
			context_start += pg_mblen(context_start);
		else
			context_start++;
	}
	if (context_start - line_start <= 3)
		context_start = line_start;
	ctxtlen = context_end - context_start;
	ctxt = palloc(ctxtlen + 1);
	memcpy(ctxt, context_start, ctxtlen);
	ctxt[ctxtlen] = '\0';
	prefix = (context_start > line_start) ? "..." : "";
	suffix = (lex->token_type != JSON_TOKEN_END && context_end - lex->input < lex->input_length && *context_end != '\n' && *context_end != '\r') ? "..." : "";
	return errcontext("JSON data, line %d: %s%s%s",
					  line_number, prefix, ctxt, suffix);
}
static int report_json_context ( JsonLexContext * lex ) { const char * context_start ; const char * context_end ; const char * line_start ; int line_number ; char * ctxt ; int ctxtlen ; const char * prefix ; const char * suffix ; context_start = lex -> input ; context_end = lex -> token_terminator ; line_start = context_start ; line_number = 1 ; for ( ; ; ) { if ( context_start < context_end && * context_start == ' \n ' ) { context_start ++ ; line_start = context_start ; line_number ++ ; continue ; } if ( context_end - context_start < 50 ) break ; if ( IS_HIGHBIT_SET ( * context_start ) ) context_start += pg_mblen ( context_start ) ; else context_start ++ ; } if ( context_start - line_start <= 3 ) context_start = line_start ; ctxtlen = context_end - context_start ; ctxt = palloc ( ctxtlen + 1 ) ; memcpy ( ctxt , context_start , ctxtlen ) ; ctxt [ ctxtlen ] = ' \0 ' ; prefix = ( context_start > line_start ) ? " " : " " ; suffix = ( lex -> token_type != JSON_TOKEN_END && context_end - lex -> input < lex -> input_length && * context_end != ' \n ' && * context_end != ' \r ' ) ? " " : " " ; return errcontext ( " " , line_number , prefix , ctxt , suffix ) ; }
Report a CONTEXT line for bogus JSON input.
Report a CONTEXT line for bogus JSON input .
/* Choose boundaries for the part of the input we will display */ /* Always advance over newlines */ /* Otherwise, done as soon as we are close enough to context_end */ /* Advance to next multibyte character */ /*
	 * We add "..." to indicate that the excerpt doesn't start at the
	 * beginning of the line ... but if we're within 3 characters of the
	 * beginning of the line, we might as well just show the whole line.
	 */ /* Get a null-terminated copy of the data to present */ /*
	 * Show the context, prefixing "..." if not starting at start of line, and
	 * suffixing "..." if not ending at end of line.
	 */