📄 hhp.c
字号:
if( !exists("$FIftiMain") ){ Full_text_search = false; got_fts = true; } else { struct stat st; if( stat("$FIftiMain",&st) == 0 ){ got_fts = true; Full_text_search = (st.st_size != 0); } } } if( got_fts && (Full_text_search || print_defaults) ) fprintf( hhp, "Full-text search=%s\r\n", Full_text_search ? "Yes" : "No" ); } /* fprintf( hhp, "IGNORE=%s\r\n", IGNORE ); */ /* Index file */ if( Index_file ) fprintf( hhp, "Index file=%s\r\n", Index_file ); /* else { FIXME: Find out how to find files with a particular extension fputs( ";The best guess for the Index file is one of the following\r\n", hhp ); while(f=findfile("*.hhk",case insensitive)) fprintf( hhp, ";Index file=%s\r\n", f ); }*/ { /* Language */ bool got_lcid = got_stuff; if(!got_lcid){ FILE* tmp = fopen( "$FIftiMain", "rb" ); if( tmp ){ fseek( tmp, 0x7E, SEEK_SET ); got_lcid = read_DWORD( tmp, &Language ); FCLOSE( tmp ); } if( !got_lcid && (tmp = fopen( "$WWKeywordLinks/BTree", "rb" )) ){ fseek( tmp, 0x34, SEEK_SET ); got_lcid = read_DWORD( tmp, &Language ); FCLOSE( tmp ); } if( !got_lcid && (tmp = fopen( "$WWAssociativeLinks/BTree", "rb" )) ){ fseek( tmp, 0x34, SEEK_SET ); got_lcid = read_DWORD( tmp, &Language ); FCLOSE( tmp ); } /* FIXME: check the LCIDs in $OBJINST */ /* if( !got_lcid && (tmp = fopen( "$OBJINST", "rb" )) ){ FCLOSE( tmp ); } */ } if(got_lcid){ char* Language_string = get_lcid_string( Language ); if( Language_string ) fprintf( hhp, "Language=0x%x %s\n", Language, Language_string ); else fprintf( hhp, "Language=0x%x\n", Language ); } } /* fprintf( hhp, "PREFIX=%s\r\n", PREFIX ); */ /* Sample Staging Path, Sample list file */ if( samples_success ){ fprintf( hhp, "Sample Staging Path=%s\r\n", Sample_Staging_Path ); fprintf( hhp, "Sample list file=%s\r\n", Sample_list_file ); } { /* Title */ char* Title = (char*)get_system( Title_CODE ); if( Title ) fprintf( hhp, "Title=%s\n", Title ); FREE( Title ); } /* fprintf( hhp, "TMPDIR=%s\r\n", TMPDIR ); */ { /* Custom tab */ BYTE* Custom_tabs = get_system( Custom_tabs_CODE ); if(Custom_tabs){ char* s = (char*)Custom_tabs+4; DWORD n = get_DWORD( Custom_tabs ); while(n){ if(!*s) break; fprintf( hhp, "Custom tab=\"%s\", ", s ); /* This is not a typo */ s += strlen(s) + 1; if(!*s) break; fprintf( hhp, "%s\r\n", s ); s += strlen(s) + 1; n --; } FREE(Custom_tabs); } } close_system(); /* [WINDOWS] */ if( open_windows() ){ fputs( "\r\n[WINDOWS]\r\n", hhp ); while( print_windows_entry( hhp ) ); close_windows(); /* FIXME: How to do the following properly uint i; bool got_one = true; for(i = 0; i < num_windows; i++){ got_one = print_windows_entry( hhp ); if(!got_one) break; } if(got_one){ / * So this is only printed when num_windows is a lie * / fputs( ";The following windows were hidden\r\n", hhp ); while( print_windows_entry( hhp ) ); } */ } /* [FILES] */ /* This only dumps out names of all non-internal files */ no_files_yet = true; print_files("."); FREE(prefix); prefix_len = prefix_size = 0; /* [ALIAS], [MAP] */ if( alias_map_success ){ fprintf( hhp, "\r\n[ALIAS]\r\n" "#include %s\r\n" "\r\n[MAP]\r\n" "#include %s\r\n", ALIAS_FILE_NAME, MAP_FILE_NAME ); } /* [TEXT POPUPS] */ /* FIXME: For this we need to grep -l '^[[:space:]]*\.topic[[:space:]]\+[0-9]\+' *.txt | fileno(hhp) grep or glob()+regcomp() would be ideal, but, dunno if these can be relied on these for example on Win32 the best would be if there were a grep to C script that made optimisations for constant regexps fputs( "\r\n[TEXT POPUPS]\r\n", hhp ); */ { /* [MERGE FILES] */ FILE* idxhdr = fopen("#IDXHDR","rb"); if( idxhdr ){ DWORD num_merge_files; fseek( idxhdr, 0x48, SEEK_SET ); if( read_DWORD( idxhdr, &num_merge_files ) && num_merge_files ){ DWORD merge_file; fseek( idxhdr, 4, SEEK_CUR ); fputs( "\r\n[MERGE FILES]\r\n", hhp ); while( read_DWORD( idxhdr, &merge_file ) && merge_file ){ print_string( hhp, merge_file ); fputs( "\r\n", hhp ); } if( merge_file ){ fputs( ";The following chms were in the internal string list, but not the merge files list\r\n", hhp ); /* stream the rest of the strings file through a \0 to \r\n converter */ print_strings( hhp ); } } FCLOSE( idxhdr ); } } /* Output this or not? May as well, since HHW does */ fputs( "\r\n[INFOTYPES]\r\n", hhp ); { /* [SUBSETS] */ struct stat st; if( stat("#SUBSETS",&st) == 0 ){ uint i, num_subsets = (st.st_size-4)/12; fputs( "\r\n[SUBSETS]\r\n", hhp ); /* Here we want to print some string out once for each #SUBSETS entry */ /* FIXME: Rethink the strings below */ if( num_subsets == 1 ) fprintf( hhp, "There was one entry in this section, but only garbage was produced\r\n" ); else if( num_subsets ) for( i = 0; i < num_subsets; i++ ) fprintf( hhp, "There were %u entries in this section, but only garbage was produced\r\n", num_subsets ); if( (st.st_size-4)%12 ) fprintf( stderr, "%s: warning: %s/%s: %s\n", PROGNAME, input, "#SUBSETS", "partial entry found" ); } } if( !ferror(hhp) ) hhp_success = true; else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", pf, strerror(errno) ); FCLOSE( hhp ); } else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", pf, strerror(errno) );}/* Returns true if the argument is the name of an internal file */bool isinternal( char* f ){ return !strcmp( f, "#BSSC" ) || !strcmp( f, "#GRPINF" ) || !strcmp( f, "#IDXHDR" ) || !strcmp( f, "#INFOTYPES" ) || !strcmp( f, "#ITBITS" ) || !strcmp( f, "#IVB" ) || !strcmp( f, "#KEY_DATA" ) || !strcmp( f, "#KEY_DELETED" ) || !strcmp( f, "#STRINGS" ) || !strcmp( f, "#SUBSETS" ) || !strcmp( f, "#SYSTEM" ) || !strcmp( f, "#TOCIDX" ) || !strcmp( f, "#TOPICS" ) || !strcmp( f, "#URLS" ) || !strcmp( f, "#URLSTR" ) || !strcmp( f, "#URLTBL" ) || !strcmp( f, "#WINDOWS" ) || !strcmp( f, "$FIftiMain" ) || !strcmp( f, "$HHTitleMap" ) || !strcmp( f, "$OBJINST" ) || !strcmp( f, "$TitleMap" ) || !strcmp( f, "$WWAssociativeLinks" ) || !strcmp( f, "$WWKeywordLinks" ) || /* The following may go away when "<input>-rec" in the current dir is where we recreate stuff */ !strcmp( f, "#recreated" ); /* Bit of a kludge, spose i should use the inode (which is not very portable) */}/* Recurse through a dir, printing out the names of files found */void print_files( char* d ){ DIR* dir = opendir( d ); if( dir ){ struct stat st; struct dirent* de; /* On cygwin we need to enter the dir first */ chdir( d ); while( (de = readdir( dir )) ){ /* Most systems define these as the current & parent dirs */ if( !strcmp( de->d_name, "." ) || !strcmp( de->d_name, ".." ) ) continue; /* Ignore internal files, except when not in root */ if( (!prefix || !*prefix) && isinternal(de->d_name) ) continue; /* Check if it is a subdir */ if( !stat( de->d_name, &st ) && S_ISDIR( st.st_mode ) ){ /* Add the directory name */ size_t old_prefix_len = prefix_len; size_t new_prefix_len = prefix_len + strlen( de->d_name ) + 1; size_t new_prefix_size = ((new_prefix_len+1)/PREFIX_GROW+1)*PREFIX_GROW; if( new_prefix_size > prefix_size ){ char* new_prefix = (char*)realloc( prefix, new_prefix_size ); if( !new_prefix ){ fprintf( stderr, "%s: %s %s: %s\n", PROGNAME, input, "prefix buffer", strerror(errno) ); continue; } prefix = new_prefix; prefix_size = new_prefix_size; } strcpy( prefix+prefix_len, de->d_name ); prefix[new_prefix_len-1] = '\\'; prefix[new_prefix_len] = '\0'; prefix_len = new_prefix_len; /* Print any files in the subdir */ print_files( de->d_name ); /* Strip away the last path */ prefix_len = old_prefix_len; prefix[prefix_len] = '\0'; } else { /* FIXME: what is the best way to speed this up? */ if( no_files_yet ){ fputs( "\r\n[FILES]\r\n", hhp ); no_files_yet = false; } /* Print the filename */ fprintf( hhp, "%s%s\r\n", prefix?prefix:"", de->d_name ); } } /* Back out */ if( !!strcmp( d, "." ) ) chdir( ".." ); closedir( dir ); } else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, prefix?prefix:"", d, strerror(errno) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -