Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- struct point { double x, y; };
- struct map {
- size_t count; /* number of points in this map */
- struct point *points; /* array of points in the map */
- };
- /* lets initialize some of them */
- struct map * map_init(size_t count)
- {
- struct map *m = (struct map *) malloc(sizeof (struct map));
- if ( !m )
- return NULL;
- m->count = count;
- m->point = (struct point *)malloc (count * sizeof(struct point));
- if ( !m->point ) {
- free(m);
- m = NULL;
- }
- return m;
- }
- void map_free(struct map *m)
- {
- if ( m ) {
- if ( m->points )
- free (m->points);
- free(m);
- }
- }
- struct point *map_set_point(struct map *m, int index, struct point *p)
- {
- if ( !m )
- return NULL;
- if ( index < m->count ) {
- m->points[index].x = p->x;
- m->points[index].y = p->y;
- return &m->points[index];
- }
- return NULL;
- }
- struct point *map_get_point(struct map *m, int index)
- {
- if ( !m || index < 0 || index >= m->count ) {
- return NULL;
- }
- return &m->points[index];
- }
- struct point *map_set_point_xy(struct map *m, int index, double x, double y)
- {
- struct point p;
- p.x = x;
- p.y = y;
- return map_set_point(m, index, &p);
- }
- size_t map_get_count(struct map *m)
- {
- if ( m )
- return m->count;
- return ((size_t)-1);
- }
- typedef int (*point_callback_func_t)(struct point *p);
- int for_each_point_call(struct map *m, point_callback_func_t f, int *error)
- {
- int k;
- int rv; /* return value from call back function */
- for (k = 0; k < m->count; k++) {
- if ((rv = f(&m->points[k])) != 0 ) {
- if (error != NULL)
- *error =rv;
- break;
- }
- }
- return (k - m->count); /*
- * if we go through all of the points this will be zero
- * otherwise it will be a negative number indicating how far
- * we were able to go in the loop
- */
- }
- struct mapset {
- size_t count; /* number of maps in this set */
- struct map **maps; /* a NULL terminated array of maps in this set */
- };
- /*
- * The read_maps_from_file reads a text file of the format:
- MAP
- <M>
- <x1>, <y1>
- <x2>, <y2>
- ...
- <xM>, <yM>
- MAP
- <N>
- <x1>, <y1>
- <x2>, <y2>
- ...
- <xN>, <yN>
- and so on and can return a struct mapset filled with the map
- coordinates
- A file with 3 maps would be:
- --CUT-HERE--
- MAP
- 3
- 5.5, 2.2
- -3.5, 5.9
- 2.0, -125.0
- MAP
- 5
- 2.2, -89.0
- 551, 223.5
- 7.5, -8.9
- 7.8, 6.9
- 4.3, -9.9
- MAP
- 1
- 2.5, 0.3
- --CUT-HERE--
- */
- /* A NOTE ON GOTOs:
- * this function uses gotos to get out of the sitations where it's unable to build a
- * proper map for whatever reason; and before any puritan structural programmers
- * jump down my throat for using gotos I would like you to examine the code
- * and determine that it is actually the better and cleaner way to program
- * error handling using the approach given here.
- */
- void free_mapset(struct mapset *set) {
- int k;
- if ( set ) {
- if ( set->maps ) {
- for(k = 0; k < set->count; k++) {
- map_free(set->maps[k]);
- }
- }
- free(set);
- }
- }
- struct mapset *load_mapset(const char *filename)
- {
- FILE * fp;
- struct mapset *set;
- size_t mapcnt = 0; /* number of maps in this set */
- char buf[1024]; /* line buffer */
- struct map *tmpmap;
- size_t tmpcnt;
- struct map **tmp_maps_arr;
- double x, y;
- int k;
- set = (struct mapset*) malloc(sizeof(struct mapset));
- if ( !set )
- goto build_error;
- set->count = 0;
- set->maps = NULL;
- fp = fopen("somefile.txt", "r");
- while(!feof(fp)) {
- fgets(buf, sizeof(buf), fp); /* read a line */
- if ( strcmp ( buf, "MAP") != 0 ) /* look for keyword 'MAP' */
- continue; /* nope, let's reloop */
- /* found 'MAP' read the next line to get the count */
- fgets(buf, sizeof(buf), fp);
- if (feof(fp))
- goto build_error;
- sscanf(buf, "%lu", &tmpcnt); /* number of points in this map */
- tmpmap = map_init(tmpcnt); /* make a tmpmap of tmpcnt points */
- if ( !tmpmap )
- goto build_error;
- for ( k = 0; k < tmpcnt; k++ ) {
- fgets(buf, sizeof(buf), fp);
- if (feof(fp))
- goto build_error;
- sscanf(buf, "%lf , %lf", &x, &y);
- map_set_point_xy(tmpmap, k, x, y); /* add x, y to index k */
- }
- /* try to increase the size of maps array */
- tmp_maps_arr= (struct map **) realloc(set->maps, sizeof(struct map *) * (1+set->count));
- if ( !tmp_maps_arr )
- goto build_error;
- set->maps = tmp_maps_arr;
- set->maps[set->count] = tmpmap; /* save the pointer to the map */
- set->count++;
- tmpmap = NULL;
- }
- return set;
- build_error:
- free_mapset(set);
- if (tmpmap)
- map_free(tmpmap);
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement