"Fossies" - the Fresh Open Source Software Archive

Member "xearth-1.1/markers.c" (7 Nov 1999, 14231 Bytes) of package /linux/misc/old/xearth-1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * markers.c
    3  * kirk johnson
    4  * august 1995
    5  *
    6  * Copyright (C) 1989, 1990, 1993-1995, 1999 Kirk Lauritz Johnson
    7  *
    8  * Parts of the source code (as marked) are:
    9  *   Copyright (C) 1989, 1990, 1991 by Jim Frost
   10  *   Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
   11  *
   12  * Permission to use, copy, modify and freely distribute xearth for
   13  * non-commercial and not-for-profit purposes is hereby granted
   14  * without fee, provided that both the above copyright notice and this
   15  * permission notice appear in all copies and in supporting
   16  * documentation.
   17  *
   18  * Unisys Corporation holds worldwide patent rights on the Lempel Zev
   19  * Welch (LZW) compression technique employed in the CompuServe GIF
   20  * image file format as well as in other formats. Unisys has made it
   21  * clear, however, that it does not require licensing or fees to be
   22  * paid for freely distributed, non-commercial applications (such as
   23  * xearth) that employ LZW/GIF technology. Those wishing further
   24  * information about licensing the LZW patent should contact Unisys
   25  * directly at (lzw_info@unisys.com) or by writing to
   26  *
   27  *   Unisys Corporation
   28  *   Welch Licensing Department
   29  *   M/S-C1SW19
   30  *   P.O. Box 500
   31  *   Blue Bell, PA 19424
   32  *
   33  * The author makes no representations about the suitability of this
   34  * software for any purpose. It is provided "as is" without express or
   35  * implied warranty.
   36  *
   37  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
   38  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
   39  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
   40  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   41  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
   42  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
   43  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   44  */
   45 
   46 #include "xearth.h"
   47 #include "kljcpyrt.h"
   48 
   49 #define BuiltInName "built-in"
   50 #define MaxLineLen  (1024)
   51 
   52 static void        builtin_marker_info _P((void));
   53 static void        user_marker_info _P((char *));
   54 static void        process_line _P((char *, const char *, int));
   55 static const char *decode_marker_info _P((int, char **));
   56 static const char *decode_extra_marker_info _P((int, char **, MarkerInfo *));
   57 static char       *get_line _P((FILE *, char *, int, const char **));
   58 
   59 MarkerInfo   *marker_info;
   60 static ExtArr info = NULL;
   61 
   62 /* builtin_marker_data[] contains the "built-in" marker data that is
   63  * compiled into xearth. (My apologies for misspellings, omissions of
   64  * your favorite location, or geographic inaccuracies. This is
   65  * primarily just a pile of data that I had handy instead of an
   66  * attempt to provide a sample that is "globally correct" in some
   67  * sense.)
   68  */
   69 
   70 static const char *builtin_marker_data[] =
   71 {
   72   "  61.17 -150.00 \"Anchorage\"           # Alaska, USA           ",
   73   "  38.00   23.73 \"Athens\"              # Greece                ",
   74   "  33.4    44.4  \"Baghdad\"             # Iraq                  ",
   75   "  13.73  100.50 \"Bangkok\"             # Thailand              ",
   76   "  39.92  116.43 \"Beijing\"             # China                 ",
   77   "  52.53   13.42 \"Berlin\"              # Germany               ",
   78   "  32.3   -64.7  \"Bermuda\"             # Bermuda               ",
   79   "  42.33  -71.08 \"Boston\"              # Massachusetts, USA    ",
   80   " -15.8   -47.9  \"Brasilia\"            # Brazil                ",
   81   "  -4.2    15.3  \"Brazzaville\"         # Congo                 ",
   82   " -34.67  -58.50 \"Buenos Aires\"        # Argentina             ",
   83   "  31.05   31.25 \"Cairo\"               # Egypt                 ",
   84   "  22.5    88.3  \"Calcutta\"            # India                 ",
   85   " -33.93   18.47 \"Cape Town\"           # South Africa          ",
   86   "  33.6    -7.6  \"Casablanca\"          # Morocco (Rabat?)      ",
   87   "  41.83  -87.75 \"Chicago\"             # Illinois, USA         ",
   88   "  32.78  -96.80 \"Dallas\"              # Texas, USA            ",
   89   "  28.63   77.20 \"New Delhi\"           # India                 ",
   90   "  39.75 -105.00 \"Denver\"              # Colorado, USA         ",
   91   "  24.23   55.28 \"Dubai\"               # UAE (Abu Dhabi?)      ",
   92   " -27.1  -109.4  \"Easter Island\"       # Easter Island         ",
   93   " -18.0   178.1  \"Fiji\"                # Fiji                  ",
   94   "  13.5   144.8  \"Guam\"                # Guam                  ",
   95   "  60.13   25.00 \"Helsinki\"            # Finland               ",
   96   "  22.2   114.1  \"Hong Kong\"           # Hong Kong             ",
   97   "  21.32 -157.83 \"Honolulu\"            # Hawaii, USA           ",
   98   "  52.2   104.3  \"Irkutsk\"             # Irkutsk, Russia       ",
   99   "  41.0    29.0  \"Istanbul\"            # Turkey (Ankara?)      ",
  100   "  -6.13  106.75 \"Jakarta\"             # Indonesia             ",
  101   "  31.8    35.2  \"Jerusalem\"           # Israel                ",
  102   "  34.5    69.2  \"Kabul\"               # Afghanistan           ",
  103   "  27.7    85.3  \"Kathmandu\"           # Nepal                 ",
  104   "  50.4    30.5  \"Kiev\"                # Ukraine               ",
  105   "   3.13  101.70 \"Kuala Lumpur\"        # Malaysia              ",
  106   "   6.45    3.47 \"Lagos\"               # Nigeria               ",
  107   " -12.10  -77.05 \"Lima\"                # Peru                  ",
  108   "  51.50   -0.17 \"London\"              # United Kingdom        ",
  109   "  40.42   -3.72 \"Madrid\"              # Spain                 ",
  110   "  14.6   121.0  \"Manila\"              # The Phillipines       ",
  111   "  21.5    39.8  \"Mecca\"               # Saudi Arabia          ",
  112   "  19.4   -99.1  \"Mexico City\"         # Mexico                ",
  113   "  25.8   -80.2  \"Miami\"               # Florida, USA          ",
  114   "   6.2   -10.8  \"Monrovia\"            # Liberia               ",
  115   "  45.5   -73.5  \"Montreal\"            # Quebec, Canada        ",
  116   "  55.75   37.70 \"Moscow\"              # Russia                ",
  117   "  -1.28   36.83 \"Nairobi\"             # Kenya                 ",
  118   "  59.93   10.75 \"Oslo\"                # Norway                ",
  119   "  48.87    2.33 \"Paris\"               # France                ",
  120   " -32.0   115.9  \"Perth\"               # Australia             ",
  121   "  45.5  -122.5  \"Portland\"            # Oregon, USA           ",
  122   "  -0.2   -78.5  \"Quito\"               # Ecuador               ",
  123   "  64.15  -21.97 \"Reykjavik\"           # Iceland               ",
  124   " -22.88  -43.28 \"Rio de Janeiro\"      # Brazil                ",
  125   "  41.88   12.50 \"Rome\"                # Italy                 ",
  126   "  11.0   106.7  \"Ho Chi Minh City\"    # Vietnam (Hanoi?)      ",
  127   "  37.75 -122.45 \"San Francisco\"       # California, USA       ",
  128   "   9.98  -84.07 \"San Jose\"            # Costa Rica            ",
  129   "  18.5   -66.1  \"San Juan\"            # Puerto Rico           ",
  130   " -33.5   -70.7  \"Santiago\"            # Chile                 ",
  131   "   1.2   103.9  \"Singapore\"           # Singapore             ",
  132   "  42.67   23.30 \"Sofia\"               # Bulgaria              ",
  133   "  59.33   18.08 \"Stockholm\"           # Sweden                ",
  134   " -33.92  151.17 \"Sydney\"              # Australia             ",
  135   " -17.6  -149.5  \"Tahiti\"              # Tahiti                ",
  136   "  16.8    -3.0  \"Timbuktu\"            # Mali (Bamako?)        ",
  137   "  35.67  139.75 \"Tokyo\"               # Japan                 ",
  138   "  43.70  -79.42 \"Toronto\"             # Ontario, Canada       ",
  139   "  32.9    13.2  \"Tripoli\"             # Libya                 ",
  140   "  47.9   106.9  \"Ulan Bator\"          # Mongolia              ",
  141   "  49.22 -123.10 \"Vancouver\"           # B.C., Canada          ",
  142   "  48.22   16.37 \"Vienna\"              # Austria               ",
  143   "  38.9   -77.0  \"Washington\"          # United States         ",
  144   " -41.28  174.78 \"Wellington\"          # New Zealand           ",
  145   "  62.5  -114.3  \"Yellowknife\"         # N.T., Canada          ",
  146   "  90.00    0.00 \"North Pole\"          # North Pole            ",
  147   " -90.00    0.00 \"South Pole\"          # South Pole            ",
  148   NULL
  149 };
  150 
  151 
  152 void load_marker_info(fname)
  153      char *fname;
  154 {
  155   int         i;
  156   MarkerInfo *new;
  157 
  158   if (info == NULL)
  159   {
  160     /* first time through, allocate a new extarr
  161      */
  162     info = extarr_alloc(sizeof(MarkerInfo));
  163   }
  164   else
  165   {
  166     /* on subsequent passes, just clean it up for reuse
  167      */
  168     for (i=0; i<(info->count-1); i++)
  169       free(((MarkerInfo *) info->body)[i].label);
  170     info->count = 0;
  171   }
  172 
  173   if (strcmp(fname, BuiltInName) == 0)
  174     builtin_marker_info();
  175   else
  176     user_marker_info(fname);
  177 
  178   new = (MarkerInfo *) extarr_next(info);
  179   new->lat   = 0;
  180   new->lon   = 0;
  181   new->label = NULL;
  182 
  183   marker_info = (MarkerInfo *) info->body;
  184 }
  185 
  186 
  187 static void builtin_marker_info()
  188 {
  189   int   idx;
  190   char *buf;
  191 
  192   buf = (char *) malloc(MaxLineLen);
  193   assert(buf != NULL);
  194 
  195   idx = 0;
  196   while (builtin_marker_data[idx] != NULL)
  197   {
  198     strcpy(buf, builtin_marker_data[idx]);
  199     idx += 1;
  200     process_line(buf, BuiltInName, idx);
  201   }
  202 
  203   free(buf);
  204 }
  205 
  206 
  207 static void user_marker_info(fname)
  208      char *fname;
  209 {
  210   int         idx;
  211   char       *buf;
  212   const char *msg;
  213   FILE       *ins;
  214 
  215   ins = fopen(fname, "r");
  216   if (ins == NULL)
  217   {
  218     warning("unable to open marker info file");
  219     return;
  220   }
  221 
  222   idx = 1;
  223   buf = (char *) malloc(MaxLineLen);
  224   assert(buf != NULL);
  225 
  226   while (get_line(ins, buf, MaxLineLen, &msg) != NULL)
  227   {
  228     if (msg != NULL)
  229     {
  230       fflush(stdout);
  231       fprintf(stderr, "%s, line %d: %s\n", fname, idx, msg);
  232       fprintf(stderr, " (length = %d)\n", (int) strlen(buf));
  233       fflush(stderr);
  234     }
  235 
  236     process_line(buf, fname, idx);
  237     idx += 1;
  238   }
  239 
  240   free(buf);
  241   fclose(ins);
  242 }
  243 
  244 
  245 static void process_line(buf, fname, idx)
  246      char       *buf;
  247      const char *fname;
  248      int         idx;
  249 {
  250   int         tokc;
  251   char      **tokv;
  252   const char *msg;
  253 
  254   tokv = tokenize(buf, &tokc, &msg);
  255   if (msg != NULL)
  256   {
  257     fflush(stdout);
  258     fprintf(stderr, "%s, line %d: %s\n", fname, idx, msg);
  259     fflush(stderr);
  260   }
  261 
  262   msg = decode_marker_info(tokc, tokv);
  263   if (msg != NULL)
  264   {
  265     fflush(stdout);
  266     fprintf(stderr, "%s, line %d: %s\n", fname, idx, msg);
  267     fflush(stderr);
  268   }
  269 
  270   free(tokv);
  271 }
  272 
  273 
  274 
  275 static const char *decode_marker_info(tokc, tokv)
  276      int    tokc;
  277      char **tokv;
  278 {
  279   double      lat;
  280   double      lon;
  281   char       *label;
  282   MarkerInfo *new;
  283   const char *rslt;
  284 
  285   if (tokc == 0)
  286   {
  287     /* blank or comment line, no problem
  288      */
  289     rslt = NULL;
  290   }
  291   else if (tokc < 3)
  292   {
  293     /* less than three tokens is a problem
  294      */
  295     rslt = "syntax error in required info";
  296   }
  297   else
  298   {
  299     /* decode first three tokens
  300      */
  301     sscanf(tokv[0], "%lf", &lat);
  302     sscanf(tokv[1], "%lf", &lon);
  303     label = (char *) malloc(strlen(tokv[2]) + 1);
  304     assert(label != NULL);
  305     strcpy(label, tokv[2]);
  306 
  307     if ((lat > 90) || (lat < -90))
  308     {
  309       rslt = "latitude must be between -90 and 90";
  310     }
  311     else if ((lon > 180) || (lon < -180))
  312     {
  313       rslt = "longitude must be between -180 and 180";
  314     }
  315     else
  316     {
  317       new = (MarkerInfo *) extarr_next(info);
  318       new->lat   = lat;
  319       new->lon   = lon;
  320       new->label = label;
  321 
  322       /* decode any extra tokens
  323        */
  324       rslt = decode_extra_marker_info(tokc-3, tokv+3, new);
  325     }
  326   }
  327 
  328   return rslt;
  329 }
  330 
  331 
  332 static const char *decode_extra_marker_info(tokc, tokv, inf)
  333      int        tokc;
  334      char     **tokv;
  335      MarkerInfo *inf;
  336 {
  337   int   i;
  338   char *key;
  339   char *val;
  340 
  341   /* set defaults
  342    */
  343   inf->align = MarkerAlignDefault;
  344 
  345   for (i=0; i<tokc; i++)
  346   {
  347     /* look for '=' separator; quit gracefully if none found, else
  348      * change it to a NUL and set key and val appropriately
  349      */
  350     val = tokv[i];
  351     while ((*val != '=') && (*val != '\0'))
  352       val += 1;
  353 
  354     if (*val == '\0')
  355       return "syntax error in optional info";
  356 
  357     key  = tokv[i];
  358     *val = '\0';
  359     val += 1;
  360 
  361     /* big decoding switch
  362      */
  363     if (strcmp(key, "align") == 0)
  364     {
  365       if (strcmp(val, "left") == 0)
  366         inf->align = MarkerAlignLeft;
  367       else if (strcmp(val, "right") == 0)
  368         inf->align = MarkerAlignRight;
  369       else if (strcmp(val, "above") == 0)
  370         inf->align = MarkerAlignAbove;
  371       else if (strcmp(val, "below") == 0)
  372         inf->align = MarkerAlignBelow;
  373       else
  374         return "unrecognized alignment value";
  375     }
  376     else
  377     {
  378       return "unrecognized key in optional info";
  379     }
  380   }
  381 
  382   return NULL;
  383 }
  384 
  385 
  386 static char *get_line(ins, buf, len, msg)
  387      FILE        *ins;
  388      char        *buf;
  389      int          len;
  390      const char **msg;
  391 {
  392   int   ch;
  393   char *rslt;
  394 
  395   *msg = NULL;
  396   rslt = buf;
  397 
  398   while (1)
  399   {
  400     ch = getc(ins);
  401 
  402     if (ch == EOF)
  403     {
  404       if (buf == rslt)
  405       {
  406         /* if EOF is the first thing we read on a line,
  407          * there aren't any more lines to read
  408          */
  409         rslt = NULL;
  410         break;
  411       }
  412       else
  413       {
  414         /* line terminated by EOF
  415          */
  416         *buf = '\0';
  417         break;
  418       }
  419     }
  420     else if (ch == '\n')
  421     {
  422       /* line terminated by newline
  423        */
  424       *buf = '\0';
  425       break;
  426     }
  427     else
  428     {
  429       *buf = ch;
  430       buf += 1;
  431       len -= 1;
  432 
  433       if (len == 0)
  434       {
  435         /* line terminated by exceeding maximum length
  436          */
  437         *msg = "line exceeds maximum length";
  438         *(buf-1) = '\0';
  439         do
  440           ch = getc(ins);
  441         while ((ch != EOF) && (ch != '\n'));
  442         break;
  443       }
  444     }
  445   }
  446 
  447   return rslt;
  448 }
  449 
  450 
  451 void show_marker_info(fname)
  452      char *fname;
  453 {
  454   MarkerInfo *minfo;
  455 
  456   printf("# xearth marker data from \"%s\":\n", fname);
  457 
  458   load_marker_info(fname);
  459 
  460   minfo = marker_info;
  461   while (minfo->label != NULL)
  462   {
  463     printf("%7.2f %8.2f \"%s\"", minfo->lat, minfo->lon, minfo->label);
  464 
  465     if (minfo->align == MarkerAlignLeft)
  466       printf(" align=left");
  467     else if (minfo->align == MarkerAlignRight)
  468       printf(" align=right");
  469     else if (minfo->align == MarkerAlignAbove)
  470       printf(" align=above");
  471     else if (minfo->align == MarkerAlignBelow)
  472       printf(" align=below");
  473     else
  474       assert(minfo->align == MarkerAlignDefault);
  475 
  476     printf("\n");
  477     minfo += 1;
  478   }
  479 
  480   exit(0);
  481 }