db07609875
segfaults from bnc#710486 due to unchecked usage of return value of open_ctree() [fixed compilation warnings] - pull upstream, replace existing patches, spec update - update 'restore' utility - lzo support - tools may now take earlies superblock when opening the fs - other fixes - pull integration-20111030 branch - mkfs: force mkfs if desired - other fixes - add btrfs-dump-super to mkinitrd - other fixes - skip non-existent devices or without media - documentation updates - scrubbing single device - graceful error handling when opening fs fails - updated mkinitrd script to scan devices before mount (bnc#727383) OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=115
459 lines
9.0 KiB
Diff
459 lines
9.0 KiB
Diff
From e1825e850af190793dadf5ca78f36f394bae9e86 Mon Sep 17 00:00:00 2001
|
|
From: Goffredo Baroncelli <kreijack@inwind.it>
|
|
Date: Sat, 16 Jul 2011 10:55:30 +0200
|
|
Subject: [PATCH 10/35] helpextract: tool to extract the info for the help
|
|
from the source.
|
|
|
|
It is created the file helpextract.c, which is the source for the tool
|
|
"helpextract". This program extract the info showed in the man page and
|
|
the help command from the sources comments.
|
|
---
|
|
helpextract.c | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 435 insertions(+), 0 deletions(-)
|
|
create mode 100644 helpextract.c
|
|
|
|
diff --git a/helpextract.c b/helpextract.c
|
|
new file mode 100644
|
|
index 0000000..9489ea0
|
|
--- /dev/null
|
|
+++ b/helpextract.c
|
|
@@ -0,0 +1,435 @@
|
|
+#include <stdio.h>
|
|
+#include <errno.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <ctype.h>
|
|
+
|
|
+#define PREFIX_MAN "/**** man: "
|
|
+#define PREFIX_TEXT "/**** text: "
|
|
+#define PREFIX_END " ****"
|
|
+#define PREFIX_SKIP " * "
|
|
+
|
|
+#define LINEBUF 1024
|
|
+
|
|
+char **msgs=0;
|
|
+int nmsg=0;
|
|
+
|
|
+static char *xstrdup(char *str){
|
|
+ char *new = strdup(str);
|
|
+ if(!new){
|
|
+ fprintf(stderr,"*** Memory allocation fail ! (xstrdup)\n");
|
|
+ exit(101);
|
|
+ }
|
|
+ return new;
|
|
+}
|
|
+
|
|
+static void *xrealloc(void *ptr, int newsize){
|
|
+ void *new = realloc(ptr, newsize);
|
|
+ if(!new){
|
|
+ fprintf(stderr,"*** Memory allocation fail ! (xrealloc)\n");
|
|
+ exit(101);
|
|
+ }
|
|
+ return new;
|
|
+
|
|
+
|
|
+}
|
|
+
|
|
+static char *xstrip(char *s){
|
|
+
|
|
+ char *last=NULL;
|
|
+ char *first;
|
|
+
|
|
+ while(*s && isspace(*s) ) s++;
|
|
+
|
|
+ first=s;
|
|
+
|
|
+ while(*s){
|
|
+ if(isspace(*s)) last=s;
|
|
+ s++;
|
|
+ }
|
|
+
|
|
+ if(last) *last=0;
|
|
+ return first;
|
|
+
|
|
+
|
|
+}
|
|
+
|
|
+static void addtuple(char *key, char *cmdline, char *short_help,
|
|
+ char *long_help){
|
|
+
|
|
+ msgs = (char**)xrealloc(msgs, sizeof(char *)*(nmsg+1)*4);
|
|
+
|
|
+ key = xstrip(key);
|
|
+
|
|
+ if( !long_help || !strcmp(long_help,"\n"))
|
|
+ long_help = short_help;
|
|
+ else if(!short_help || !strcmp(short_help, "\n"))
|
|
+ short_help = long_help;
|
|
+
|
|
+ msgs[nmsg*4] = key;
|
|
+ msgs[nmsg*4+1] = cmdline;
|
|
+ msgs[nmsg*4+2] = short_help;
|
|
+ msgs[nmsg*4+3] = long_help;
|
|
+ nmsg++;
|
|
+}
|
|
+
|
|
+
|
|
+static int search_in_file(char *nf){
|
|
+ char buf[LINEBUF+1];
|
|
+ FILE *fp;
|
|
+ int status;
|
|
+ char *key=NULL;
|
|
+ char *cmdline=NULL;
|
|
+ char *short_help=NULL;
|
|
+ char *long_help=NULL;
|
|
+
|
|
+ fp = fopen(nf,"r");
|
|
+ if(!fp){
|
|
+ int e=errno;
|
|
+ fprintf(stderr, "*** Cannot open '%s'; error = %d - '%s'\n",
|
|
+ nf, e, strerror(e));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ status = 0;
|
|
+ while(fgets(buf,LINEBUF,fp)){
|
|
+ // printf("status = %d, buf=%s",status, buf);
|
|
+
|
|
+ if(status == 0){
|
|
+ if(!strncmp(buf,PREFIX_MAN, strlen(PREFIX_MAN)) ){
|
|
+ key = xstrdup(buf+strlen(PREFIX_MAN));
|
|
+ status++;
|
|
+ }else if(!strncmp(buf,PREFIX_TEXT,
|
|
+ strlen(PREFIX_TEXT))){
|
|
+ key = xstrdup(buf+strlen(PREFIX_TEXT));
|
|
+ status=5;
|
|
+ }
|
|
+ continue;
|
|
+
|
|
+ }
|
|
+
|
|
+ if( !strncmp(buf,PREFIX_END, strlen(PREFIX_END)) ||
|
|
+ strncmp(buf, PREFIX_SKIP,2)){
|
|
+
|
|
+ addtuple(key, cmdline, short_help, long_help);
|
|
+ key = cmdline = short_help = long_help = 0;
|
|
+ status = 0;
|
|
+
|
|
+ continue;
|
|
+ }
|
|
+ if( status == 2){
|
|
+ if(strlen(buf)>strlen(PREFIX_SKIP))
|
|
+ cmdline = xstrdup(buf+strlen(PREFIX_SKIP));
|
|
+ status++;
|
|
+ continue;
|
|
+ }
|
|
+ if( status == 4){
|
|
+ int len;
|
|
+ int len2;
|
|
+ char *p;
|
|
+
|
|
+ if(strlen(buf)<=strlen(PREFIX_SKIP)){
|
|
+ status++;
|
|
+ continue;
|
|
+ }
|
|
+ p=buf+3;
|
|
+ while(isspace(*p) && *p ) p++;
|
|
+ if(!*p){
|
|
+ status++;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ len2 = strlen(buf)-strlen(PREFIX_SKIP);
|
|
+
|
|
+ if(short_help)
|
|
+ len = strlen(short_help);
|
|
+ else
|
|
+ len = 0;
|
|
+ short_help = (char*)xrealloc(short_help, len+len2+1);
|
|
+ strcpy(short_help+len,buf+strlen(PREFIX_SKIP));
|
|
+ continue;
|
|
+ }
|
|
+ if( status == 5){
|
|
+ int len;
|
|
+ int len2 = strlen(buf)-strlen(PREFIX_SKIP);
|
|
+
|
|
+ if(long_help)
|
|
+ len = strlen(long_help);
|
|
+ else
|
|
+ len = 0;
|
|
+ long_help = (char*)xrealloc(long_help, len+len2+1);
|
|
+ strcpy(long_help+len,buf+strlen(PREFIX_SKIP));
|
|
+ continue;
|
|
+ }
|
|
+ if( status == 1 || status == 3 ){
|
|
+ status++;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ fprintf(stderr,"*** Internal error: status = %d\n",status);
|
|
+ exit(100);
|
|
+
|
|
+ }
|
|
+
|
|
+ if( status != 0 ){
|
|
+ fprintf(stderr,"*** Parse error: file = '%s', "
|
|
+ "status = %d at the end of file\n",
|
|
+ nf, status);
|
|
+ exit(100);
|
|
+
|
|
+ }
|
|
+
|
|
+ fclose(fp);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* remove all the escape sequence excepet \\ */
|
|
+static char * my_escape(char *src, char *filters[] ){
|
|
+
|
|
+ static char buffer[LINEBUF*5];
|
|
+
|
|
+ int i=0;
|
|
+ while(*src){
|
|
+ int j;
|
|
+ int next_char = *(src+1);
|
|
+ if(*src != '\\'){
|
|
+ buffer[i++]=*src++;
|
|
+ continue;
|
|
+ }
|
|
+ if(!next_char){
|
|
+ buffer[i++]=*src++;
|
|
+ continue;
|
|
+ }
|
|
+ if( !filters ){
|
|
+ src +=2;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ j=0;
|
|
+ while(filters[j]){
|
|
+ if(filters[j][0] == next_char ){
|
|
+ strcpy(buffer+i, filters[j]+2);
|
|
+ i+=strlen(filters[j]+2);
|
|
+ break;
|
|
+ }
|
|
+ j++;
|
|
+ }
|
|
+ if(!filters[j]){
|
|
+ char *p=src;
|
|
+ int l=40;
|
|
+ fprintf(stderr,
|
|
+ "Unknow escape sequence '\%c' in [\"",
|
|
+ next_char);
|
|
+ while(*p && l--) fputc(*p++, stderr);
|
|
+ fprintf(stderr, "\"...]\n");
|
|
+ }
|
|
+ src += 2;
|
|
+
|
|
+ }
|
|
+
|
|
+ buffer[i]=0;
|
|
+ return buffer;
|
|
+
|
|
+}
|
|
+
|
|
+static char * escape_c_array(char *src ){
|
|
+ static char *filters[]={
|
|
+
|
|
+ /* remove the all know esc-sequence */
|
|
+
|
|
+ "B ", /* bold */
|
|
+ "b ", /* end bold */
|
|
+ "I ", /* italic */
|
|
+ "i ", /* end italic */
|
|
+ "c ", /* comment */
|
|
+ "P ", /* start paragraph */
|
|
+ "p ", /* indented paragraph */
|
|
+ "h ", /* header */
|
|
+ "d ", /* bold regular */
|
|
+ "e ", /* bold */
|
|
+ "t ", /* indented paragraph */
|
|
+ "w ", /* move the left margin */
|
|
+ "q ", /* move the left margin back */
|
|
+
|
|
+ "\\ \\\\",
|
|
+ "- -",
|
|
+
|
|
+ 0
|
|
+ };
|
|
+
|
|
+ return my_escape(src, filters);
|
|
+}
|
|
+
|
|
+static char *escape_man_page(char *src){
|
|
+ /* from Gnu troff manual */
|
|
+ static char *filters[]={
|
|
+ "B \\fB", /* bold */
|
|
+ "b \\fP", /* end bold */
|
|
+ "I \\fI", /* italic */
|
|
+ "i \\fP", /* end italic */
|
|
+ "c .\\\"", /* comment */
|
|
+ "P .PP", /* start paragraph */
|
|
+ "p .TP", /* indented paragraph */
|
|
+ "h .SH", /* header */
|
|
+ "d .BR", /* bold regular */
|
|
+ "e .B", /* bold */
|
|
+ "t .IP", /* indented paragraph */
|
|
+ "w .RS", /* move the left margin */
|
|
+ "q .RE", /* move the left margin back */
|
|
+
|
|
+ "- \\-", /* escape the minus sign */
|
|
+ "\\ \\",
|
|
+
|
|
+ 0
|
|
+ };
|
|
+
|
|
+ return my_escape(src, filters);
|
|
+}
|
|
+
|
|
+
|
|
+static void dump_c_array(){
|
|
+
|
|
+ int i;
|
|
+
|
|
+ printf("{");
|
|
+ for(i=0; i < nmsg*4 ; i++){
|
|
+ char *c = msgs[i];
|
|
+ int begin;
|
|
+
|
|
+ if(!(i%4) && strncmp(c,"btrfs ",5)){
|
|
+ i+=3;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if(i>0){
|
|
+ putchar(',');
|
|
+ if(!(i%4)) putchar('\n');
|
|
+ }
|
|
+
|
|
+ if(!c){
|
|
+ printf("\n NULL");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ c = escape_c_array(c);
|
|
+
|
|
+ begin = 1;
|
|
+ while( *c ){
|
|
+ if(begin)
|
|
+ printf("\n \"");
|
|
+ begin = 0;
|
|
+ if( *c == '\n' ){
|
|
+ printf("\\n\"");
|
|
+ begin = 1;
|
|
+ }else if( *c == '"' ){
|
|
+ printf("\\\"");
|
|
+ }else{
|
|
+ putchar(*c);
|
|
+ }
|
|
+
|
|
+ c++;
|
|
+ }
|
|
+ if(!begin) putchar('"');
|
|
+ }
|
|
+ printf(",\n\n ");
|
|
+ for(i=0; i < 4; i++){
|
|
+ if(i>0) putchar(',');
|
|
+ printf("NULL");
|
|
+ }
|
|
+ printf("\n}\n");
|
|
+
|
|
+}
|
|
+
|
|
+static int my_sort_cmp(const void *p1, const void *p2){
|
|
+ return strcmp(*(char**)p1, *(char **)p2);
|
|
+}
|
|
+
|
|
+static void my_sort(){
|
|
+ qsort(msgs, nmsg, sizeof(char*)*4, my_sort_cmp);
|
|
+}
|
|
+
|
|
+static int find_section(char *key){
|
|
+ int i;
|
|
+ for(i = 0 ; i < nmsg ; i++ )
|
|
+ if(!strcmp( msgs[i*4],key) ) return i;
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static void dump_man_page(){
|
|
+
|
|
+ int i, fmt;
|
|
+
|
|
+ i = find_section("man btrfs header");
|
|
+ if( i>= 0 ) printf(msgs[i*4+3]);
|
|
+
|
|
+ i = find_section("man btrfs synopsis");
|
|
+ if( i>= 0 ) printf(msgs[i*4+3]);
|
|
+
|
|
+ fmt = find_section("man btrfs synopsis format");
|
|
+ for(i = 0; i < nmsg && fmt>=0; i++ ){
|
|
+ if( strncmp("btrfs ",msgs[i*4], 6) ||
|
|
+ !strcmp("btrfs introduction", msgs[i*4] ) ||
|
|
+ !strcmp("btrfs notes", msgs[i*4] ) )
|
|
+ continue;
|
|
+
|
|
+ printf(msgs[fmt*4+3], escape_man_page(msgs[i*4+1]));
|
|
+ }
|
|
+
|
|
+ i = find_section("btrfs introduction");
|
|
+ if( i>= 0 ) printf(escape_man_page(msgs[i*4+3]));
|
|
+
|
|
+ i = find_section("man btrfs commands");
|
|
+ if( i>= 0 ) printf(msgs[i*4+3]);
|
|
+
|
|
+ fmt = find_section("man btrfs command format");
|
|
+ for(i = 0; i < nmsg && fmt>=0; i++ ){
|
|
+
|
|
+ char big2[LINEBUF*5];
|
|
+ if( strncmp("btrfs ",msgs[i*4], 6) ||
|
|
+ !strcmp("btrfs introduction", msgs[i*4] ) ||
|
|
+ !strcmp("btrfs notes", msgs[i*4] ) )
|
|
+ continue;
|
|
+
|
|
+ strcpy(big2, escape_man_page(msgs[i*4+3]));
|
|
+ printf(msgs[fmt*4+3], escape_man_page(msgs[i*4+1]), big2);
|
|
+
|
|
+ }
|
|
+
|
|
+ i = find_section("man btrfs notes");
|
|
+ if( i>= 0 ) printf(msgs[i*4+3]);
|
|
+
|
|
+ i = find_section("btrfs notes");
|
|
+ if( i>= 0 ) printf(escape_man_page(msgs[i*4+3]));
|
|
+
|
|
+ i = find_section("man btrfs footer");
|
|
+ if( i>= 0 ) printf(msgs[i*4+3]);
|
|
+}
|
|
+
|
|
+static void usage(char *np){
|
|
+ printf("usage: %s --man-page|--c-array <file> [<file> [...]]\n", np);
|
|
+}
|
|
+
|
|
+int main(int argc, char **argv ){
|
|
+
|
|
+ int i;
|
|
+ if( argc < 3 || ( strcmp(argv[1],"--man-page") &&
|
|
+ strcmp(argv[1],"--c-array") )){
|
|
+ usage(argv[0]);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ for(i=2; i < argc ; i++)
|
|
+ search_in_file(argv[i]);
|
|
+
|
|
+ my_sort();
|
|
+
|
|
+ if(!strcmp(argv[1], "--man-page"))
|
|
+ dump_man_page();
|
|
+ else if (!strcmp(argv[1], "--c-array"))
|
|
+ dump_c_array();
|
|
+
|
|
+ return 0;
|
|
+
|
|
+}
|
|
--
|
|
1.7.6.233.gd79bc
|
|
|