| /* 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; |
| } |