GRASS Programmer's Manual
6.4.1(2011)
|
00001 00020 #include <stdlib.h> 00021 #include <stdio.h> 00022 #include <string.h> 00023 #include <unistd.h> 00024 #include <sys/types.h> 00025 #include <sys/stat.h> 00026 #include <grass/glocale.h> 00027 #include <grass/gis.h> 00028 #include <grass/Vect.h> 00029 00030 #define MAX_OPEN_LEVEL 2 00031 00032 static int open_old_dummy() 00033 { 00034 return 0; 00035 } 00036 00037 #ifndef HAVE_OGR 00038 static int format() 00039 { 00040 G_fatal_error(_("Requested format is not compiled in this version")); 00041 return 0; 00042 } 00043 #endif 00044 00045 static int Open_level = 0; 00046 00047 static int (*Open_old_array[][2]) () = { 00048 { 00049 open_old_dummy, V1_open_old_nat} 00050 #ifdef HAVE_OGR 00051 , { 00052 open_old_dummy, V1_open_old_ogr} 00053 #else 00054 , { 00055 open_old_dummy, format} 00056 #endif 00057 }; 00058 00059 static void fatal_error(int ferror, char *errmsg) 00060 { 00061 switch (ferror) { 00062 case GV_FATAL_EXIT: 00063 G_fatal_error(errmsg); 00064 break; 00065 case GV_FATAL_PRINT: 00066 G_warning(errmsg); 00067 break; 00068 case GV_FATAL_RETURN: 00069 break; 00070 } 00071 } 00072 00073 00096 int Vect_set_open_level(int level) 00097 { 00098 Open_level = level; 00099 if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL) { 00100 G_warning(_("Programmer requested unknown open level %d"), 00101 Open_level); 00102 Open_level = 0; 00103 return 1; 00104 } 00105 00106 return 0; 00107 } 00108 00109 00124 int 00125 Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, 00126 int update, int head_only) 00127 { 00128 char buf[GNAME_MAX + 10], buf2[GMAPSET_MAX + 10], xname[GNAME_MAX], 00129 xmapset[GMAPSET_MAX], errmsg[2000]; 00130 FILE *fp; 00131 int level, level_request, ferror; 00132 int format, ret; 00133 char *fmapset; 00134 00135 G_debug(1, "Vect_open_old(): name = %s mapset= %s update = %d", name, 00136 mapset, update); 00137 00138 /* TODO: Open header for update ('dbln') */ 00139 00140 ferror = Vect_get_fatal_error(); 00141 Vect_set_fatal_error(GV_FATAL_EXIT); 00142 00143 level_request = Open_level; 00144 Open_level = 0; 00145 Vect__init_head(Map); 00146 dig_init_plus(&(Map->plus)); 00147 00148 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00149 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, xname); 00150 sprintf(buf2, "%s@%s", GRASS_VECT_COOR_ELEMENT, xmapset); 00151 00152 Map->name = G_store(xname); 00153 Map->mapset = G_store(xmapset); 00154 } 00155 else { 00156 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, name); 00157 sprintf(buf2, "%s", GRASS_VECT_COOR_ELEMENT); 00158 Map->name = G_store(name); 00159 00160 if (mapset) 00161 Map->mapset = G_store(mapset); 00162 else 00163 Map->mapset = G_store(""); 00164 } 00165 00166 fmapset = G_find_vector2(Map->name, Map->mapset); 00167 if (fmapset == NULL) { 00168 sprintf(errmsg, _("Vector map <%s> not found"), 00169 Vect_get_full_name(Map)); 00170 fatal_error(ferror, errmsg); 00171 return -1; 00172 } 00173 Map->mapset = G_store(fmapset); 00174 00175 Map->location = G_store(G_location()); 00176 Map->gisdbase = G_store(G_gisdbase()); 00177 00178 if (update && (0 != strcmp(Map->mapset, G_mapset()))) { 00179 G_warning(_("Vector map which is not in the current mapset cannot be opened for update")); 00180 return -1; 00181 } 00182 00183 /* Read vector format information */ 00184 format = 0; 00185 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00186 G_debug(1, "open format file: '%s/%s/%s'", Map->mapset, buf, 00187 GRASS_VECT_FRMT_ELEMENT); 00188 fp = G_fopen_old(buf, GRASS_VECT_FRMT_ELEMENT, Map->mapset); 00189 if (fp == NULL) { 00190 G_debug(1, "Vector format: %d (native)", format); 00191 format = GV_FORMAT_NATIVE; 00192 } 00193 else { 00194 format = dig_read_frmt_ascii(fp, &(Map->fInfo)); 00195 fclose(fp); 00196 00197 G_debug(1, "Vector format: %d (non-native)", format); 00198 if (format < 0) { 00199 sprintf(errmsg, _("Unable to open vector map <%s>"), 00200 Vect_get_full_name(Map)); 00201 fatal_error(ferror, errmsg); 00202 return -1; 00203 } 00204 } 00205 00206 Map->format = format; 00207 00208 /* Read vector head */ 00209 if (Vect__read_head(Map) != GRASS_OK) { 00210 sprintf(errmsg, 00211 _("Unable to open vector map <%s> on level %d. " 00212 "Try to rebuild vector topology by v.build."), 00213 Vect_get_full_name(Map), level_request); 00214 G_warning(_("Unable to read head file")); 00215 } 00216 00217 G_debug(1, "Level request = %d", level_request); 00218 00219 /* There are only 2 possible open levels, 1 and 2. Try first to open 'support' files 00220 * (topo,sidx,cidx), these files are the same for all formats. 00221 * If it is not possible and requested level is 2, return error, 00222 * otherwise call Open_old_array[format][1], to open remaining files/sources (level 1) 00223 */ 00224 00225 /* Try to open support files if level was not requested or requested level is 2 (format independent) */ 00226 if (level_request == 0 || level_request == 2) { 00227 level = 2; /* We expect success */ 00228 /* open topo */ 00229 ret = Vect_open_topo(Map, head_only); 00230 if (ret == 1) { /* topo file is not available */ 00231 G_debug(1, "Topo file for vector '%s' not available.", 00232 Vect_get_full_name(Map)); 00233 level = 1; 00234 } 00235 else if (ret == -1) { 00236 G_fatal_error(_("Unable to open topology file for vector map <%s>"), 00237 Vect_get_full_name(Map)); 00238 } 00239 /* open spatial index, not needed for head_only */ 00240 /* spatial index is not loaded anymore */ 00241 /* 00242 if ( level == 2 && !head_only ) { 00243 if ( Vect_open_spatial_index(Map) == -1 ) { 00244 G_debug( 1, "Cannot open spatial index file for vector '%s'.", Vect_get_full_name (Map) ); 00245 dig_free_plus ( &(Map->plus) ); 00246 level = 1; 00247 } 00248 } 00249 */ 00250 /* open category index */ 00251 if (level == 2) { 00252 ret = Vect_cidx_open(Map, head_only); 00253 if (ret == 1) { /* category index is not available */ 00254 G_debug(1, 00255 "Category index file for vector '%s' not available.", 00256 Vect_get_full_name(Map)); 00257 dig_free_plus(&(Map->plus)); /* free topology */ 00258 dig_spidx_free(&(Map->plus)); /* free spatial index */ 00259 level = 1; 00260 } 00261 else if (ret == -1) { /* file exists, but cannot be opened */ 00262 G_fatal_error(_("Unable to open category index file for vector map <%s>"), 00263 Vect_get_full_name(Map)); 00264 } 00265 } 00266 #ifdef HAVE_OGR 00267 /* Open OGR specific support files */ 00268 if (level == 2 && Map->format == GV_FORMAT_OGR) { 00269 if (V2_open_old_ogr(Map) < 0) { 00270 dig_free_plus(&(Map->plus)); 00271 dig_spidx_free(&(Map->plus)); 00272 dig_cidx_free(&(Map->plus)); 00273 level = 1; 00274 } 00275 } 00276 #endif 00277 if (level_request == 2 && level < 2) { 00278 sprintf(errmsg, 00279 _("Unable to open vector map <%s> on level %d. " 00280 "Try to rebuild vector topology by v.build."), 00281 Vect_get_full_name(Map), level_request); 00282 fatal_error(ferror, errmsg); 00283 return -1; 00284 } 00285 } 00286 else { 00287 level = 1; /* I.e. requested level is 1 */ 00288 } 00289 00290 /* Open level 1 files / sources (format specific) */ 00291 if (!head_only) { /* No need to open coordinates */ 00292 if (0 != (*Open_old_array[format][1]) (Map, update)) { /* Cannot open */ 00293 if (level == 2) { /* support files opened */ 00294 dig_free_plus(&(Map->plus)); 00295 dig_spidx_free(&(Map->plus)); 00296 dig_cidx_free(&(Map->plus)); 00297 } 00298 sprintf(errmsg, 00299 _("Unable to open vector map <%s> on level %d. " 00300 "Try to rebuild vector topology by v.build."), 00301 Vect_get_full_name(Map), level_request); 00302 fatal_error(ferror, errmsg); 00303 return -1; 00304 } 00305 } 00306 else { 00307 Map->head.with_z = Map->plus.with_z; /* take dimension from topo */ 00308 } 00309 00310 /* Set status */ 00311 Map->open = VECT_OPEN_CODE; 00312 Map->level = level; 00313 Map->head_only = head_only; 00314 Map->support_updated = 0; 00315 if (update) { 00316 Map->mode = GV_MODE_RW; 00317 Map->plus.mode = GV_MODE_RW; 00318 } 00319 else { 00320 Map->mode = GV_MODE_READ; 00321 Map->plus.mode = GV_MODE_READ; 00322 } 00323 if (head_only) { 00324 Map->head_only = 1; 00325 } 00326 else { 00327 Map->head_only = 0; 00328 } 00329 00330 Map->Constraint_region_flag = 0; 00331 Map->Constraint_type_flag = 0; 00332 G_debug(1, "Vect_open_old(): vector opened on level %d", level); 00333 00334 if (level == 1) { /* without topology */ 00335 Map->plus.built = GV_BUILD_NONE; 00336 } 00337 else { /* level 2, with topology */ 00338 Map->plus.built = GV_BUILD_ALL; /* Highest level of topology for level 2 */ 00339 } 00340 00341 Map->plus.do_uplist = 0; 00342 00343 Map->dblnk = Vect_new_dblinks_struct(); 00344 Vect_read_dblinks(Map); 00345 00346 /* Open history file */ 00347 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00348 00349 if (update) { /* native only */ 00350 Map->hist_fp = G_fopen_modify(buf, GRASS_VECT_HIST_ELEMENT); 00351 if (Map->hist_fp == NULL) { 00352 sprintf(errmsg, 00353 _("Unable to open history file for vector map <%s>"), 00354 Vect_get_full_name(Map)); 00355 fatal_error(ferror, errmsg); 00356 return (-1); 00357 } 00358 fseek(Map->hist_fp, (long)0, SEEK_END); 00359 Vect_hist_write(Map, 00360 "---------------------------------------------------------------------------------\n"); 00361 00362 } 00363 else { 00364 if (Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR) { 00365 Map->hist_fp = 00366 G_fopen_old(buf, GRASS_VECT_HIST_ELEMENT, Map->mapset); 00367 /* If NULL (does not exist) then Vect_hist_read() handle that */ 00368 } 00369 else { 00370 Map->hist_fp = NULL; 00371 } 00372 } 00373 00374 if (!head_only) { /* Cannot rewind if not fully opened */ 00375 Vect_rewind(Map); 00376 } 00377 00378 /* Delete support files if native format was opened for update (not head_only) */ 00379 if (update && !head_only) { 00380 char file_path[2000]; 00381 struct stat info; 00382 00383 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, name); 00384 00385 G__file_name(file_path, buf, GV_TOPO_ELEMENT, G_mapset()); 00386 if (stat(file_path, &info) == 0) /* file exists? */ 00387 unlink(file_path); 00388 00389 G__file_name(file_path, buf, GV_SIDX_ELEMENT, G_mapset()); 00390 if (stat(file_path, &info) == 0) /* file exists? */ 00391 unlink(file_path); 00392 00393 G__file_name(file_path, buf, GV_CIDX_ELEMENT, G_mapset()); 00394 if (stat(file_path, &info) == 0) /* file exists? */ 00395 unlink(file_path); 00396 } 00397 00398 return (level); 00399 } 00400 00413 int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset) 00414 { 00415 return (Vect__open_old(Map, name, mapset, 0, 0)); 00416 } 00417 00430 int 00431 Vect_open_update(struct Map_info *Map, const char *name, const char *mapset) 00432 { 00433 int ret; 00434 00435 ret = Vect__open_old(Map, name, mapset, 1, 0); 00436 00437 if (ret > 0) { 00438 Map->plus.do_uplist = 1; 00439 00440 Map->plus.uplines = NULL; 00441 Map->plus.n_uplines = 0; 00442 Map->plus.alloc_uplines = 0; 00443 Map->plus.upnodes = NULL; 00444 Map->plus.n_upnodes = 0; 00445 Map->plus.alloc_upnodes = 0; 00446 00447 /* Build spatial index from topo */ 00448 Vect_build_sidx_from_topo(Map); 00449 } 00450 00451 return ret; 00452 } 00453 00467 int 00468 Vect_open_old_head(struct Map_info *Map, const char *name, const char *mapset) 00469 { 00470 return (Vect__open_old(Map, name, mapset, 0, 1)); 00471 } 00472 00485 int 00486 Vect_open_update_head(struct Map_info *Map, const char *name, 00487 const char *mapset) 00488 { 00489 int ret; 00490 00491 ret = Vect__open_old(Map, name, mapset, 1, 1); 00492 00493 if (ret > 0) { /* Probably not important */ 00494 Map->plus.do_uplist = 1; 00495 00496 Map->plus.uplines = NULL; 00497 Map->plus.n_uplines = 0; 00498 Map->plus.alloc_uplines = 0; 00499 Map->plus.upnodes = NULL; 00500 Map->plus.n_upnodes = 0; 00501 Map->plus.alloc_upnodes = 0; 00502 } 00503 00504 return ret; 00505 } 00506 00517 int Vect_open_new(struct Map_info *Map, const char *name, int with_z) 00518 { 00519 int ret, ferror; 00520 char errmsg[2000], buf[200]; 00521 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00522 00523 G_debug(2, "Vect_open_new(): name = %s", name); 00524 00525 Vect__init_head(Map); 00526 ferror = Vect_get_fatal_error(); 00527 Vect_set_fatal_error(GV_FATAL_EXIT); 00528 00529 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00530 if (strcmp(xmapset, G_mapset()) != 0) { 00531 sprintf(errmsg, _("%s is not in the current mapset (%s)"), name, 00532 G_mapset()); 00533 fatal_error(ferror, errmsg); 00534 } 00535 name = xname; 00536 } 00537 00538 /* check for [A-Za-z][A-Za-z0-9_]* in name */ 00539 if (Vect_legal_filename(name) < 0) { 00540 sprintf(errmsg, _("Vector map name is not SQL compliant")); 00541 fatal_error(ferror, errmsg); 00542 return (-1); 00543 } 00544 00545 /* Check if map already exists */ 00546 if (G_find_file2(GRASS_VECT_DIRECTORY, name, G_mapset()) != NULL) { 00547 G_warning(_("Vector map <%s> already exists and will be overwritten"), 00548 name); 00549 00550 ret = Vect_delete(name); 00551 if (ret == -1) { 00552 sprintf(errmsg, _("Unable to delete vector map <%s>"), name); 00553 fatal_error(ferror, errmsg); 00554 return (-1); 00555 } 00556 } 00557 00558 Map->name = G_store(name); 00559 Map->mapset = G_store(G_mapset()); 00560 Map->location = G_store(G_location()); 00561 Map->gisdbase = G_store(G_gisdbase()); 00562 00563 Map->format = GV_FORMAT_NATIVE; 00564 00565 if (V1_open_new_nat(Map, name, with_z) < 0) { 00566 sprintf(errmsg, _("Unable to create vector map <%s>"), 00567 Vect_get_full_name(Map)); 00568 fatal_error(ferror, errmsg); 00569 return (-1); 00570 } 00571 00572 /* Open history file */ 00573 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00574 Map->hist_fp = G_fopen_new(buf, GRASS_VECT_HIST_ELEMENT); 00575 if (Map->hist_fp == NULL) { 00576 sprintf(errmsg, _("Unable to open history file for vector map <%s>"), 00577 Vect_get_full_name(Map)); 00578 fatal_error(ferror, errmsg); 00579 return (-1); 00580 } 00581 00582 Open_level = 0; 00583 00584 dig_init_plus(&(Map->plus)); 00585 00586 Map->open = VECT_OPEN_CODE; 00587 Map->level = 1; 00588 Map->head_only = 0; 00589 Map->support_updated = 0; 00590 Map->plus.built = GV_BUILD_NONE; 00591 Map->mode = GV_MODE_RW; 00592 Map->Constraint_region_flag = 0; 00593 Map->Constraint_type_flag = 0; 00594 Map->head.with_z = with_z; 00595 Map->plus.do_uplist = 0; 00596 00597 Map->dblnk = Vect_new_dblinks_struct(); 00598 00599 return 1; 00600 } 00601 00611 int Vect_coor_info(struct Map_info *Map, struct Coor_info *Info) 00612 { 00613 char buf[2000], path[2000]; 00614 struct stat stat_buf; 00615 00616 switch (Map->format) { 00617 case GV_FORMAT_NATIVE: 00618 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00619 G__file_name(path, buf, GRASS_VECT_COOR_ELEMENT, Map->mapset); 00620 G_debug(1, "get coor info: %s", path); 00621 if (0 != stat(path, &stat_buf)) { 00622 G_warning(_("Unable to stat file <%s>"), path); 00623 Info->size = -1L; 00624 Info->mtime = -1L; 00625 } 00626 else { 00627 Info->size = (long)stat_buf.st_size; /* file size */ 00628 Info->mtime = (long)stat_buf.st_mtime; /* last modified time */ 00629 } 00630 /* stat does not give correct size on MINGW 00631 * if the file is opened */ 00632 #ifdef __MINGW32__ 00633 if (Map->open == VECT_OPEN_CODE) { 00634 dig_fseek(&(Map->dig_fp), 0L, SEEK_END); 00635 G_debug(2, "ftell = %d", dig_ftell(&(Map->dig_fp))); 00636 Info->size = dig_ftell(&(Map->dig_fp)); 00637 } 00638 #endif 00639 break; 00640 case GV_FORMAT_OGR: 00641 Info->size = 0L; 00642 Info->mtime = 0L; 00643 break; 00644 } 00645 G_debug(1, "Info->size = %ld, Info->mtime = %ld", Info->size, 00646 Info->mtime); 00647 00648 return 1; 00649 } 00650 00659 const char *Vect_maptype_info(struct Map_info *Map) 00660 { 00661 char maptype[1000]; 00662 00663 switch (Map->format) { 00664 case GV_FORMAT_NATIVE: 00665 sprintf(maptype, "native"); 00666 break; 00667 case GV_FORMAT_OGR: 00668 sprintf(maptype, "ogr"); 00669 break; 00670 default: 00671 sprintf(maptype, "unknown %d (update Vect_maptype_info)", 00672 Map->format); 00673 } 00674 00675 return G_store(maptype); 00676 } 00677 00678 00689 int Vect_open_topo(struct Map_info *Map, int head_only) 00690 { 00691 int err, ret; 00692 char buf[500], file_path[2000]; 00693 GVFILE fp; 00694 struct Coor_info CInfo; 00695 struct Plus_head *Plus; 00696 struct stat info; 00697 00698 G_debug(1, "Vect_open_topo(): name = %s mapset= %s", Map->name, 00699 Map->mapset); 00700 00701 Plus = &(Map->plus); 00702 00703 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00704 G__file_name(file_path, buf, GV_TOPO_ELEMENT, Map->mapset); 00705 00706 if (stat(file_path, &info) != 0) /* does not exist */ 00707 return 1; 00708 00709 dig_file_init(&fp); 00710 fp.file = G_fopen_old(buf, GV_TOPO_ELEMENT, Map->mapset); 00711 00712 if (fp.file == NULL) { /* topo file is not available */ 00713 G_debug(1, "Cannot open topo file for vector '%s@%s'.", 00714 Map->name, Map->mapset); 00715 return -1; 00716 } 00717 00718 /* get coor info */ 00719 Vect_coor_info(Map, &CInfo); 00720 00721 /* load head */ 00722 if (dig_Rd_Plus_head(&fp, Plus) == -1) 00723 return -1; 00724 00725 G_debug(1, "Topo head: coor size = %ld, coor mtime = %ld", 00726 Plus->coor_size, Plus->coor_mtime); 00727 00728 /* do checks */ 00729 err = 0; 00730 if (CInfo.size != Plus->coor_size) { 00731 G_warning(_("Size of 'coor' file differs from value saved in topology file")); 00732 err = 1; 00733 } 00734 /* Do not check mtime because mtime is changed by copy */ 00735 /* 00736 if ( CInfo.mtime != Plus->coor_mtime ) { 00737 G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n"); 00738 err = 1; 00739 } 00740 */ 00741 if (err) { 00742 G_warning(_("Please rebuild topology for vector map <%s@%s>"), 00743 Map->name, Map->mapset); 00744 return -1; 00745 } 00746 00747 /* load file to the memory */ 00748 /* dig_file_load ( &fp); */ 00749 00750 /* load topo to memory */ 00751 ret = dig_load_plus(Plus, &fp, head_only); 00752 00753 fclose(fp.file); 00754 /* dig_file_free ( &fp); */ 00755 00756 if (ret == 0) 00757 return -1; 00758 00759 return 0; 00760 } 00761 00770 int Vect_open_spatial_index(struct Map_info *Map) 00771 { 00772 char buf[500]; 00773 GVFILE fp; 00774 00775 /* struct Coor_info CInfo; */ 00776 struct Plus_head *Plus; 00777 00778 G_debug(1, "Vect_open_spatial_index(): name = %s mapset= %s", Map->name, 00779 Map->mapset); 00780 00781 Plus = &(Map->plus); 00782 00783 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name); 00784 dig_file_init(&fp); 00785 fp.file = G_fopen_old(buf, GV_SIDX_ELEMENT, Map->mapset); 00786 00787 if (fp.file == NULL) { /* spatial index file is not available */ 00788 G_debug(1, "Cannot open spatial index file for vector '%s@%s'.", 00789 Map->name, Map->mapset); 00790 return -1; 00791 } 00792 00793 /* TODO: checks */ 00794 /* load head */ 00795 /* 00796 dig_Rd_spindx_head (fp, Plus); 00797 G_debug ( 1, "Spindx head: coor size = %ld, coor mtime = %ld", 00798 Plus->coor_size, Plus->coor_mtime); 00799 00800 */ 00801 /* do checks */ 00802 /* 00803 err = 0; 00804 if ( CInfo.size != Plus->coor_size ) { 00805 G_warning ( "Size of 'coor' file differs from value saved in topo file.\n"); 00806 err = 1; 00807 } 00808 */ 00809 /* Do not check mtime because mtime is changed by copy */ 00810 /* 00811 if ( CInfo.mtime != Plus->coor_mtime ) { 00812 G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n"); 00813 err = 1; 00814 } 00815 */ 00816 /* 00817 if ( err ) { 00818 G_warning ( "Please rebuild topology for vector '%s@%s'\n", Map->name, 00819 Map->mapset ); 00820 return -1; 00821 } 00822 */ 00823 00824 /* load file to the memory */ 00825 /* dig_file_load ( &fp); */ 00826 00827 /* load topo to memory */ 00828 dig_spidx_init(Plus); 00829 dig_read_spidx(&fp, Plus); 00830 00831 fclose(fp.file); 00832 /* dig_file_free ( &fp); */ 00833 00834 return 0; 00835 }