sectionfile.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 1,220 行 · 第 1/2 页
C
1,220 行
return( retval );}/* * Write out the internal data to the file */static int writeFile(struct parse_state *ps){ int retval = 0, temp_fd = -1; FILE *in_file, *out_file; struct section_file *sf; char *temp_name = 0; sf = ps->ps_section_file; in_file = ps->ps_in_file; /* Create a temporary file for the output */ if( (temp_name = (char *)KMALLOC(10)) && strcpy(temp_name, "sf.XXXXXX") && ((temp_fd = mkstemp(temp_name)) >= 0) && (out_file = fdopen(temp_fd, "w+")) ) { ps->ps_out_file = out_file; /* Parse the old file and update with current data */ if( (retval = parseFile(ps)) ) { if( !ps->ps_parent ) { /* * Write out any sections that don't have peers * in the input file */ retval = writeNewSections(ps); } } else { dprintf( "Error: Unable to sync file %s\n", ps->ps_filename); } fclose(out_file); /* * If there weren't any errors we rename the temporary file * so that it overwrites the input file. Otherwise, we remove * the bad output file, and leave the input file intact. */ if( retval ) { rename(temp_name, ps->ps_filename); } else { remove(temp_name); } } else { dprintf( "Error: Unable to create temporary file for " "rewriting %s.\n", ps->ps_filename); if( temp_fd >= 0 ) { remove(temp_name); close(temp_fd); } } KFREE(temp_name); return( retval );}/* * Internal file sync function. This allows for included files to be processed * and their data contained in the root section file. */static int syncFile(struct parse_state *parent, struct section_file *sf, char *filename){ struct stat file_stat; time_t file_time = 0; int retval = 0; FILE *file; /* Make sure theres a file to sync with */ if( !filename || !filename[0] ) return( 0 ); /* Get the file's time stamp so we know whether its new or old */ if( !stat(filename, &file_stat) ) { file_time = file_stat.st_mtime; } else { /* Make an empty file if it doesn't exist */ if( (file = fopen(filename, "w+")) ) { fclose(file); } } if( (file = fopen(filename, "r")) ) { struct parse_state ps; /* Initialize the parser state */ ps.ps_parent = parent; ps.ps_filename = filename; ps.ps_section_file = sf; ps.ps_in_file = file; ps.ps_out_file = 0; ps.ps_section = 0; ps.ps_line = 0; ps.ps_column = 0; ps.ps_data = 0; ps.ps_len = 0; if( sf->sf_time < file_time ) { /* The file is newer, read it in */ if( (retval = parseFile(&ps)) ) { if( !parent ) sf->sf_time = time(0); } } else { /* The file is older, write out our data */ if( (retval = writeFile(&ps)) ) { if( !parent ) sf->sf_time = time(0); } } fclose(file); } return( retval );}struct section_file *createSectionFile(){ struct section_file *retval; /* Allocate the structure and do any initialization */ if( (retval = (struct section_file *) KMALLOC(sizeof(struct section_file))) ) { int lpc; retval->lock = 0; retval->sf_filename = 0; retval->sf_time = 0; retval->sf_ordered_sections = 0; retval->sf_last_section = &retval->sf_ordered_sections; for( lpc = 0; lpc < SECTION_FILE_HASH_SIZE; lpc++ ) { retval->sf_sections[lpc] = 0; } } return( retval );}void deleteSectionFile(struct section_file *sf){ if( sf ) { struct section_file_data *sfd, *sfd_next; int lpc; /* * Walk through the section and have their handlers delete the * section data objects. */ for( lpc = 0; lpc < SECTION_FILE_HASH_SIZE; lpc++ ) { sfd = sf->sf_sections[lpc]; while( sfd ) { sfd_next = sfd->sfd_next; sfd->sfd_type->fs_handler(sfd->sfd_type, sf, SFM_DELETE, sfd); sfd = sfd_next; } } KFREE(sf); }}void setSectionFileName(struct section_file *sf, char *name){ sf->sf_filename = name;}/* * States for parsing a section line made up of an identifier followed by * white space, and a data string */enum { SS_TAG, /* Getting the tag */ SS_GUTTER, /* White space between tag and value */ SS_VALUE, /* Value to the end of the line, minus ws, comments */};int parseSectionLine(struct parse_state *ps, char **tag, char **value, FILE *out_file){ int state, tag_start = -1, tag_end = -1; int value_start = -1, value_end = -1; int retval = 1, curr, line_len; char *line, *save; line = ps->ps_data; line_len = ps->ps_len; save = ps->ps_save; /* We start out looking for the tag */ state = SS_TAG; /* Walk through the line */ for( curr = 0; curr < line_len; curr++ ) { switch(line[curr]) { case '#': /* Its a comment */ if( out_file ) { /* Write out value */ fwrite(*value, 1, strlen(*value), out_file); if( value_end > 0 ) { /* * Reset the trampled character at the * end of value */ line[value_end + 1] = save[1]; /* Write out the comment */ fwrite(&line[value_end + 1], 1, line_len - (value_end + 1), out_file); } else { fwrite(&line[curr], 1, line_len - curr, out_file); } } /* Nothing left to parse, jump to the end */ curr = line_len; break; case 0: /* Trampled white space */ case ' ': case '\t': switch(state) { case SS_TAG: if( tag_start != -1 ) { /* Found the gutter */ if( out_file ) { /* Write the tag out */ fwrite(*tag, 1, strlen(*tag), out_file); /* * Write out the trampled char */ fwrite(&save[0], 1, 1, out_file); } state = SS_GUTTER; } else if( out_file ) { /* Write out the space */ fwrite(&line[curr], 1, 1, out_file); } break; case SS_GUTTER: if( out_file ) { /* Write out the space */ fwrite(&line[curr], 1, 1, out_file); } break; case SS_VALUE: if( out_file ) { /* * If the trampled char was a linefeed * then we need to write the value and * the linefeed. */ if( (line[curr] == 0) && (curr == line_len - 1) ) { fwrite(*value, 1, strlen(*value), out_file); fwrite("\n", 1, 1, out_file); } } break; default: break; } break; case '\n': if( out_file ) { /* Write out value and the linefeed */ fwrite(*value, 1, strlen(*value), out_file); fwrite(&line[curr], 1, 1, out_file); } break; default: switch(state) { case SS_TAG: if( tag_start == -1 ) tag_start = curr; tag_end = curr; break; case SS_GUTTER: state = SS_VALUE; /* Fallthrough */ case SS_VALUE: if( value_start == -1 ) value_start = curr; value_end = curr; break; } break; } ps->ps_column++; } if( (tag_start != -1) && (tag_end != -1) ) { /* Save the char we're gonna trample */ save[0] = line[tag_end + 1]; line[tag_end + 1] = 0; *tag = &line[tag_start]; } else { *tag = ""; /* better than NULL... */ } if( (value_start != -1) && (value_end != -1) ) { /* Save the char we're gonna trample */ save[1] = line[value_end + 1]; line[value_end + 1] = 0; *value = &line[value_start]; } else { *value = ""; } /* Check for I/O error */ if( out_file && ferror(out_file) ) retval = 0; return( retval );}/* * Silly function to restore the characters that parseLine tramples */static void restoreLine(struct parse_state *ps){ int save_idx = 0, lpc; for( lpc = 0; lpc < ps->ps_len; lpc++ ) { /* Find any nulls and replace with saved chars */ if( !ps->ps_data[lpc] ) { ps->ps_data[lpc] = ps->ps_save[save_idx]; save_idx++; } }}/* Strings that represent `true' */static char *trueStrings[] = { "1", "true", "yes", "y", "t", 0};/* Strings that represent `false' */static char *falseStrings[] = { "0", "false", "no", "n", "f", 0};/* * Note: The order of the values in trueStrings and falseStrings is important, * and should be of consistent style. */unsigned long parseFlagString(char *value, unsigned long flags, unsigned long flag_bit){ int retval = flags; int lpc; for( lpc = 0; trueStrings[lpc]; lpc++ ) { /* If `value' is true, then set the bit */ if( !strcasecmp(value, trueStrings[lpc]) ) { retval |= flag_bit; break; } /* If `value' is false, then clear the bit */ if( !strcasecmp(value, falseStrings[lpc]) ) { retval &= ~flag_bit; break; } } return( retval );}char *makeFlagString(unsigned long flags, unsigned long flag_bit, char *value){ /* Default to the old value */ char *retval = value; /* Check for a change from the old value */ if( parseFlagString(value, flags, flag_bit) != flags ) { int lpc; /* Loop through all the strings */ for( lpc = 0; trueStrings[lpc]; lpc++ ) { /* * If this true matches, then return the corresponding * false string */ if( !strcasecmp(value, trueStrings[lpc]) ) { retval = falseStrings[lpc]; break; } /* * If this false matches, then return the corresponding * true string */ if( !strcasecmp(value, falseStrings[lpc]) ) { retval = trueStrings[lpc]; break; } } } return( retval );}int syncSectionFile(struct section_file *sf){ int iLockRoot, retval; lockMutex(sf); retval = syncFile(0, sf, sf->sf_filename); unlockMutex(sf); return( retval );}void addSectionType(struct file_section *fs){ int hash; hash = hashName(fs->fs_name, FILE_SECTION_TYPES_SIZE); fs->fs_next = file_section_types[hash]; file_section_types[hash] = fs;}struct file_section *findSectionType(char *name){ struct file_section *retval = 0, *fs; int hash; hash = hashName(name, FILE_SECTION_TYPES_SIZE); fs = file_section_types[hash]; while( fs && !retval ) { if( !strcmp(name, fs->fs_name) ) { retval = fs; } fs = fs->fs_next; } return( retval );}void addSectionToFile(struct section_file *sf, struct section_file_data *sfd){ int iLockRoot, hash; hash = hashName(sfd->sfd_name, SECTION_FILE_HASH_SIZE); lockMutex(sf); sfd->sfd_next = sf->sf_sections[hash]; /* The section is new to this file so we set the dirty bit */ sfd->sfd_flags |= SFDF_DIRTY; sf->sf_sections[hash] = sfd; *sf->sf_last_section = sfd; sf->sf_last_section = &sfd->sfd_order; sfd->sfd_order = 0; unlockMutex(sf);}void remSectionFromFile(struct section_file *sf, struct section_file_data *sfd){ sfd->sfd_flags |= SFDF_REMOVED;}struct section_file_data *findSectionInFile(struct section_file *sf, struct file_section *type, char *name){ struct section_file_data *retval = 0, *sfd; int iLockRoot, hash; lockMutex(sf); hash = hashName(name, SECTION_FILE_HASH_SIZE); sfd = sf->sf_sections[hash]; while( sfd && !retval ) { if( (type == sfd->sfd_type) && !strcmp(name, sfd->sfd_name) ) retval = sfd; sfd = sfd->sfd_next; } unlockMutex(sf); return( retval );}int walkFileSections(struct section_file *sf, int (*handler)(void *arg, struct section_file *sf, struct section_file_data *sfd), void *arg){ struct section_file_data *sfd; int iLockRoot, retval = 1; if( !sf ) return( 0 ); lockMutex(sf); /* Walk over the ordered links */ sfd = sf->sf_ordered_sections; while( sfd && retval ) { retval = handler(arg, sf, sfd); sfd = sfd->sfd_order; } unlockMutex(sf); return( retval );}struct section_file_data *createFileSection(char *section_type, char *section_name, ...){ struct section_file_data *retval = 0; struct file_section *fs; char *new_name; va_list args; va_start(args, section_name); /* Get the section type and ask it to create a section data object */ if( (fs = findSectionType(section_type)) && (new_name = (char *)KMALLOC(strlen(section_name) + 1)) ) { strcpy(new_name, section_name); if( !fs->fs_handler(fs, 0, SFM_CREATE, &retval, new_name, &args) ) { KFREE(new_name); retval = 0; } } va_end(args); return( retval );}void deleteFileSection(struct section_file_data *sfd){ if( sfd ) { KFREE(sfd->sfd_name); /* Ask the handler to clean up the object */ sfd->sfd_type->fs_handler(sfd->sfd_type, 0, SFM_DELETE, sfd); }}#endif /* KAFFE_FEEDBACK */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?