<commit_before>
#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "../inc/sizes.h"
#include "../inc/cc.h"
#include "cc1.h"

#ifndef PREFIX
#define PREFIX "/usr/include/local"
#endif

static char *argp, *macroname;
static unsigned arglen;
static Symbol *symline, *symfile;
static unsigned char ifstatus[NR_COND];
static Type *charptype;

unsigned cppctx;
int disexpand;

static Symbol *
defmacro(char *s)
{
	Symbol *sym;

	strcpy(yytext, s);
	sym = lookup(NS_CPP);
	sym->flags |= ISDEFINED;
	return sym;
}

void
icpp(void)
{
	static char sdate[17], stime[14];
	struct tm *tm;
	time_t t;

	t = time(NULL);
	tm = localtime(&t);
	strftime(sdate, sizeof(sdate), "-1#\"%b %d %Y\"", tm);
	strftime(stime, sizeof(stime), "-1#\"%H:%M:%S\"", tm);

	defmacro("__STDC__")->u.s = "-1#1";
	defmacro("__DATE__")->u.s = sdate;
	defmacro("__TIME__")->u.s = stime;
	defmacro("__STDC_HOSTED__")->u.s = "-1#1";
	defmacro("__STDC_VERSION__")->u.s = "-1#199409L";
	symline = defmacro("__LINE__");
	symfile = defmacro("__FILE__");
}

static void
nextcpp(void)
{
	next();
	if (yytoken == EOFTOK)
		error("unterminated argument list invoking macro \"%s\"",
		      macroname);
	if (yylen + 1 > arglen)
		error("argument overflow invoking macro \"%s\"",
		      macroname);
	memcpy(argp, yytext, yylen);
	argp += yylen;
	*argp++ = ' ';
	arglen -= yylen + 1;
}

static void
paren(void)
{
	for (;;) {
		nextcpp();
		switch (yytoken) {
		case ')':
			return;
		case '(':
			paren();
			break;
		}
	}
}

static void
parameter(void)
{
	for (;;) {
		nextcpp();
		switch (yytoken) {
		case ')':
		case ',':
			argp -= 3;  /* remove " , "  or " ) "*/
			*argp++ = '\0';
			return;
		case '(':
			paren();
			break;
		}
	}
}

static int
parsepars(char *buffer, char **listp, int nargs)
{
	int n;

	if (nargs == -1)
		return -1;
	if (ahead() != '(' && nargs > 0)
		return 0;

	disexpand = 1;
	next();
	n = 0;
	argp = buffer;
	arglen = INPUTSIZ;
	if (yytoken != ')') {
		do {
			*listp++ = argp;
			parameter();
		} while (++n < NR_MACROARG && yytoken == ',');
	}
	if (yytoken != ')')
		error("incorrect macro function alike invocation");
	disexpand = 0;

	if (n == NR_MACROARG)
		error("too much parameters in macro \"%s\"", macroname);
	if (n != nargs) {
		error("macro \"%s\" passed %d arguments, but it takes %d",
		      macroname, n, nargs);
	}

	return 1;
}

static void
copymacro(char *bp, char *s, size_t bufsiz, char *arglist[])
{
	char prevc, c, *arg;

	for (prevc = '\0'; c = *s; prevc = c, ++s) {
		if (c != '@') {
			if (c == '#')
				continue;
			if (bufsiz-- == 0)
				goto expansion_too_long;
			*bp++ = c;
		} else {
			size_t size;

			if (prevc == '#')
				bufsiz -= 2;
			arg = arglist[atoi(++s)];
			size = strlen(arg);
			if (size > bufsiz)
				goto expansion_too_long;
			if (prevc == '#')
				*bp++ = '"';
			memcpy(bp, arg, size);
			bp += size;
			if (prevc == '#')
				*bp++ = '"';
			bufsiz -= size;
			s += 2;
		}
	}
	*bp = '\0';

	return;

expansion_too_long:
	error("expansion of macro \"%s\" is too long", macroname);
}

#define BUFSIZE ((INPUTSIZ > FILENAME_MAX+2) ? INPUTSIZ : FILENAME_MAX+2)
bool
expand(char *begin, Symbol *sym)
{
	size_t len;
	int n;
	char *s = sym->u.s;
	char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];

	fprintf(stderr, "macro '%s':%s\n", sym->name, sym->u.s);
	if (sym == symfile) {
		sprintf(buffer, "\"%s\"", input->fname);
		goto print_subs;
	}
	if (sym == symline) {
		sprintf(buffer, "%d", input->line);
		goto print_subs;
	}
<commit_msg>expand: fix %d -> %s format string for char * line, check truncation or error<commit_after>
#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "../inc/sizes.h"
#include "../inc/cc.h"
#include "cc1.h"

#ifndef PREFIX
#define PREFIX "/usr/include/local"
#endif

