blob: 2aac6ec4383113f84555e6ac2b8aaa53fd9c797d [file] [log] [blame]
/* Copyright 2012 Google LLC
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google LLC nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* platform.c: platform interface routines
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mosys/alloc.h"
#include "mosys/globals.h"
#include "mosys/kv_pair.h"
#include "mosys/log.h"
#include "mosys/platform.h"
#include "mosys/output.h"
#include "lib/string.h"
#ifndef LINE_MAX
#define LINE_MAX 64
#endif
struct platform_intf *platform_intf = NULL;
/*
* mosys_platform_setup - identify platform, setup interfaces and commands
*
* returns pointer to identified platform interface
* returns NULL if platform not identified or other error
*/
struct platform_intf *mosys_platform_setup(void)
{
if (!platform_intf)
return NULL;
/* call platform-specific setup if found */
if (platform_intf->setup && platform_intf->setup(platform_intf) < 0)
return NULL;
return platform_intf;
}
/*
* platform_cmd_usage - print usage text for command
*
* @cmd: command pointer
*/
void platform_cmd_usage(struct platform_cmd *cmd)
{
printf("usage: %s %s\n\n", cmd->name, cmd->usage ? : "");
}
/*
* tree_sub - subcommand handler for print_tree
*
* @intf: platform interface
* @cmd: command to iterate thru
* @depth: depth of recursion (number of leading tabs to prepend)
* @str: string with full command name
*
* returns 0 to indicate success
* returns <0 to indicate failure (or end of command hierarchy)
*/
static int tree_subcommand(struct platform_intf *intf,
struct platform_cmd *cmd,
int depth, char *str)
{
struct platform_cmd *sub;
char *tabs;
int index;
tabs = mosys_malloc(depth + 1);
memset(tabs, '\t', depth);
tabs[depth] = '\0';
for (sub = cmd->arg.sub, index = 1; sub->name != NULL; sub++, index++) {
printf("%s", tabs);
if (sub->type == ARG_TYPE_SUB) {
int pos = 0, len = 0;
if (mosys_get_verbosity() >= LOG_NOTICE) {
printf("[branch] %s ", str);
/* add full command info */
pos = strlen(str);
len = LINE_MAX - strlen(str);
snprintf(str + pos, len, " %s", sub->name);
}
printf("%s\n", sub->name);
/* continue descending into the hierarchy */
tree_subcommand(intf, sub, depth + 1, str);
if (mosys_get_verbosity() >= LOG_NOTICE) {
memset(str + pos, 0, len);
}
} else if (sub->type == ARG_TYPE_GETTER) {
if (mosys_get_verbosity() >= LOG_NOTICE)
printf("[leaf] %s ", str);
printf("%s\n", sub->name);
} else if (sub->type == ARG_TYPE_SETTER) {
if (mosys_get_verbosity() >= LOG_NOTICE)
printf("[flur] %s ", str);
printf("%s\n", sub->name);
} else {
// not a subcommand or function?!?
return -1;
}
}
free(tabs);
return 0;
}
/*
* print_tree - print command tree for this platform
*
* @intf: platform interface
*/
void print_tree(struct platform_intf *intf)
{
int root;
char str[LINE_MAX];
for (root = 0; intf->sub[root] != NULL; root++) {
if (mosys_get_verbosity() >= LOG_NOTICE) {
printf("[root] ");
snprintf(str, sizeof(str), "mosys %s",
intf->sub[root]->name);
} else {
snprintf(str, sizeof(str), "%s", intf->sub[root]->name);
}
printf("%s\n", str);
if (tree_subcommand(intf, intf->sub[root], 1, str) < 0)
lprintf(LOG_DEBUG, "tree walking failed: %s", str);
}
}