<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

#ifdef __linux__
#include <linux/limits.h>
#endif

#include "reporting.h"
#include "region.h"
#include "stringport.h"
#include "parser.h"
#include "interpreter.h"
#include "builtins.h"

#define LEN(X) (sizeof(X) / sizeof((X)[0]))

char cwd[PATH_MAX];

Builtin builtins[] = {
	{ "cd",     &builtin_cd },
	{ "set",    &builtin_set },
	{ "unset",  &builtin_unset },
	{ "source", &builtin_source },
	{ "exit",   &builtin_exit }
};

int
perform_builtin(struct AST *n)
{
	int i;

	if (n->type != NODE_COMMAND || !n->node.tokens[0])
		return 0;

	for (i = 0; i < LEN(builtins); i++)
		if (!strcmp(builtins[i].name, n->node.tokens[0])) {
			(*builtins[i].func)(n->node.tokens);
			return 1;
		}

	return 0;
}

void
builtin_cd(char **args)
{
	char *dir;

	if (!(dir = args[1]))
		if (!(dir = getenv("HOME"))) {
			report("invalid $HOME");
			return;
		}

	if (chdir(dir)) {
		report("could not change directory to [%s]", dir);
	} else {
		getcwd(cwd, PATH_MAX);
		setenv("PWD", cwd, 1);
	}
}<commit_msg>Add $OLDPWD support to cd builtin<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

#ifdef __linux__
#include <linux/limits.h>
#endif

#include "reporting.h"
#include "region.h"
#include "stringport.h"
#include "parser.h"
#include "interpreter.h"
#include "builtins.h"

#define LEN(X) (sizeof(X) / sizeof((X)[0]))

char cwd[PATH_MAX];
char owd[PATH_MAX];

Builtin builtins[] = {
	{ "cd",     &builtin_cd },
	{ "set",    &builtin_set },
	{ "unset",  &builtin_unset },
	{ "source", &builtin_source },
	{ "exit",   &builtin_exit }
};

int
perform_builtin(struct AST *n)
{
	int i;

	if (n->type != NODE_COMMAND || !n->node.tokens[0])
		return 0;

	for (i = 0; i < LEN(builtins); i++)
		if (!strcmp(builtins[i].name, n->node.tokens[0])) {
			(*builtins[i].func)(n->node.tokens);
			return 1;
		}

	return 0;
}

void
builtin_cd(char **args)
{
	char *dir;
	int isowd = 0;

	if (!(dir = args[1])) {
		if (!(dir = getenv("HOME"))) {
			report("invalid $HOME");
			return;
		}
	} else if (strcmp(dir, "-") == 0) {
		if (!(dir = getenv("OLDPWD"))) {
			report("invalid $OLDPWD");
			return;
		}
		isowd = 1;
	}

	getcwd(owd, PATH_MAX);
	if (chdir(dir)) {
		report("could not change directory to [%s]", dir);
	} else {
		getcwd(cwd, PATH_MAX);
		setenv("PWD", cwd, 1);
		setenv("OLDPWD", owd, 1);
		if (isowd)
			printf("%s\n", dir);
	}
}
{'fraction_non_alphanumeric': 0.21297037630104082, 'fraction_numerical': 0.008807045636509208, 'mean_word_length': 3.9583333333333335, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 23, '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': '1135570', 'n_tokens_mistral': 1133, 'n_tokens_neox': 1074, 'n_words': 231}