static char *argp, *macroname;
static unsigned arglen;
static Symbol *symline, *symfile;
static unsigned char ifstatus[NR_COND];
static Type *charptype;

unsigned cppctx;
int disexpand;

static Symbol *
defmacro(char *s)
{
	Symbol *sym;

	strcpy(yytext, s);
	sym = lookup(NS_CPP);
	sym->flags |= ISDEFINED;
	return sym;
}

void
icpp(void)
{
	static char sdate[17], stime[14];
	struct tm *tm;
	time_t t;

	t = time(NULL);
	tm = localtime(&t);
	strftime(sdate, sizeof(sdate), "-1#\"%b %d %Y\"", tm);
	strftime(stime, sizeof(stime), "-1#\"%H:%M:%S\"", tm);

	defmacro("__STDC__")->u.s = "-1#1";
	defmacro("__DATE__")->u.s = sdate;
	defmacro("__TIME__")->u.s = stime;
	defmacro("__STDC_HOSTED__")->u.s = "-1#1";
	defmacro("__STDC_VERSION__")->u.s = "-1#199409L";
	symline = defmacro("__LINE__");
	symfile = defmacro("__FILE__");
}

static void
nextcpp(void)
{
	next();
	if (yytoken == EOFTOK)
		error("unterminated argument list invoking macro \"%s\"",
		      macroname);
	if (yylen + 1 > arglen)
		error("argument overflow invoking macro \"%s\"",
		      macroname);
	memcpy(argp, yytext, yylen);
	argp += yylen;
	*argp++ = ' ';
	arglen -= yylen + 1;
}

static void
paren(void)
{
	for (;;) {
		nextcpp();
		switch (yytoken) {
		case ')':
			return;
		case '(':
			paren();
			break;
		}
	}
}

static void
parameter(void)
{
	for (;;) {
		nextcpp();
		switch (yytoken) {
		case ')':
		case ',':
			argp -= 3;  /* remove " , "  or " ) "*/
			*argp++ = '\0';
			return;
		case '(':
			paren();
			break;
		}
	}
}

static int
parsepars(char *buffer, char **listp, int nargs)
{
	int n;

	if (nargs == -1)
		return -1;
	if (ahead() != '(' && nargs > 0)
		return 0;

	disexpand = 1;
	next();
	n = 0;
	argp = buffer;
	arglen = INPUTSIZ;
	if (yytoken != ')') {
		do {
			*listp++ = argp;
			parameter();
		} while (++n < NR_MACROARG && yytoken == ',');
	}
	if (yytoken != ')')
		error("incorrect macro function alike invocation");
	disexpand = 0;

	if (n == NR_MACROARG)
		error("too much parameters in macro \"%s\"", macroname);
	if (n != nargs) {
		error("macro \"%s\" passed %d arguments, but it takes %d",
		      macroname, n, nargs);
	}

	return 1;
}

static void
copymacro(char *bp, char *s, size_t bufsiz, char *arglist[])
{
	char prevc, c, *arg;

	for (prevc = '\0'; c = *s; prevc = c, ++s) {
		if (c != '@') {
			if (c == '#')
				continue;
			if (bufsiz-- == 0)
				goto expansion_too_long;
			*bp++ = c;
		} else {
			size_t size;

			if (prevc == '#')
				bufsiz -= 2;
			arg = arglist[atoi(++s)];
			size = strlen(arg);
			if (size > bufsiz)
				goto expansion_too_long;
			if (prevc == '#')
				*bp++ = '"';
			memcpy(bp, arg, size);
			bp += size;
			if (prevc == '#')
				*bp++ = '"';
			bufsiz -= size;
			s += 2;
		}
	}
	*bp = '\0';

	return;

expansion_too_long:
	error("expansion of macro \"%s\" is too long", macroname);
}

#define BUFSIZE ((INPUTSIZ > FILENAME_MAX+2) ? INPUTSIZ : FILENAME_MAX+2)
bool
expand(char *begin, Symbol *sym)
{
	size_t len;
	int n, r;
	char *s = sym->u.s;
	char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];

	fprintf(stderr, "macro '%s':%s\n", sym->name, sym->u.s);
	if (sym == symfile) {
		sprintf(buffer, "\"%s\"", input->fname);
		goto print_subs;
	}
	if (sym == symline) {
		r = snprintf(buffer, sizeof(buffer), "%s", input->line);
		if(r == -1 || (size_t)r >= sizeof(buffer)) {
			error("expansion of macro \"%s\" is too long", sym->name);
			return 0;
		}
		goto print_subs;
	}

{'fraction_non_alphanumeric': 0.2057228098725251, 'fraction_numerical': 0.010306482234879306, 'mean_word_length': 3.3204452255418864, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3764767', 'n_tokens_mistral': 3419, 'n_tokens_neox': 3137, 'n_words': 753}