blob: 757ae6944c6ea9ed51e3fa2f8fdf6a6ab442e772 [file] [log] [blame]
/* Generate assembler source containing git information
*
* Copyright (C) 2013 Marvell International Ltd.
* All rights reserved.
*
* 2013-2 Guoqing Li <ligq@marvell.com>
* get top ten commits and current branch info
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* Usage: cgitinfo kernel_source_path > gitinfo.S
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define GIT_INFO_NUM 20
#define GIT_INFO_LEN 100
#define GIT_CONFIG_INFO_LEN 200
#define FILE_DIR_LEN 256
#define GIT_CMD_LEN 260
#define KER_SRC_DIR_LEN_MAX 160
#define HEADER "refs/heads/"
const char cmd_get_gitinfo[] = "git log --pretty=%H -10";
const char git_name[] = ".git";
const char git_branch_file[] = ".git/HEAD";
const char git_config_file[] = ".git/config";
const char git_commit_file[] = ".git/gitcommit_top10";
static char git_dir[FILE_DIR_LEN], git_branch_dir[FILE_DIR_LEN],
git_config_dir[FILE_DIR_LEN], git_commit_dir[FILE_DIR_LEN];
static char get_gitinfo[GIT_CMD_LEN];
static char git_info[GIT_INFO_NUM][GIT_INFO_LEN];
static char head_name[GIT_INFO_LEN], branch_local[GIT_INFO_LEN];
static char config_info[GIT_CONFIG_INFO_LEN];
static void create_file(void)
{
char *p, *q;
FILE *fp, *cfg_fp;
int i = 0, j, git_info_len[GIT_INFO_NUM], git_info_num = 11;
/* get git branch info */
fp = fopen(git_branch_dir, "r");
if (fp) {
if (fgets(head_name, GIT_INFO_LEN, fp) == NULL)
printf("/* warning: no head found! */\n");
fclose(fp);
}
p = strstr(head_name, HEADER);
if (p) {
p += sizeof(HEADER) - 1;
q = strchr(head_name, '\n');
while (p < q)
branch_local[i++] = *p++;
}
printf("/* branch_local:%s */\n", branch_local);
memset(git_info_len, 0, sizeof(git_info_len));
cfg_fp = fopen(git_config_dir, "r");
if (cfg_fp) {
while (fgets(config_info, GIT_CONFIG_INFO_LEN, cfg_fp)) {
if (strstr(config_info, "branch") &&
strstr(config_info, branch_local)) {
if (fgets(config_info, GIT_CONFIG_INFO_LEN,
cfg_fp) == NULL)
printf("/* Warning: no origin config for the branch:%s */\n",
branch_local);
if (fgets(config_info, GIT_CONFIG_INFO_LEN,
cfg_fp) == NULL)
printf("/* Warning: no refs config for the branch:%s */\n",
branch_local);
i = 0;
p = strstr(config_info, HEADER);
if (p) {
p += sizeof(HEADER) - 1;
q = strchr(config_info, '\n');
while (p < q)
git_info[0][i++] = *p++;
}
git_info_len[0] = i;
break;
}
}
if (!git_info_len[0])
printf("/* warning: no branch found! */\n");
fclose(cfg_fp);
}
printf("/* branch_origin:%s */\n\n", git_info[0]);
/* get top ten git commits info */
fp = fopen(git_commit_dir, "r");
if (fp) {
for (i = 1; i < 11; i++) {
if (fgets(git_info[i], 50, fp) == NULL)
printf("/* warning: no commint:%d found */\n",
i);
p = strchr(git_info[i], '\n');
if (p)
git_info_len[i] = p - git_info[i];
else
git_info_len[i] = 0;
}
fclose(fp);
}
printf("#include <asm/types.h>\n");
printf("#if BITS_PER_LONG == 64\n");
printf("#define PTR .quad\n");
printf("#define ALGN .align 8\n");
printf("#else\n");
printf("#define PTR .long\n");
printf("#define ALGN .align 4\n");
printf("#endif\n");
printf("\t.section .rodata, \"a\"\n");
printf(".globl git_info_num\n");
printf("\tALGN\n");
printf("git_info_num:\n");
printf("\tPTR\t%d\n", git_info_num);
printf("\n");
printf(".globl git_info\n");
printf("\tALGN\n");
printf("git_info:\n");
for (i = 0; i < 11; i++) {
printf("\t.byte 0x%02x", git_info_len[i]);
for (j = 0; j < git_info_len[i]; j++)
printf(", 0x%02x", git_info[i][j]);
printf("\n");
}
printf("\n");
}
static void create_title(void)
{
printf("/*\n");
printf(" * kernel/gitinfo.S\n");
printf(" * Automatically generated by cgitinfo tool, don't edit\n");
printf(" */\n");
printf("\n");
}
int main(int argc, char **argv)
{
int ret;
char kernel_src_dir[KER_SRC_DIR_LEN_MAX];
create_title();
if (argc >= 2) {
if (strlen(argv[1]) >= KER_SRC_DIR_LEN_MAX)
printf("/* error: src dir was too long (<%d)! */\n",
KER_SRC_DIR_LEN_MAX);
strncpy(kernel_src_dir, argv[1], KER_SRC_DIR_LEN_MAX);
}
printf("/* src dir:%s */\n", kernel_src_dir);
if (!access(kernel_src_dir, 0)) {
sprintf(git_dir, "%s/%s", kernel_src_dir, git_name);
sprintf(get_gitinfo, "cd %s; %s > %s/%s", kernel_src_dir,
cmd_get_gitinfo, kernel_src_dir,
git_commit_file);
if (!access(git_dir, 0)) {
ret = system(get_gitinfo);
if (ret == -1)
printf("/* error: git log cmd error! */\n");
} else
printf("/* error: .git not exist! */\n");
sprintf(git_branch_dir, "%s/%s", kernel_src_dir,
git_branch_file);
sprintf(git_config_dir, "%s/%s", kernel_src_dir,
git_config_file);
sprintf(git_commit_dir, "%s/%s", kernel_src_dir,
git_commit_file);
} else
printf("/* error: src dir not exist! */\n");
create_file();
return 0;
}