1 /* sdld.c
2 
3    Copyright (C) 2009-2010 Borut Razem
4 
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any
8 later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17 
18 #ifndef _WIN32
19 #include <libgen.h>
20 #endif
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 
26 #include "sdld.h"
27 
28 #define NELEM(x)  (sizeof (x) / sizeof (x)[0])
29 
30 
31 static int sdld = -1;
32 static enum sdld_target_e target = TARGET_ID_UNKNOWN;
33 
34 
35 static char
program_name(char * path)36 *program_name (char *path)
37 {
38 #ifdef _WIN32
39   static char fname[_MAX_FNAME];
40   char *p;
41 
42   _splitpath (path, NULL, NULL, fname, NULL);
43   /* convert it to lower case:
44      on DOS and Windows 9x the file name in argv[0] is uppercase */
45   for (p = fname; '\0' != *p; ++p)
46     *p = tolower (*p);
47   return fname;
48 #else
49   return basename (path);
50 #endif
51 }
52 
53 
54 static void
check_init(void)55 check_init(void)
56 {
57   if (sdld == -1)
58     {
59       fprintf(stderr, "sdld_init not called!\n");
60       exit (1);
61     }
62 }
63 
64 
65 void
sdld_init(char * path)66 sdld_init (char *path)
67 {
68   struct tgt_s {
69     char *str;
70     enum sdld_target_e target;
71   } tgt[] = {
72     { "gb",   TARGET_ID_GB,   },
73     { "z80",  TARGET_ID_Z80,  },
74     { "z180", TARGET_ID_Z180, },
75     { "8051", TARGET_ID_8051, },
76     { "6808", TARGET_ID_6808, },
77     { "stm8", TARGET_ID_STM8, },
78     { "pdk",  TARGET_ID_PDK,   },
79   };
80   int i = NELEM (tgt);
81 
82   char *progname = program_name (path);
83   if ((sdld = (strncmp(progname, "sdld", 4) == 0)) != 0)
84     {
85       /* exception: sdld is 8051 linker */
86       if (progname[4] == '\0')
87         target = TARGET_ID_8051;
88       else
89         {
90           for (i = 0; i < NELEM (tgt); ++i)
91             {
92               if (strstr(progname, tgt[i].str))
93                 {
94                   target = tgt[i].target;
95                   break;
96                 }
97             }
98         }
99     }
100   /* diagnostic message */
101   if (getenv ("SDLD_DIAG"))
102     {
103       printf ("sdld path: %s\n", path);
104       printf ("is sdld: %d\n", sdld);
105       if (sdld)
106         printf ("sdld target: %s\n", (i >= NELEM (tgt)) ? "8051" : tgt[i].str);
107     }
108 }
109 
110 
111 int
is_sdld(void)112 is_sdld(void)
113 {
114   check_init();
115   return sdld;
116 }
117 
118 
119 void
set_sdld_target(enum sdld_target_e trgt)120 set_sdld_target(enum sdld_target_e trgt)
121 {
122   target = trgt;
123 }
124 
125 
126 enum sdld_target_e
get_sdld_target(void)127 get_sdld_target(void)
128 {
129   check_init();
130   return target;
131 }
132 
133 
134 int
is_sdld_target_z80_like(void)135 is_sdld_target_z80_like(void)
136 {
137   check_init();
138   return target == TARGET_ID_Z80 || target == TARGET_ID_Z180 || target == TARGET_ID_GB;
139 }
140 
141 
142 int
is_sdld_target_8051_like(void)143 is_sdld_target_8051_like(void)
144 {
145   check_init();
146   return target == TARGET_ID_8051;
147 }
148