N
 ­    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <head>
  <title>Index of /FSS-OZR/root/sys/dev/char/4:56/subsystem/tty2</title>
 </head>
 <body>
<h1>Index of /FSS-OZR/root/sys/dev/char/4:56/subsystem/tty2</h1>
  <table>
   <tr><th valign="top">&nbsp;</th><th><a href="?C=N;O=A">Name</a></th><th><a href="?C=M;O=D">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top">&nbsp;</td><td><a href="/FSS-OZR/root/sys/dev/char/4:56/subsystem/">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="subsystem/">subsystem/</a>             </td><td align="right">2026-10-10 14:31  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="power/">power/</a>                 </td><td align="right">2026-10-10 17:34  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="dev">dev</a>                    </td><td align="right">2026-10-10 17:41  </td><td align="right">4.0K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="uevent">uevent</a>                 </td><td align="right">2026-10-10 17:41  </td><td align="right">4.0K</td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>
 ,
    // SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>

#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"
#include <xalloc.h>
#include "lkc.h"

#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0]))

static char *expand_string_with_args(const char *in, int argc, char *argv[]);
static char *expand_string(const char *in);

static void __attribute__((noreturn)) pperror(const char *format, ...)
{
	va_list ap;

	fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
	va_start(ap, format);
	vfprintf(stderr, format, ap);
	va_end(ap);
	fprintf(stderr, "\n");

	exit(1);
}

/*
 * Environment variables
 */
static LIST_HEAD(env_list);

struct env {
	char *name;
	char *value;
	struct list_head node;
};

static void env_add(const char *name, const char *value)
{
	struct env *e;

	e = xmalloc(sizeof(*e));
	e->name = xstrdup(name);
	e->value = xstrdup(value);

	list_add_tail(&e->node, &env_list);
}

static void env_del(struct env *e)
{
	list_del(&e->node);
	free(e->name);
	free(e->value);
	free(e);
}

/* The returned pointer must be freed when done */
static char *env_expand(const char *name)
{
	struct env *e;
	const char *value;

	if (!*name)
		return NULL;

	list_for_each_entry(e, &env_list, node) {
		if (!strcmp(name, e->name))
			return xstrdup(e->value);
	}

	value = getenv(name);
	if (!value)
		return NULL;

	/*
	 * We need to remember all referenced environment variables.
	 * They will be written out to include/config/auto.conf.cmd
	 */
	env_add(name, value);

	return xstrdup(value);
}

void env_write_dep(FILE *f, const char *autoconfig_name)
{
	struct env *e, *tmp;

	list_for_each_entry_safe(e, tmp, &env_list, node) {
		fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
		fprintf(f, "%s: FORCE\n", autoconfig_name);
		fprintf(f, "endif\n");
		env_del(e);
	}
}

/*
 * Built-in functions
 */
struct function {
	const char *name;
	unsigned int min_args;
	unsigned int max_args;
	char *(*func)(int argc, char *argv[]);
};

static char *do_error_if(int argc, char *argv[])
{
	if (!strcmp(argv[0], "y"))
		pperror("%s", argv[1]);

	return xstrdup("");
}

static char *do_filename(int argc, char *argv[])
{
	return xstrdup(current_file->name);
}

static char *do_info(int argc, char *argv[])
{
	printf("%s\n", argv[0]);

	return xstrdup("");
}

static char *do_lineno(int argc, char *argv[])
{
	char buf[16];

	sprintf(buf, "%d", yylineno);

	return xstrdup(buf);
}

static char *do_shell(int argc, char *argv[])
{
	FILE *p;
	char buf[256];
	char *cmd;
