Print this page
make: translate using gettext, rather than the unmaintainable catgets


  20  */
  21 /*
  22  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  *      read.c
  28  *
  29  *      This file contains the makefile reader.
  30  */
  31 
  32 /*
  33  * Included files
  34  */
  35 #include <mk/defs.h>
  36 #include <mksh/dosys.h>           /* sh_command2string() */
  37 #include <mksh/macro.h>           /* expand_value() */
  38 #include <mksh/misc.h>            /* retmem() */
  39 #include <stdarg.h>               /* va_list, va_start(), va_end() */

  40 
  41 /*
  42  * Defined macros
  43  */
  44 
  45 /*
  46  * typedefs & structs
  47  */
  48 
  49 /*
  50  * Static variables
  51  */
  52 static  Boolean         built_last_make_run_seen;
  53 
  54 /*
  55  * File table of contents
  56  */
  57 static  Name_vector     enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
  58 extern  Name            normalize_name(register wchar_t *name_string, register int length);
  59 static  void            read_suffixes_list(register Name_vector depes);


 654         /* makefile we remember that */
 655         Wstring tstr(target);
 656         wchar_t * wcb = tstr.get_string();
 657         if ((makefile_type == reading_makefile) &&
 658             (default_target_to_build == NULL) &&
 659             ((wcb[0] != (int) period_char) ||
 660              wschr(wcb, (int) slash_char))) {
 661 
 662 /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
 663 ** The target with empty name cannot be default_target_to_build
 664 */
 665                 if (target->hash.length != 0)
 666                         default_target_to_build = target;
 667         }
 668         /* Check if the line is ":" or "::" */
 669         if (makefile_type == reading_makefile) {
 670                 if (target->colons == no_colon) {
 671                         target->colons = separator;
 672                 } else {
 673                         if (target->colons != separator) {
 674                                 fatal_reader(catgets(catd, 1, 92, ":/:: conflict for target `%s'"),
 675                                              target->string_mb);
 676                         }
 677                 }
 678                 if (target->colons == two_colon) {
 679                         if (depes->used == 0) {
 680                                 /* If this is a "::" type line with no */
 681                                 /* dependencies we add one "FRC" type */
 682                                 /* dependency for free */
 683                                 depes->used = 1; /* Force :: targets with no
 684                                                   * depes to always run */
 685                                 depes->names[0] = force;
 686                         }
 687                         /* Do not delete "::" type targets when interrupted */
 688                         target->stat.is_precious = true;
 689                         /*
 690                          * Build a synthetic target "<number>%target"
 691                          * for "target".
 692                          */
 693                         mb_namep = getmem((int) (strlen(target->string_mb) + 10));
 694                         namep = ALLOC_WC((int) (target->hash.length + 10));


 788                 /* Reading report file from programs that reports */
 789                 /* dependencies. If this is the first time the target is */
 790                 /* read from this reportfile we clear all old */
 791                 /* automatic depes */
 792                 if (target->temp_file_number == temp_file_number) {
 793                         break;
 794                 }
 795                 target->temp_file_number = temp_file_number;
 796                 command_changed = true;
 797                 if (line != NULL) {
 798                         for (dp = line->body.line.dependencies;
 799                              dp != NULL;
 800                              dp = dp->next) {
 801                                 if (dp->automatic) {
 802                                         dp->stale = true;
 803                                 }
 804                         }
 805                 }
 806                 break;
 807         default:
 808                 fatal_reader(catgets(catd, 1, 93, "Internal error. Unknown makefile type %d"),
 809                              makefile_type);
 810         }
 811         /* A target may only be involved in one target group */
 812         if (line->body.line.target_group != NULL) {
 813                 if (target_group != NULL) {
 814                         fatal_reader(catgets(catd, 1, 94, "Too many target groups for target `%s'"),
 815                                      target->string_mb);
 816                 }
 817         } else {
 818                 line->body.line.target_group = target_group;
 819         }
 820 
 821         if (trace_reader) {
 822                 (void) printf("%s:\t", target->string_mb);
 823         }
 824         /* Enter the dependencies */
 825         register_as_auto = BOOLEAN(makefile_type != reading_makefile);
 826         not_auto_found = false;
 827         for (;
 828              (depes != NULL) && !not_auto_found;
 829              depes = depes->next) {
 830                 for (i = 0; i < depes->used; i++) {
 831                         /* the dependency .NOT_AUTO signals beginning of
 832                          * explicit dependancies which were put at end of
 833                          * list in .make.state file - we stop entering
 834                          * dependencies at this point


1061  */
1062 Dyntarget
1063 enter_dyntarget(register Name target)
1064 {
1065         register Dyntarget      result = ALLOC(Dyntarget);
1066         Dyntarget               p;
1067         Dyntarget               *insert;
1068         int                             i;
1069 
1070         result->next = NULL;
1071         result->name = target;
1072 
1073 
1074         /* Find the end of the dyntarget list and append the new pattern */
1075         for (insert = &dyntarget_list, p = *insert;
1076              p != NULL;
1077              insert = &p->next, p = *insert);
1078         *insert = result;
1079 
1080         if (trace_reader) {
1081                 (void) printf(NOCATGETS("Dynamic target %s:\n"), result->name->string_mb);
1082         }
1083         return( result);
1084 }
1085 
1086 
1087 /*
1088  *      special_reader(target, depes, command)
1089  *
1090  *      Read the pseudo targets make knows about
1091  *      This handles the special targets that should not be entered as regular
1092  *      target/dependency sets.
1093  *
1094  *      Parameters:
1095  *              target          The special target
1096  *              depes           The list of dependencies it was entered with
1097  *              command         The command it was entered with
1098  *
1099  *      Static variables used:
1100  *              built_last_make_run_seen Set to indicate .BUILT_LAST... seen
1101  *


1116  *              only_parallel   Set to indicate only some targets runs parallel
1117  *              parallel_name   The Name ".PARALLEL", used for tracing
1118  *              precious        The Name ".PRECIOUS", used for tracing
1119  *              sccs_get_name   The Name ".SCCS_GET", used for tracing
1120  *              sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
1121  *              get_name        The Name ".GET", used for tracing
1122  *              sccs_get_rule   Set when ".SCCS_GET" target is read
1123  *              silent          Set when ".SILENT" target is read
1124  *              silent_name     The Name ".SILENT", used for tracing
1125  *              trace_reader    Indicates that we should echo stuff we read
1126  */
1127 void
1128 special_reader(Name target, register Name_vector depes, Cmd_line command)
1129 {
1130         register int            n;
1131 
1132         switch (target->special_reader) {
1133 
1134         case svr4_special:
1135                 if (depes->used != 0) {
1136                         fatal_reader(catgets(catd, 1, 98, "Illegal dependencies for target `%s'"),
1137                                      target->string_mb);
1138                 }
1139                 svr4  = true;
1140                 posix  = false;
1141                 keep_state = false;
1142                 all_parallel = false;
1143                 only_parallel = false;
1144                 if (trace_reader) {
1145                         (void) printf("%s:\n", svr4_name->string_mb);
1146                 }
1147                 break;
1148 
1149         case posix_special:
1150                 if(svr4)
1151                   break;
1152                 if (depes->used != 0) {
1153                         fatal_reader(catgets(catd, 1, 99, "Illegal dependencies for target `%s'"),
1154                                      target->string_mb);
1155                 }
1156                 posix  = true;
1157                         /* with posix on, use the posix get rule */
1158                 sccs_get_rule = sccs_get_posix_rule;
1159                         /* turn keep state off being SunPro make specific */
1160                 keep_state = false;
1161                 /* Use /usr/xpg4/bin/sh on Solaris */
1162                 MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
1163                 (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
1164                 if (trace_reader) {
1165                         (void) printf("%s:\n", posix_name->string_mb);
1166                 }
1167                 break;
1168 
1169         case built_last_make_run_special:
1170                 built_last_make_run_seen = true;
1171                 break;
1172 
1173         case default_special:
1174                 if (depes->used != 0) {
1175                         warning(catgets(catd, 1, 100, "Illegal dependency list for target `%s'"),
1176                                 target->string_mb);
1177                 }
1178                 default_rule = command;
1179                 if (trace_reader) {
1180                         (void) printf("%s:\n",
1181                                       default_rule_name->string_mb);
1182                         print_rule(command);
1183                 }
1184                 break;
1185 
1186 
1187         case ignore_special:
1188                 if ((depes->used != 0) &&(!posix)){
1189                         fatal_reader(catgets(catd, 1, 101, "Illegal dependencies for target `%s'"),
1190                                      target->string_mb);
1191                 }
1192                 if (depes->used == 0)
1193                 {
1194                    ignore_errors_all = true;
1195                 }
1196                 if(svr4) {
1197                   ignore_errors_all = true;
1198                   break;
1199                 }
1200                 for (; depes != NULL; depes = depes->next) {
1201                         for (n = 0; n < depes->used; n++) {
1202                                 depes->names[n]->ignore_error_mode = true;
1203                         }
1204                 }
1205                 if (trace_reader) {
1206                         (void) printf("%s:\n", ignore_name->string_mb);
1207                 }
1208                 break;
1209 
1210         case keep_state_special:
1211                 if(svr4)
1212                   break;
1213                         /* ignore keep state, being SunPro make specific */
1214                 if(posix)
1215                   break;
1216                 if (depes->used != 0) {
1217                         fatal_reader(catgets(catd, 1, 102, "Illegal dependencies for target `%s'"),
1218                                      target->string_mb);
1219                 }
1220                 keep_state = true;
1221                 if (trace_reader) {
1222                         (void) printf("%s:\n",
1223                                       dot_keep_state->string_mb);
1224                 }
1225                 break;
1226 
1227         case keep_state_file_special:
1228                 if(svr4)
1229                   break;
1230                 if(posix)
1231                   break;
1232                         /* it's not necessary to specify KEEP_STATE, if this 
1233                         ** is given, so set the keep_state.
1234                         */
1235                 keep_state = true;
1236                 if (depes->used != 0) {
1237                    if((!make_state) ||(!strcmp(make_state->string_mb,NOCATGETS(".make.state")))) {
1238                      make_state = depes->names[0];
1239                    }
1240                 }
1241                 break;
1242         case make_version_special:
1243                 if(svr4)
1244                   break;
1245                 if (depes->used != 1) {
1246                         fatal_reader(catgets(catd, 1, 103, "Illegal dependency list for target `%s'"),
1247                                      target->string_mb);
1248                 }
1249                 if (depes->names[0] != current_make_version) {
1250                         /*
1251                          * Special case the fact that version 1.0 and 1.1
1252                          * are identical.
1253                          */
1254                         if (!IS_EQUAL(depes->names[0]->string_mb,
1255                                       NOCATGETS("VERSION-1.1")) ||
1256                             !IS_EQUAL(current_make_version->string_mb,
1257                                       NOCATGETS("VERSION-1.0"))) {
1258                                 /*
1259                                  * Version mismatches should cause the
1260                                  * .make.state file to be skipped.
1261                                  * This is currently not true - it is read
1262                                  * anyway.
1263                                  */
1264                                 warning(catgets(catd, 1, 104, "Version mismatch between current version `%s' and `%s'"),
1265                                         current_make_version->string_mb,
1266                                         depes->names[0]->string_mb);
1267                         }
1268                 }
1269                 break;
1270 
1271         case no_parallel_special:
1272                 if(svr4)
1273                   break;
1274                 /* Set the no_parallel bit for all the targets on */
1275                 /* the dependency list */
1276                 if (depes->used == 0) {
1277                         /* only those explicitly made parallel */
1278                         only_parallel = true;
1279                         all_parallel = false;
1280                 }
1281                 for (; depes != NULL; depes = depes->next) {
1282                         for (n = 0; n < depes->used; n++) {
1283                                 if (trace_reader) {
1284                                         (void) printf("%s:\t%s\n",


1348                 if(svr4) {
1349                   all_precious = true;
1350                   break;
1351                 }
1352                 /* Set the precious bit for all the targets on */
1353                 /* the dependency list */
1354                 for (; depes != NULL; depes = depes->next) {
1355                         for (n = 0; n < depes->used; n++) {
1356                                 if (trace_reader) {
1357                                         (void) printf("%s:\t%s\n",
1358                                                       precious->string_mb,
1359                                                       depes->names[n]->string_mb);
1360                                 }
1361                                 depes->names[n]->stat.is_precious = true;
1362                         }
1363                 }
1364                 break;
1365 
1366         case sccs_get_special:
1367                 if (depes->used != 0) {
1368                         fatal_reader(catgets(catd, 1, 105, "Illegal dependencies for target `%s'"),
1369                                      target->string_mb);
1370                 }
1371                 sccs_get_rule = command;
1372                 sccs_get_org_rule = command;
1373                 if (trace_reader) {
1374                         (void) printf("%s:\n", sccs_get_name->string_mb);
1375                         print_rule(command);
1376                 }
1377                 break;
1378 
1379         case sccs_get_posix_special:
1380                 if (depes->used != 0) {
1381                         fatal_reader(catgets(catd, 1, 106, "Illegal dependencies for target `%s'"),
1382                                      target->string_mb);
1383                 }
1384                 sccs_get_posix_rule = command;
1385                 if (trace_reader) {
1386                         (void) printf("%s:\n", sccs_get_posix_name->string_mb);
1387                         print_rule(command);
1388                 }
1389                 break;
1390 
1391         case get_posix_special:
1392                 if (depes->used != 0) {
1393                         fatal_reader(catgets(catd, 1, 107, "Illegal dependencies for target `%s'"),
1394                                      target->string_mb);
1395                 }
1396                 get_posix_rule = command;
1397                 if (trace_reader) {
1398                         (void) printf("%s:\n", get_posix_name->string_mb);
1399                         print_rule(command);
1400                 }
1401                 break;
1402 
1403         case get_special:
1404                 if(!svr4) {
1405                   break;
1406                 }
1407                 if (depes->used != 0) {
1408                         fatal_reader(catgets(catd, 1, 108, "Illegal dependencies for target `%s'"),
1409                                      target->string_mb);
1410                 }
1411                 get_rule = command;
1412                 sccs_get_rule = command;
1413                 if (trace_reader) {
1414                         (void) printf("%s:\n", get_name->string_mb);
1415                         print_rule(command);
1416                 }
1417                 break;
1418 
1419         case silent_special:
1420                 if ((depes->used != 0) && (!posix)){
1421                         fatal_reader(catgets(catd, 1, 109, "Illegal dependencies for target `%s'"),
1422                                      target->string_mb);
1423                 }
1424                 if (depes->used == 0)
1425                 {
1426                    silent_all = true;
1427                 }
1428                 if(svr4) {
1429                   silent_all = true;
1430                   break;
1431                 }
1432                 for (; depes != NULL; depes = depes->next) {
1433                         for (n = 0; n < depes->used; n++) {
1434                                 depes->names[n]->silent_mode = true;
1435                         }
1436                 }
1437                 if (trace_reader) {
1438                         (void) printf("%s:\n", silent_name->string_mb);
1439                 }
1440                 break;
1441 
1442         case suffixes_special:
1443                 read_suffixes_list(depes);
1444                 break;
1445 
1446         default:
1447 
1448                 fatal_reader(catgets(catd, 1, 110, "Internal error: Unknown special reader"));
1449         }
1450 }
1451 
1452 /*
1453  *      read_suffixes_list(depes)
1454  *
1455  *      Read the special list .SUFFIXES. If it is empty the old list is
1456  *      cleared. Else the new one is appended. Suffixes with ~ are extracted
1457  *      and marked.
1458  *
1459  *      Parameters:
1460  *              depes           The list of suffixes
1461  *
1462  *      Global variables used:
1463  *              hashtab         The central hashtable for Names.
1464  *              suffixes        The list of suffixes, set or appended to
1465  *              suffixes_name   The Name ".SUFFIXES", used for tracing
1466  *              trace_reader    Indicates that we should echo stuff we read
1467  */
1468 static void


1736  *              trace_reader    Indicates that we should echo stuff we read
1737  */
1738 void
1739 enter_equal(Name name, Name value, register Boolean append)
1740 {
1741         wchar_t         *string;
1742         Name            temp;
1743 
1744         if (name->colon) {
1745                 sh_transform(&name, &value);
1746         }
1747         (void) SETVAR(name, value, append);
1748 
1749         /* if we're setting FC, we want to set F77 to the same value. */
1750         Wstring nms(name);
1751         wchar_t * wcb = nms.get_string();
1752         string = wcb;
1753         if (string[0]=='F' &&
1754             string[1]=='C' &&
1755             string[2]=='\0') {
1756                 MBSTOWCS(wcs_buffer, NOCATGETS("F77"));
1757                 temp = GETNAME(wcs_buffer, FIND_LENGTH);
1758                 (void) SETVAR(temp, value, append);
1759 /*
1760                 fprintf(stderr, catgets(catd, 1, 111, "warning: FC is obsolete, use F77 instead\n"));
1761  */
1762         }
1763 
1764         if (trace_reader) {
1765                 if (value == NULL) {
1766                         (void) printf("%s %c=\n",
1767                                       name->string_mb,
1768                                       append ?
1769                                       (int) plus_char : (int) space_char);
1770                 } else {
1771                         (void) printf("%s %c= %s\n",
1772                                       name->string_mb,
1773                                       append ?
1774                                       (int) plus_char : (int) space_char,
1775                                       value->string_mb);
1776                 }
1777         }
1778 }
1779 
1780 /*


1782  *
1783  *      Parameters:
1784  *              name    The name of the macro we might transform
1785  *              value   The value to transform
1786  *
1787  */
1788 static void
1789 sh_transform(Name *name, Name *value)
1790 {
1791         /* Check if we need :sh transform */
1792         wchar_t         *colon;
1793         String_rec      command;
1794         String_rec      destination;
1795         wchar_t         buffer[1000];
1796         wchar_t         buffer1[1000];
1797 
1798         static wchar_t  colon_sh[4];
1799         static wchar_t  colon_shell[7];
1800 
1801         if (colon_sh[0] == (int) nul_char) {
1802                 MBSTOWCS(colon_sh, NOCATGETS(":sh"));
1803                 MBSTOWCS(colon_shell, NOCATGETS(":shell"));
1804         }
1805         Wstring nms((*name));
1806         wchar_t * wcb = nms.get_string();
1807 
1808         colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
1809         if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1810                 INIT_STRING_FROM_STACK(destination, buffer);
1811 
1812                 if(*value == NULL) {
1813                         buffer[0] = 0;
1814                 } else {
1815                         Wstring wcb1((*value));
1816                         if (IS_WEQUAL(colon, colon_shell)) {
1817                                 INIT_STRING_FROM_STACK(command, buffer1);
1818                                 expand_value(*value, &command, false);
1819                         } else {
1820                                 command.text.p = wcb1.get_string() + (*value)->hash.length;
1821                                 command.text.end = command.text.p;
1822                                 command.buffer.start = wcb1.get_string();
1823                                 command.buffer.end = command.text.p;


1840  *              args            arguments to match the format
1841  *
1842  *      Global variables used:
1843  *              file_being_read Name of the makefile being read
1844  *              line_number     Line that is being read
1845  *              report_pwd      Indicates whether current path should be shown
1846  *              temp_file_name  When reading tempfile we report that name
1847  */
1848 /*VARARGS*/
1849 void
1850 fatal_reader(char * pattern, ...)
1851 {
1852         va_list args;
1853         char    message[1000];
1854 
1855         va_start(args, pattern);
1856         if (file_being_read != NULL) {
1857                 WCSTOMBS(mbs_buffer, file_being_read);
1858                 if (line_number != 0) {
1859                         (void) sprintf(message,
1860                                        catgets(catd, 1, 112, "%s, line %d: %s"),
1861                                        mbs_buffer,
1862                                        line_number,
1863                                        pattern);
1864                 } else {
1865                         (void) sprintf(message,
1866                                        "%s: %s",
1867                                        mbs_buffer,
1868                                        pattern);
1869                 }
1870                 pattern = message;
1871         }
1872 
1873         (void) fflush(stdout);
1874         (void) fprintf(stderr, catgets(catd, 1, 238, "make: Fatal error in reader: "));
1875         (void) vfprintf(stderr, pattern, args);
1876         (void) fprintf(stderr, "\n");
1877         va_end(args);
1878 
1879         if (temp_file_name != NULL) {
1880                 (void) fprintf(stderr,
1881                                catgets(catd, 1, 239, "make: Temp-file %s not removed\n"),
1882                                temp_file_name->string_mb);
1883                 temp_file_name = NULL;
1884         }
1885 
1886         if (report_pwd) {
1887                 (void) fprintf(stderr,
1888                                catgets(catd, 1, 115, "Current working directory %s\n"),
1889                                get_current_path());
1890         }
1891         (void) fflush(stderr);
1892         exit_status = 1;
1893         exit(1);
1894 }
1895 


  20  */
  21 /*
  22  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  *      read.c
  28  *
  29  *      This file contains the makefile reader.
  30  */
  31 
  32 /*
  33  * Included files
  34  */
  35 #include <mk/defs.h>
  36 #include <mksh/dosys.h>           /* sh_command2string() */
  37 #include <mksh/macro.h>           /* expand_value() */
  38 #include <mksh/misc.h>            /* retmem() */
  39 #include <stdarg.h>               /* va_list, va_start(), va_end() */
  40 #include <libintl.h>
  41 
  42 /*
  43  * Defined macros
  44  */
  45 
  46 /*
  47  * typedefs & structs
  48  */
  49 
  50 /*
  51  * Static variables
  52  */
  53 static  Boolean         built_last_make_run_seen;
  54 
  55 /*
  56  * File table of contents
  57  */
  58 static  Name_vector     enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
  59 extern  Name            normalize_name(register wchar_t *name_string, register int length);
  60 static  void            read_suffixes_list(register Name_vector depes);


 655         /* makefile we remember that */
 656         Wstring tstr(target);
 657         wchar_t * wcb = tstr.get_string();
 658         if ((makefile_type == reading_makefile) &&
 659             (default_target_to_build == NULL) &&
 660             ((wcb[0] != (int) period_char) ||
 661              wschr(wcb, (int) slash_char))) {
 662 
 663 /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
 664 ** The target with empty name cannot be default_target_to_build
 665 */
 666                 if (target->hash.length != 0)
 667                         default_target_to_build = target;
 668         }
 669         /* Check if the line is ":" or "::" */
 670         if (makefile_type == reading_makefile) {
 671                 if (target->colons == no_colon) {
 672                         target->colons = separator;
 673                 } else {
 674                         if (target->colons != separator) {
 675                                 fatal_reader(gettext(":/:: conflict for target `%s'"),
 676                                              target->string_mb);
 677                         }
 678                 }
 679                 if (target->colons == two_colon) {
 680                         if (depes->used == 0) {
 681                                 /* If this is a "::" type line with no */
 682                                 /* dependencies we add one "FRC" type */
 683                                 /* dependency for free */
 684                                 depes->used = 1; /* Force :: targets with no
 685                                                   * depes to always run */
 686                                 depes->names[0] = force;
 687                         }
 688                         /* Do not delete "::" type targets when interrupted */
 689                         target->stat.is_precious = true;
 690                         /*
 691                          * Build a synthetic target "<number>%target"
 692                          * for "target".
 693                          */
 694                         mb_namep = getmem((int) (strlen(target->string_mb) + 10));
 695                         namep = ALLOC_WC((int) (target->hash.length + 10));


 789                 /* Reading report file from programs that reports */
 790                 /* dependencies. If this is the first time the target is */
 791                 /* read from this reportfile we clear all old */
 792                 /* automatic depes */
 793                 if (target->temp_file_number == temp_file_number) {
 794                         break;
 795                 }
 796                 target->temp_file_number = temp_file_number;
 797                 command_changed = true;
 798                 if (line != NULL) {
 799                         for (dp = line->body.line.dependencies;
 800                              dp != NULL;
 801                              dp = dp->next) {
 802                                 if (dp->automatic) {
 803                                         dp->stale = true;
 804                                 }
 805                         }
 806                 }
 807                 break;
 808         default:
 809                 fatal_reader(gettext("Internal error. Unknown makefile type %d"),
 810                              makefile_type);
 811         }
 812         /* A target may only be involved in one target group */
 813         if (line->body.line.target_group != NULL) {
 814                 if (target_group != NULL) {
 815                         fatal_reader(gettext("Too many target groups for target `%s'"),
 816                                      target->string_mb);
 817                 }
 818         } else {
 819                 line->body.line.target_group = target_group;
 820         }
 821 
 822         if (trace_reader) {
 823                 (void) printf("%s:\t", target->string_mb);
 824         }
 825         /* Enter the dependencies */
 826         register_as_auto = BOOLEAN(makefile_type != reading_makefile);
 827         not_auto_found = false;
 828         for (;
 829              (depes != NULL) && !not_auto_found;
 830              depes = depes->next) {
 831                 for (i = 0; i < depes->used; i++) {
 832                         /* the dependency .NOT_AUTO signals beginning of
 833                          * explicit dependancies which were put at end of
 834                          * list in .make.state file - we stop entering
 835                          * dependencies at this point


1062  */
1063 Dyntarget
1064 enter_dyntarget(register Name target)
1065 {
1066         register Dyntarget      result = ALLOC(Dyntarget);
1067         Dyntarget               p;
1068         Dyntarget               *insert;
1069         int                             i;
1070 
1071         result->next = NULL;
1072         result->name = target;
1073 
1074 
1075         /* Find the end of the dyntarget list and append the new pattern */
1076         for (insert = &dyntarget_list, p = *insert;
1077              p != NULL;
1078              insert = &p->next, p = *insert);
1079         *insert = result;
1080 
1081         if (trace_reader) {
1082                 (void) printf("Dynamic target %s:\n", result->name->string_mb);
1083         }
1084         return( result);
1085 }
1086 
1087 
1088 /*
1089  *      special_reader(target, depes, command)
1090  *
1091  *      Read the pseudo targets make knows about
1092  *      This handles the special targets that should not be entered as regular
1093  *      target/dependency sets.
1094  *
1095  *      Parameters:
1096  *              target          The special target
1097  *              depes           The list of dependencies it was entered with
1098  *              command         The command it was entered with
1099  *
1100  *      Static variables used:
1101  *              built_last_make_run_seen Set to indicate .BUILT_LAST... seen
1102  *


1117  *              only_parallel   Set to indicate only some targets runs parallel
1118  *              parallel_name   The Name ".PARALLEL", used for tracing
1119  *              precious        The Name ".PRECIOUS", used for tracing
1120  *              sccs_get_name   The Name ".SCCS_GET", used for tracing
1121  *              sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
1122  *              get_name        The Name ".GET", used for tracing
1123  *              sccs_get_rule   Set when ".SCCS_GET" target is read
1124  *              silent          Set when ".SILENT" target is read
1125  *              silent_name     The Name ".SILENT", used for tracing
1126  *              trace_reader    Indicates that we should echo stuff we read
1127  */
1128 void
1129 special_reader(Name target, register Name_vector depes, Cmd_line command)
1130 {
1131         register int            n;
1132 
1133         switch (target->special_reader) {
1134 
1135         case svr4_special:
1136                 if (depes->used != 0) {
1137                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1138                                      target->string_mb);
1139                 }
1140                 svr4  = true;
1141                 posix  = false;
1142                 keep_state = false;
1143                 all_parallel = false;
1144                 only_parallel = false;
1145                 if (trace_reader) {
1146                         (void) printf("%s:\n", svr4_name->string_mb);
1147                 }
1148                 break;
1149 
1150         case posix_special:
1151                 if(svr4)
1152                   break;
1153                 if (depes->used != 0) {
1154                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1155                                      target->string_mb);
1156                 }
1157                 posix  = true;
1158                         /* with posix on, use the posix get rule */
1159                 sccs_get_rule = sccs_get_posix_rule;
1160                         /* turn keep state off being SunPro make specific */
1161                 keep_state = false;
1162                 /* Use /usr/xpg4/bin/sh on Solaris */
1163                 MBSTOWCS(wcs_buffer, "/usr/xpg4/bin/sh");
1164                 (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
1165                 if (trace_reader) {
1166                         (void) printf("%s:\n", posix_name->string_mb);
1167                 }
1168                 break;
1169 
1170         case built_last_make_run_special:
1171                 built_last_make_run_seen = true;
1172                 break;
1173 
1174         case default_special:
1175                 if (depes->used != 0) {
1176                         warning(gettext("Illegal dependency list for target `%s'"),
1177                                 target->string_mb);
1178                 }
1179                 default_rule = command;
1180                 if (trace_reader) {
1181                         (void) printf("%s:\n",
1182                                       default_rule_name->string_mb);
1183                         print_rule(command);
1184                 }
1185                 break;
1186 
1187 
1188         case ignore_special:
1189                 if ((depes->used != 0) &&(!posix)){
1190                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1191                                      target->string_mb);
1192                 }
1193                 if (depes->used == 0)
1194                 {
1195                    ignore_errors_all = true;
1196                 }
1197                 if(svr4) {
1198                   ignore_errors_all = true;
1199                   break;
1200                 }
1201                 for (; depes != NULL; depes = depes->next) {
1202                         for (n = 0; n < depes->used; n++) {
1203                                 depes->names[n]->ignore_error_mode = true;
1204                         }
1205                 }
1206                 if (trace_reader) {
1207                         (void) printf("%s:\n", ignore_name->string_mb);
1208                 }
1209                 break;
1210 
1211         case keep_state_special:
1212                 if(svr4)
1213                   break;
1214                         /* ignore keep state, being SunPro make specific */
1215                 if(posix)
1216                   break;
1217                 if (depes->used != 0) {
1218                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1219                                      target->string_mb);
1220                 }
1221                 keep_state = true;
1222                 if (trace_reader) {
1223                         (void) printf("%s:\n",
1224                                       dot_keep_state->string_mb);
1225                 }
1226                 break;
1227 
1228         case keep_state_file_special:
1229                 if(svr4)
1230                   break;
1231                 if(posix)
1232                   break;
1233                         /* it's not necessary to specify KEEP_STATE, if this 
1234                         ** is given, so set the keep_state.
1235                         */
1236                 keep_state = true;
1237                 if (depes->used != 0) {
1238                    if((!make_state) ||(!strcmp(make_state->string_mb,".make.state"))) {
1239                      make_state = depes->names[0];
1240                    }
1241                 }
1242                 break;
1243         case make_version_special:
1244                 if(svr4)
1245                   break;
1246                 if (depes->used != 1) {
1247                         fatal_reader(gettext("Illegal dependency list for target `%s'"),
1248                                      target->string_mb);
1249                 }
1250                 if (depes->names[0] != current_make_version) {
1251                         /*
1252                          * Special case the fact that version 1.0 and 1.1
1253                          * are identical.
1254                          */
1255                         if (!IS_EQUAL(depes->names[0]->string_mb,
1256                                       "VERSION-1.1") ||
1257                             !IS_EQUAL(current_make_version->string_mb,
1258                                       "VERSION-1.0")) {
1259                                 /*
1260                                  * Version mismatches should cause the
1261                                  * .make.state file to be skipped.
1262                                  * This is currently not true - it is read
1263                                  * anyway.
1264                                  */
1265                                 warning(gettext("Version mismatch between current version `%s' and `%s'"),
1266                                         current_make_version->string_mb,
1267                                         depes->names[0]->string_mb);
1268                         }
1269                 }
1270                 break;
1271 
1272         case no_parallel_special:
1273                 if(svr4)
1274                   break;
1275                 /* Set the no_parallel bit for all the targets on */
1276                 /* the dependency list */
1277                 if (depes->used == 0) {
1278                         /* only those explicitly made parallel */
1279                         only_parallel = true;
1280                         all_parallel = false;
1281                 }
1282                 for (; depes != NULL; depes = depes->next) {
1283                         for (n = 0; n < depes->used; n++) {
1284                                 if (trace_reader) {
1285                                         (void) printf("%s:\t%s\n",


1349                 if(svr4) {
1350                   all_precious = true;
1351                   break;
1352                 }
1353                 /* Set the precious bit for all the targets on */
1354                 /* the dependency list */
1355                 for (; depes != NULL; depes = depes->next) {
1356                         for (n = 0; n < depes->used; n++) {
1357                                 if (trace_reader) {
1358                                         (void) printf("%s:\t%s\n",
1359                                                       precious->string_mb,
1360                                                       depes->names[n]->string_mb);
1361                                 }
1362                                 depes->names[n]->stat.is_precious = true;
1363                         }
1364                 }
1365                 break;
1366 
1367         case sccs_get_special:
1368                 if (depes->used != 0) {
1369                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1370                                      target->string_mb);
1371                 }
1372                 sccs_get_rule = command;
1373                 sccs_get_org_rule = command;
1374                 if (trace_reader) {
1375                         (void) printf("%s:\n", sccs_get_name->string_mb);
1376                         print_rule(command);
1377                 }
1378                 break;
1379 
1380         case sccs_get_posix_special:
1381                 if (depes->used != 0) {
1382                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1383                                      target->string_mb);
1384                 }
1385                 sccs_get_posix_rule = command;
1386                 if (trace_reader) {
1387                         (void) printf("%s:\n", sccs_get_posix_name->string_mb);
1388                         print_rule(command);
1389                 }
1390                 break;
1391 
1392         case get_posix_special:
1393                 if (depes->used != 0) {
1394                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1395                                      target->string_mb);
1396                 }
1397                 get_posix_rule = command;
1398                 if (trace_reader) {
1399                         (void) printf("%s:\n", get_posix_name->string_mb);
1400                         print_rule(command);
1401                 }
1402                 break;
1403 
1404         case get_special:
1405                 if(!svr4) {
1406                   break;
1407                 }
1408                 if (depes->used != 0) {
1409                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1410                                      target->string_mb);
1411                 }
1412                 get_rule = command;
1413                 sccs_get_rule = command;
1414                 if (trace_reader) {
1415                         (void) printf("%s:\n", get_name->string_mb);
1416                         print_rule(command);
1417                 }
1418                 break;
1419 
1420         case silent_special:
1421                 if ((depes->used != 0) && (!posix)){
1422                         fatal_reader(gettext("Illegal dependencies for target `%s'"),
1423                                      target->string_mb);
1424                 }
1425                 if (depes->used == 0)
1426                 {
1427                    silent_all = true;
1428                 }
1429                 if(svr4) {
1430                   silent_all = true;
1431                   break;
1432                 }
1433                 for (; depes != NULL; depes = depes->next) {
1434                         for (n = 0; n < depes->used; n++) {
1435                                 depes->names[n]->silent_mode = true;
1436                         }
1437                 }
1438                 if (trace_reader) {
1439                         (void) printf("%s:\n", silent_name->string_mb);
1440                 }
1441                 break;
1442 
1443         case suffixes_special:
1444                 read_suffixes_list(depes);
1445                 break;
1446 
1447         default:
1448 
1449                 fatal_reader(gettext("Internal error: Unknown special reader"));
1450         }
1451 }
1452 
1453 /*
1454  *      read_suffixes_list(depes)
1455  *
1456  *      Read the special list .SUFFIXES. If it is empty the old list is
1457  *      cleared. Else the new one is appended. Suffixes with ~ are extracted
1458  *      and marked.
1459  *
1460  *      Parameters:
1461  *              depes           The list of suffixes
1462  *
1463  *      Global variables used:
1464  *              hashtab         The central hashtable for Names.
1465  *              suffixes        The list of suffixes, set or appended to
1466  *              suffixes_name   The Name ".SUFFIXES", used for tracing
1467  *              trace_reader    Indicates that we should echo stuff we read
1468  */
1469 static void


1737  *              trace_reader    Indicates that we should echo stuff we read
1738  */
1739 void
1740 enter_equal(Name name, Name value, register Boolean append)
1741 {
1742         wchar_t         *string;
1743         Name            temp;
1744 
1745         if (name->colon) {
1746                 sh_transform(&name, &value);
1747         }
1748         (void) SETVAR(name, value, append);
1749 
1750         /* if we're setting FC, we want to set F77 to the same value. */
1751         Wstring nms(name);
1752         wchar_t * wcb = nms.get_string();
1753         string = wcb;
1754         if (string[0]=='F' &&
1755             string[1]=='C' &&
1756             string[2]=='\0') {
1757                 MBSTOWCS(wcs_buffer, "F77");
1758                 temp = GETNAME(wcs_buffer, FIND_LENGTH);
1759                 (void) SETVAR(temp, value, append);
1760 /*
1761                 fprintf(stderr, gettext("warning: FC is obsolete, use F77 instead\n"));
1762  */
1763         }
1764 
1765         if (trace_reader) {
1766                 if (value == NULL) {
1767                         (void) printf("%s %c=\n",
1768                                       name->string_mb,
1769                                       append ?
1770                                       (int) plus_char : (int) space_char);
1771                 } else {
1772                         (void) printf("%s %c= %s\n",
1773                                       name->string_mb,
1774                                       append ?
1775                                       (int) plus_char : (int) space_char,
1776                                       value->string_mb);
1777                 }
1778         }
1779 }
1780 
1781 /*


1783  *
1784  *      Parameters:
1785  *              name    The name of the macro we might transform
1786  *              value   The value to transform
1787  *
1788  */
1789 static void
1790 sh_transform(Name *name, Name *value)
1791 {
1792         /* Check if we need :sh transform */
1793         wchar_t         *colon;
1794         String_rec      command;
1795         String_rec      destination;
1796         wchar_t         buffer[1000];
1797         wchar_t         buffer1[1000];
1798 
1799         static wchar_t  colon_sh[4];
1800         static wchar_t  colon_shell[7];
1801 
1802         if (colon_sh[0] == (int) nul_char) {
1803                 MBSTOWCS(colon_sh, ":sh");
1804                 MBSTOWCS(colon_shell, ":shell");
1805         }
1806         Wstring nms((*name));
1807         wchar_t * wcb = nms.get_string();
1808 
1809         colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
1810         if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1811                 INIT_STRING_FROM_STACK(destination, buffer);
1812 
1813                 if(*value == NULL) {
1814                         buffer[0] = 0;
1815                 } else {
1816                         Wstring wcb1((*value));
1817                         if (IS_WEQUAL(colon, colon_shell)) {
1818                                 INIT_STRING_FROM_STACK(command, buffer1);
1819                                 expand_value(*value, &command, false);
1820                         } else {
1821                                 command.text.p = wcb1.get_string() + (*value)->hash.length;
1822                                 command.text.end = command.text.p;
1823                                 command.buffer.start = wcb1.get_string();
1824                                 command.buffer.end = command.text.p;


1841  *              args            arguments to match the format
1842  *
1843  *      Global variables used:
1844  *              file_being_read Name of the makefile being read
1845  *              line_number     Line that is being read
1846  *              report_pwd      Indicates whether current path should be shown
1847  *              temp_file_name  When reading tempfile we report that name
1848  */
1849 /*VARARGS*/
1850 void
1851 fatal_reader(char * pattern, ...)
1852 {
1853         va_list args;
1854         char    message[1000];
1855 
1856         va_start(args, pattern);
1857         if (file_being_read != NULL) {
1858                 WCSTOMBS(mbs_buffer, file_being_read);
1859                 if (line_number != 0) {
1860                         (void) sprintf(message,
1861                                        gettext("%s, line %d: %s"),
1862                                        mbs_buffer,
1863                                        line_number,
1864                                        pattern);
1865                 } else {
1866                         (void) sprintf(message,
1867                                        "%s: %s",
1868                                        mbs_buffer,
1869                                        pattern);
1870                 }
1871                 pattern = message;
1872         }
1873 
1874         (void) fflush(stdout);
1875         (void) fprintf(stderr, gettext("make: Fatal error in reader: "));
1876         (void) vfprintf(stderr, pattern, args);
1877         (void) fprintf(stderr, "\n");
1878         va_end(args);
1879 
1880         if (temp_file_name != NULL) {
1881                 (void) fprintf(stderr,
1882                                gettext("make: Temp-file %s not removed\n"),
1883                                temp_file_name->string_mb);
1884                 temp_file_name = NULL;
1885         }
1886 
1887         if (report_pwd) {
1888                 (void) fprintf(stderr,
1889                                gettext("Current working directory %s\n"),
1890                                get_current_path());
1891         }
1892         (void) fflush(stderr);
1893         exit_status = 1;
1894         exit(1);
1895 }
1896