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


  24  */
  25 
  26 /*
  27  *      read.c
  28  *
  29  *      This file contains the makefile reader.
  30  */
  31 
  32 /*
  33  * Included files
  34  */
  35 #include <alloca.h>               /* alloca() */
  36 #include <errno.h>                /* errno */
  37 #include <fcntl.h>                /* fcntl() */
  38 #include <mk/defs.h>
  39 #include <mksh/macro.h>           /* expand_value(), expand_macro() */
  40 #include <mksh/misc.h>            /* getmem() */
  41 #include <mksh/read.h>            /* get_next_block_fn() */
  42 #include <sys/uio.h>              /* read() */
  43 #include <unistd.h>               /* read(), unlink() */

  44 
  45 
  46 /*
  47  * typedefs & structs
  48  */
  49 
  50 /*
  51  * Static variables
  52  */
  53 
  54 static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
  55 
  56 /*
  57  * File table of contents
  58  */
  59 static  void            parse_makefile(register Name true_makefile_name, register Source source);
  60 static  Source          push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source);
  61 extern  void            enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
  62 extern  Name            normalize_name(register wchar_t *name_string, register int length);
  63 


 100         register int            n;
 101         char                    *path;
 102         register Source         source = ALLOC(Source);
 103         Property                orig_makefile = makefile;
 104         Dependency              *dpp;
 105         Dependency              dp;
 106         register int            length;
 107         wchar_t                 *previous_file_being_read = file_being_read;
 108         int                     previous_line_number = line_number;
 109         wchar_t                 previous_current_makefile[MAXPATHLEN];
 110         Makefile_type           save_makefile_type;
 111         Name                    normalized_makefile_name;
 112         register wchar_t        *string_start;
 113         register wchar_t        *string_end;
 114 
 115 
 116 
 117         wchar_t * wcb = get_wstring(makefile_name->string_mb);
 118 
 119         if (max_include_depth++ >= 40) {
 120                 fatal(catgets(catd, 1, 66, "Too many nested include statements"));
 121         }
 122         if (makefile->body.makefile.contents != NULL) {
 123                 retmem(makefile->body.makefile.contents);
 124         }
 125         source->inp_buf =
 126           source->inp_buf_ptr =
 127             source->inp_buf_end = NULL;
 128         source->error_converting = false;
 129         makefile->body.makefile.contents = NULL;
 130         makefile->body.makefile.size = 0;
 131         if ((makefile_name->hash.length != 1) ||
 132             (wcb[0] != (int) hyphen_char)) {
 133                 if ((makefile->body.makefile.contents == NULL) &&
 134                     (doname_it)) {
 135                         if (makefile_path == NULL) {
 136                                 char *pfx = make_install_prefix();
 137                                 char *path;
 138 
 139                                 add_dir_to_path(".",
 140                                                 &makefile_path,
 141                                                 -1);
 142 
 143                                 // As regularly installed
 144                                 asprintf(&path, "%s/../share/lib/make", pfx);
 145                                 add_dir_to_path(path, &makefile_path, -1);
 146                                 free(path);
 147 
 148                                 // Tools build
 149                                 asprintf(&path, "%s/../../share/", pfx);
 150                                 add_dir_to_path(path, &makefile_path, -1);
 151                                 free(path);
 152                                     
 153                                 add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
 154                                                 &makefile_path,
 155                                                 -1);
 156                                 add_dir_to_path(NOCATGETS("/etc/default"),
 157                                                 &makefile_path,
 158                                                 -1);
 159 
 160                                 free(pfx);
 161                         }
 162                         save_makefile_type = makefile_type;
 163                         makefile_type = reading_nothing;
 164                         if (doname(makefile_name, true, false) == build_dont_know) {
 165                                 /* Try normalized filename */
 166                                 string_start=get_wstring(makefile_name->string_mb);
 167                                 for (string_end=string_start+1; *string_end != L'\0'; string_end++);
 168                                 normalized_makefile_name=normalize_name(string_start, string_end - string_start);
 169                                 if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) || 
 170                                         (doname(normalized_makefile_name, true, false) == build_dont_know)) {
 171                                         n = access_vroot(makefile_name->string_mb,
 172                                                  4,
 173                                                  chase_path ?
 174                                                  makefile_path : NULL,
 175                                                  VROOT_DEFAULT);
 176                                         if (n == 0) {


 187                                         }
 188                                 }
 189                                 retmem(string_start);
 190                                 /* 
 191                                  * Commented out: retmem_mb(normalized_makefile_name->string_mb);
 192                                  * We have to return this memory, but it seems to trigger a bug
 193                                  * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
 194                                  * is compiled using Sun C++ 5.6).
 195                                  */
 196                                 // retmem_mb(normalized_makefile_name->string_mb); 
 197                         }
 198                         makefile_type = save_makefile_type;
 199                 }
 200                 source->string.free_after_use = false;
 201                 source->previous = NULL;
 202                 source->already_expanded = false;
 203                 /* Lock the file for read, but not when -n. */
 204                 if (lock_makefile && 
 205                     !do_not_exec_rule) {
 206 
 207                          make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
 208                          (void) sprintf(make_state_lockfile,
 209                                                 NOCATGETS("%s.lock"),
 210                                                 make_state->string_mb);
 211                         (void) file_lock(make_state->string_mb,
 212                                          make_state_lockfile,
 213                                          (int *) &make_state_locked,
 214                                          0);
 215                         if(!make_state_locked) {
 216                                 printf(NOCATGETS("-- NO LOCKING for read\n"));
 217                                 retmem_mb(make_state_lockfile);
 218                                 make_state_lockfile = 0;
 219                                 return failed;
 220                         }
 221                 }
 222                 if (makefile->body.makefile.contents == NULL) {
 223                         save_makefile_type = makefile_type;
 224                         makefile_type = reading_nothing;
 225                         if ((doname_it) &&
 226                             (doname(makefile_name, true, false) == build_failed)) {
 227                                 if (complain) {
 228                                         (void) fprintf(stderr,
 229                                                        catgets(catd, 1, 237, "make: Couldn't make `%s'\n"),
 230                                                        makefile_name->string_mb);
 231                                 }
 232                                 max_include_depth--;
 233                                 makefile_type = save_makefile_type;
 234                                 return failed;
 235                         }
 236                         makefile_type = save_makefile_type;
 237                         //
 238                         // Before calling exists() make sure that we have the right timestamp
 239                         //
 240                         makefile_name->stat.time = file_no_time;
 241 
 242                         if (exists(makefile_name) == file_doesnt_exist) {
 243                                 if (complain ||
 244                                     (makefile_name->stat.stat_errno != ENOENT)) {
 245                                         if (must_exist) {
 246                                                 fatal(catgets(catd, 1, 68, "Can't find `%s': %s"),
 247                                                       makefile_name->string_mb,
 248                                                       errmsg(makefile_name->
 249                                                              stat.stat_errno));
 250                                         } else {
 251                                                 warning(catgets(catd, 1, 69, "Can't find `%s': %s"),
 252                                                         makefile_name->string_mb,
 253                                                         errmsg(makefile_name->
 254                                                                stat.stat_errno));
 255                                         }
 256                                 }
 257                                 max_include_depth--;
 258                                 if(make_state_locked && (make_state_lockfile != NULL)) {
 259                                         (void) unlink(make_state_lockfile);
 260                                         retmem_mb(make_state_lockfile);
 261                                         make_state_lockfile = NULL;
 262                                         make_state_locked = false;
 263                                 }
 264                                 retmem(wcb);
 265                                 retmem_mb((char *)source);
 266                                 return failed;
 267                         }
 268                         /*
 269                          * These values are the size and bytes of
 270                          * the MULTI-BYTE makefile.
 271                          */


 276                         if (report_file) {
 277                                 for (dpp = &makefiles_used;
 278                                      *dpp != NULL;
 279                                      dpp = &(*dpp)->next);
 280                                 dp = ALLOC(Dependency);
 281                                 dp->next = NULL;
 282                                 dp->name = makefile_name;
 283                                 dp->automatic = false;
 284                                 dp->stale = false;
 285                                 dp->built = false;
 286                                 *dpp = dp;
 287                         }
 288                         source->fd = open_vroot(makefile_name->string_mb,
 289                                                 O_RDONLY,
 290                                                 0,
 291                                                 NULL,
 292                                                 VROOT_DEFAULT);
 293                         if (source->fd < 0) {
 294                                 if (complain || (errno != ENOENT)) {
 295                                         if (must_exist) {
 296                                                 fatal(catgets(catd, 1, 70, "Can't open `%s': %s"),
 297                                                       makefile_name->string_mb,
 298                                                       errmsg(errno));
 299                                         } else {
 300                                                 warning(catgets(catd, 1, 71, "Can't open `%s': %s"),
 301                                                         makefile_name->string_mb,
 302                                                         errmsg(errno));
 303                                         }
 304                                 }
 305                                 max_include_depth--;
 306                                 return failed;
 307                         }
 308                         (void) fcntl(source->fd, F_SETFD, 1);
 309                         orig_makefile->body.makefile.contents =
 310                           makefile->body.makefile.contents =
 311                             source->string.text.p =
 312                               source->string.buffer.start =
 313                                 ALLOC_WC((int) (makefile_name->stat.size + 2));
 314                         if (makefile_type == reading_cpp_file) {
 315                                 forget_after_parse = true;
 316                         }
 317                         source->string.text.end = source->string.text.p;
 318                         source->string.buffer.end =
 319                           source->string.text.p + makefile_name->stat.size;
 320                 } else {


 322                         source->fd = -1;
 323                         source->string.text.p =
 324                           source->string.buffer.start =
 325                             makefile->body.makefile.contents;
 326                         source->string.text.end =
 327                           source->string.buffer.end =
 328                             source->string.text.p + makefile->body.makefile.size;
 329                         source->bytes_left_in_file =
 330                           makefile->body.makefile.size;
 331                 }
 332                 file_being_read = wcb;
 333         } else {
 334                 char            *stdin_text_p;
 335                 char            *stdin_text_end;
 336                 char            *stdin_buffer_start;
 337                 char            *stdin_buffer_end;
 338                 char            *p_mb;
 339                 int             num_mb_chars;
 340                 size_t          num_wc_chars;
 341 
 342                 MBSTOWCS(wcs_buffer, NOCATGETS("Standard in"));
 343                 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
 344                 /*
 345                  * Memory to read standard in, then convert it
 346                  * to wide char strings.
 347                  */
 348                 stdin_buffer_start =
 349                   stdin_text_p = getmem(length = 1024);
 350                 stdin_buffer_end = stdin_text_p + length;
 351                 MBSTOWCS(wcs_buffer, NOCATGETS("standard input"));
 352                 file_being_read = (wchar_t *) wsdup(wcs_buffer);
 353                 line_number = 0;
 354                 while ((n = read(fileno(stdin),
 355                                  stdin_text_p,
 356                                  length)) > 0) {
 357                         length -= n;
 358                         stdin_text_p += n;
 359                         if (length == 0) {
 360                                 p_mb = getmem(length = 1024 +
 361                                               (stdin_buffer_end -
 362                                                stdin_buffer_start));
 363                                 (void) strncpy(p_mb,
 364                                                stdin_buffer_start,
 365                                                (stdin_buffer_end -
 366                                                 stdin_buffer_start));
 367                                 retmem_mb(stdin_buffer_start);
 368                                 stdin_text_p = p_mb +
 369                                   (stdin_buffer_end - stdin_buffer_start);
 370                                 stdin_buffer_start = p_mb;
 371                                 stdin_buffer_end =
 372                                   stdin_buffer_start + length;
 373                                 length = 1024;
 374                         }
 375                 }
 376                 if (n < 0) {
 377                         fatal(catgets(catd, 1, 72, "Error reading standard input: %s"),
 378                               errmsg(errno));
 379                 }
 380                 stdin_text_p = stdin_buffer_start;
 381                 stdin_text_end = stdin_buffer_end - length;
 382                 num_mb_chars = stdin_text_end - stdin_text_p;
 383 
 384                 /*
 385                  * Now, convert the sequence of multibyte chars into
 386                  * a sequence of corresponding wide character codes.
 387                  */
 388                 source->string.free_after_use = false;
 389                 source->previous = NULL;
 390                 source->bytes_left_in_file = 0;
 391                 source->fd = -1;
 392                 source->already_expanded = false;
 393                 source->string.buffer.start =
 394                   source->string.text.p = ALLOC_WC(num_mb_chars + 1);
 395                 source->string.buffer.end =
 396                     source->string.text.p + num_mb_chars;
 397                 num_wc_chars = mbstowcs(source->string.text.p,
 398                                         stdin_text_p,
 399                                         num_mb_chars);
 400                 if ((int) num_wc_chars >= 0) {
 401                         source->string.text.end =
 402                           source->string.text.p + num_wc_chars;
 403                 }
 404                 (void) retmem_mb(stdin_text_p);
 405         }
 406         line_number = 1;
 407         if (trace_reader) {
 408                 (void) printf(catgets(catd, 1, 73, ">>>>>>>>>>>>>>>> Reading makefile %s\n"),
 409                               makefile_name->string_mb);
 410         }
 411         parse_makefile(makefile_name, source);
 412         if (trace_reader) {
 413                 (void) printf(catgets(catd, 1, 74, ">>>>>>>>>>>>>>>> End of makefile %s\n"),
 414                               makefile_name->string_mb);
 415         }
 416         if(file_being_read) {
 417                 retmem(file_being_read);
 418         }
 419         file_being_read = previous_file_being_read;
 420         line_number = previous_line_number;
 421         makefile_type = reading_nothing;
 422         max_include_depth--;
 423         if (make_state_locked) {
 424                 /* Unlock .make.state. */
 425                 unlink(make_state_lockfile);
 426                 make_state_locked = false;
 427                 retmem_mb(make_state_lockfile);
 428         }
 429         if (forget_after_parse) {
 430                 retmem(makefile->body.makefile.contents);
 431                 makefile->body.makefile.contents = NULL;
 432         }
 433         retmem_mb((char *)source);


 712                                 /* And push the value */
 713                                 extrap->previous = source;
 714                                 source = extrap;
 715                                 CACHE_SOURCE(0);
 716                                 goto line_evald;
 717                         }
 718                 }
 719         default:
 720                 goto line_evald;
 721         }
 722 
 723         /* We now have a line we can start reading */
 724  line_evald:
 725         if (source == NULL) {
 726                 GOTO_STATE(exit_state);
 727         }
 728         /* Check if this is an include command */
 729         if ((makefile_type == reading_makefile) &&
 730             !source->already_expanded) {
 731             if (include_space[0] == (int) nul_char) {
 732                 MBSTOWCS(include_space, NOCATGETS("include "));
 733                 MBSTOWCS(include_tab, NOCATGETS("include\t"));
 734             }
 735             if ((IS_WEQUALN(source_p, include_space, 8)) ||
 736                 (IS_WEQUALN(source_p, include_tab, 8))) {
 737                 source_p += 7;
 738                 if (iswspace(*source_p)) {
 739                         Makefile_type save_makefile_type;
 740                         wchar_t         *name_start;
 741                         int             name_length;
 742 
 743                         /*
 744                          * Yes, this is an include.
 745                          * Skip spaces to get to the filename.
 746                          */
 747                         while (iswspace(*source_p) ||
 748                                (*source_p == (int) nul_char)) {
 749                                 switch (GET_CHAR()) {
 750                                 case nul_char:
 751                                         GET_NEXT_BLOCK(source);
 752                                         if (source == NULL) {
 753                                                 GOTO_STATE(on_eoln_state);


 856                                      p++);
 857                                 for (q = p;
 858                                      (*q != (int) nul_char) && !iswspace(*q);
 859                                      q++);
 860                                 makefile_name = GETNAME(p, q-p);
 861                                 if (destination.free_after_use) {
 862                                         retmem(destination.buffer.start);
 863                                 }
 864                         }
 865                         source_p++;
 866                         UNCACHE_SOURCE();
 867                         /* Read the file */
 868                         save_makefile_type = makefile_type;
 869                         if (read_simple_file(makefile_name,
 870                                              true,
 871                                              true,
 872                                              true,
 873                                              false,
 874                                              true,
 875                                              false) == failed) {
 876                                 fatal_reader(catgets(catd, 1, 75, "Read of include file `%s' failed"),
 877                                              makefile_name->string_mb);
 878                         }
 879                         makefile_type = save_makefile_type;
 880                         do_not_exec_rule = save_do_not_exec_rule;
 881                         CACHE_SOURCE(0);
 882                         goto start_new_line;
 883                 } else {
 884                         source_p -= 7;
 885                 }
 886             } else {
 887                 /* Check if the word include was split across 8K boundary. */
 888                 
 889                 tmp_bytes_left_in_string = source->string.text.end - source_p;
 890                 if (tmp_bytes_left_in_string < 8) {
 891                         tmp_maybe_include = false;
 892                         if (IS_WEQUALN(source_p,
 893                                        include_space,
 894                                        tmp_bytes_left_in_string)) {
 895                                 tmp_maybe_include = true;
 896                         }


1042                         if (source_p != string_start) {
1043                                 if (!macro_seen_in_string) {
1044                                         INIT_STRING_FROM_STACK(name_string,
1045                                                                name_buffer);
1046                                 }
1047                                 append_string(string_start,
1048                                               &name_string,
1049                                               source_p - string_start);
1050                                 macro_seen_in_string = true;
1051                         }
1052                         /* Get more text to read */
1053                         GET_NEXT_BLOCK(source);
1054                         string_start = source_p;
1055                         source_p--;
1056                         if (source == NULL) {
1057                                 GOTO_STATE(on_eoln_state);
1058                         }
1059                         break;
1060                 case newline_char:
1061                         if (paren_count > 0) {
1062                                 fatal_reader(catgets(catd, 1, 76, "Unmatched `(' on line"));
1063                         }
1064                         if (brace_count > 0) {
1065                                 fatal_reader(catgets(catd, 1, 77, "Unmatched `{' on line"));
1066                         }
1067                         source_p++;
1068                         /* Enter name */
1069                         current_names = enter_name(&name_string,
1070                                                    macro_seen_in_string,
1071                                                    string_start,
1072                                                    source_p - 1,
1073                                                    current_names,
1074                                                    &extra_names,
1075                                                    &target_group_seen);
1076                         first_target = false;
1077                         if (extra_names == NULL) {
1078                                 extra_names = (Name_vector)
1079                                   alloca((int) sizeof (Name_vector_rec));
1080                         }
1081                         /* Do postprocessing or return error */
1082                         if (source->fd >= 0) {
1083                                 line_number++;
1084                         }
1085                         GOTO_STATE(on_eoln_state);


1098                                 if (source == NULL) {
1099                                         GOTO_STATE(on_eoln_state);
1100                                 }
1101                         }
1102                         if (*source_p == (int) newline_char) {
1103                                 if (source->fd >= 0) {
1104                                         line_number++;
1105                                 }
1106                                 *source_p = (int) space_char;
1107                                 string_start = source_p;
1108                                 goto resume_name_scan;
1109                         } else {
1110                                 string_start = source_p;
1111                                 break;
1112                         }
1113                         break;
1114                 case numbersign_char:
1115                         if (paren_count + brace_count > 0) {
1116                                 break;
1117                         }
1118                         fatal_reader(catgets(catd, 1, 78, "Unexpected comment seen"));
1119                 case dollar_char:
1120                         if (source->already_expanded) {
1121                                 break;
1122                         }
1123                         /* Save the identifier so far */
1124                         if (source_p != string_start) {
1125                                 if (!macro_seen_in_string) {
1126                                         INIT_STRING_FROM_STACK(name_string,
1127                                                                name_buffer);
1128                                 }
1129                                 append_string(string_start,
1130                                               &name_string,
1131                                               source_p - string_start);
1132                                 macro_seen_in_string = true;
1133                         }
1134                         /* Eval and push the macro */
1135                         source_p++;
1136                         UNCACHE_SOURCE();
1137                         {
1138                                 Source t =
1139                                   (Source) alloca((int) sizeof (Source_rec));
1140                                 source = push_macro_value(t,
1141                                                           buffer,
1142                                                           sizeof buffer,
1143                                                           source);
1144                         }
1145                         CACHE_SOURCE(1);
1146                         string_start = source_p + 1;
1147                         break;
1148                 case parenleft_char:
1149                         paren_count++;
1150                         break;
1151                 case parenright_char:
1152                         if (--paren_count < 0) {
1153                                 fatal_reader(catgets(catd, 1, 79, "Unmatched `)' on line"));
1154                         }
1155                         break;
1156                 case braceleft_char:
1157                         brace_count++;
1158                         break;
1159                 case braceright_char:
1160                         if (--brace_count < 0) {
1161                                 fatal_reader(catgets(catd, 1, 80, "Unmatched `}' on line"));
1162                         }
1163                         break;
1164                 case ampersand_char:
1165                 case greater_char:
1166                 case bar_char:
1167                         if (paren_count + brace_count == 0) {
1168                                 source_p++;
1169                         }
1170                         /* Fall into */
1171                 case tab_char:
1172                 case space_char:
1173                         if (paren_count + brace_count > 0) {
1174                                 break;
1175                         }
1176                         current_names = enter_name(&name_string,
1177                                                    macro_seen_in_string,
1178                                                    string_start,
1179                                                    source_p,
1180                                                    current_names,
1181                                                    &extra_names,


1186                                   alloca((int) sizeof (Name_vector_rec));
1187                         }
1188                         goto enter_state;
1189                 case colon_char:
1190                         if (paren_count + brace_count > 0) {
1191                                 break;
1192                         }
1193                         if (separator == conditional_seen) {
1194                                 break;
1195                         }
1196 /** POSIX **/
1197 #if 0
1198                         if(posix) {
1199                           emptycount = 0;
1200                         }
1201 #endif
1202 /** END POSIX **/
1203                         /* End of the target list. We now start reading */
1204                         /* dependencies or a conditional assignment */
1205                         if (separator != none_seen) {
1206                                 fatal_reader(catgets(catd, 1, 81, "Extra `:', `::', or `:=' on dependency line"));
1207                         }
1208                         /* Enter the last target */
1209                         if ((string_start != source_p) ||
1210                             macro_seen_in_string) {
1211                                 current_names =
1212                                   enter_name(&name_string,
1213                                              macro_seen_in_string,
1214                                              string_start,
1215                                              source_p,
1216                                              current_names,
1217                                              &extra_names,
1218                                              &target_group_seen);
1219                                 first_target = false;
1220                                 if (extra_names == NULL) {
1221                                         extra_names = (Name_vector)
1222                                           alloca((int)
1223                                                  sizeof (Name_vector_rec));
1224                                 }
1225                         }
1226                         /* Check if it is ":" "::" or ":=" */
1227                 scan_colon_label:
1228                         switch (*++source_p) {
1229                         case nul_char:
1230                                 GET_NEXT_BLOCK(source);
1231                                 source_p--;
1232                                 if (source == NULL) {
1233                                         GOTO_STATE(enter_dependencies_state);
1234                                 }
1235                                 goto scan_colon_label;
1236                         case equal_char:
1237                                 if(svr4) {
1238                                   fatal_reader(catgets(catd, 1, 82, "syntax error"));
1239                                 }
1240                                 separator = conditional_seen;
1241                                 source_p++;
1242                                 current_names = &depes;
1243                                 GOTO_STATE(scan_name_state);
1244                         case colon_char:
1245                                 separator = two_colon;
1246                                 source_p++;
1247                                 break;
1248                         default:
1249                                 separator = one_colon;
1250                         }
1251                         current_names = &depes;
1252                         on_eoln_state = enter_dependencies_state;
1253                         GOTO_STATE(scan_name_state);
1254                 case semicolon_char:
1255                         if (paren_count + brace_count > 0) {
1256                                 break;
1257                         }
1258                         /* End of reading names. Start reading the rule */
1259                         if ((separator != one_colon) &&
1260                             (separator != two_colon)) {
1261                                 fatal_reader(catgets(catd, 1, 83, "Unexpected command seen"));
1262                         }
1263                         /* Enter the last dependency */
1264                         if ((string_start != source_p) ||
1265                             macro_seen_in_string) {
1266                                 current_names =
1267                                   enter_name(&name_string,
1268                                              macro_seen_in_string,
1269                                              string_start,
1270                                              source_p,
1271                                              current_names,
1272                                              &extra_names,
1273                                              &target_group_seen);
1274                                 first_target = false;
1275                                 if (extra_names == NULL) {
1276                                         extra_names = (Name_vector)
1277                                           alloca((int)
1278                                                  sizeof (Name_vector_rec));
1279                                 }
1280                         }
1281                         source_p++;


1368                         switch (*++source_p) {
1369                         case nul_char:
1370                                 if (!macro_seen_in_string) {
1371                                         INIT_STRING_FROM_STACK(name_string,
1372                                                                name_buffer);
1373                                 }
1374                                 append_string(string_start,
1375                                               &name_string,
1376                                               source_p - string_start);
1377                                 GET_NEXT_BLOCK(source);
1378                                 source_p--;
1379                                 string_start = source_p;
1380                                 if (source == NULL) {
1381                                         GOTO_STATE(illegal_eoln_state);
1382                                 }
1383                                 goto scan_append;
1384                         case equal_char:
1385                                 if(!svr4) {
1386                                   append = true;
1387                                 } else {
1388                                   fatal_reader(catgets(catd, 1, 84, "Must be a separator on rules"));
1389                                 }
1390                                 break;
1391                         default:
1392                                 /* The "+" just starts a regular name. */
1393                                 /* Start reading that name */
1394                                 goto resume_name_scan;
1395                         }
1396                         /* Fall into */
1397                 case equal_char:
1398                         if (paren_count + brace_count > 0) {
1399                                 break;
1400                         }
1401                         /* We found macro assignment. */
1402                         /* Check if it is legal and if it is appending */
1403                         switch (separator) {
1404                         case none_seen:
1405                                 separator = equal_seen;
1406                                 on_eoln_state = enter_equal_state;
1407                                 break;
1408                         case conditional_seen:
1409                                 on_eoln_state = enter_conditional_state;
1410                                 break;
1411                         default:
1412                                 /* Reader must special check for "MACRO:sh=" */
1413                                 /* notation */
1414                                 if (sh_name == NULL) {
1415                                         MBSTOWCS(wcs_buffer, NOCATGETS("sh"));
1416                                         sh_name = GETNAME(wcs_buffer, FIND_LENGTH);
1417                                         MBSTOWCS(wcs_buffer, NOCATGETS("shell"));
1418                                         shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
1419                                 }
1420 
1421                                 if (!macro_seen_in_string) {
1422                                         INIT_STRING_FROM_STACK(name_string,
1423                                                        name_buffer);
1424                                 }
1425                                 append_string(string_start,
1426                                               &name_string,
1427                                               source_p - string_start
1428                                 );
1429 
1430                                 if ( (((target.used == 1) &&
1431                                      (depes.used == 1) &&
1432                                      (depes.names[0] == sh_name)) ||
1433                                     ((target.used == 1) &&
1434                                      (depes.used == 0) &&
1435                                      (separator == one_colon) &&
1436                                      (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) &&
1437                                     (!svr4)) {


1466                                         wchar_t         buffer[100];
1467 
1468                                         INIT_STRING_FROM_STACK(macro_name,
1469                                                                buffer);
1470                                         APPEND_NAME(target.names[0],
1471                                                       &macro_name,
1472                                                       FIND_LENGTH);
1473                                         append_char((int) colon_char,
1474                                                     &macro_name);
1475                                         APPEND_NAME(shell_name,
1476                                                       &macro_name,
1477                                                       FIND_LENGTH);
1478                                         target.names[0] =
1479                                           GETNAME(macro_name.buffer.start,
1480                                                   FIND_LENGTH);
1481                                         separator = equal_seen;
1482                                         on_eoln_state = enter_equal_state;
1483                                         break;
1484                                 } 
1485                                 if(svr4) {
1486                                   fatal_reader(catgets(catd, 1, 85, "syntax error"));
1487                                 }
1488                                 else {
1489                                   fatal_reader(catgets(catd, 1, 86, "Macro assignment on dependency line"));
1490                                 }
1491                         }
1492                         if (append) {
1493                                 source_p--;
1494                         }
1495                         /* Enter the macro name */
1496                         if ((string_start != source_p) ||
1497                             macro_seen_in_string) {
1498                                 current_names =
1499                                   enter_name(&name_string,
1500                                              macro_seen_in_string,
1501                                              string_start,
1502                                              source_p,
1503                                              current_names,
1504                                              &extra_names,
1505                                              &target_group_seen);
1506                                 first_target = false;
1507                                 if (extra_names == NULL) {
1508                                         extra_names = (Name_vector)
1509                                           alloca((int)


1968  *      enter conditional state
1969  */
1970 case enter_conditional_state:
1971         if (depes.used != 1) {
1972                 GOTO_STATE(poorly_formed_macro_state);
1973         }
1974         for (nvp = &target; nvp != NULL; nvp = nvp->next) {
1975                 for (i = 0; i < nvp->used; i++) {
1976                         enter_conditional(nvp->names[i],
1977                                           depes.names[0],
1978                                           macro_value,
1979                                           append);
1980                 }
1981         }
1982         goto start_new_line;
1983 
1984 /****************************************************************
1985  *      Error states
1986  */
1987 case illegal_bytes_state:
1988         fatal_reader(catgets(catd, 1, 340, "Invalid byte sequence"));
1989 case illegal_eoln_state:
1990         if (line_number > 1) {
1991                 if (line_started_with_space == (line_number - 1)) {
1992                         line_number--;
1993                         fatal_reader(catgets(catd, 1, 90, "Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)"));
1994                 }
1995         }
1996         fatal_reader(catgets(catd, 1, 87, "Unexpected end of line seen"));
1997 case poorly_formed_macro_state:
1998         fatal_reader(catgets(catd, 1, 88, "Badly formed macro assignment"));
1999 case exit_state:
2000         return;
2001 default:
2002         fatal_reader(catgets(catd, 1, 89, "Internal error. Unknown reader state"));
2003 }
2004 }
2005 
2006 /*
2007  *      push_macro_value(bp, buffer, size, source)
2008  *
2009  *      Macro and function that evaluates one macro
2010  *      and makes the reader read from the value of it
2011  *
2012  *      Return value:
2013  *                              The source block to read the macro from
2014  *
2015  *      Parameters:
2016  *              bp              The new source block to fill in
2017  *              buffer          Buffer to read from
2018  *              size            size of the buffer
2019  *              source          The old source block
2020  *
2021  *      Global variables used:
2022  */


2070  *      is called to setup the dependencies and the commands for it.
2071  *      If the target is a % pattern or part of a target group, then 
2072  *      the appropriate routines are called.
2073  */
2074         
2075 void
2076 enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
2077 {
2078         int                     i;
2079         Boolean                 reset= true;
2080         Chain                   target_group_member;
2081         Percent                 percent_ptr;
2082 
2083         for (; target != NULL; target = target->next) {
2084                 for (i = 0; i < target->used; i++) {
2085                         if (target->names[i] != NULL) {
2086                                 if (target_group_seen) {
2087                                         target_group_member =
2088                                           find_target_groups(target, i, reset);
2089                                         if(target_group_member == NULL) {
2090                                                 fatal_reader(catgets(catd, 1, 328, "Unexpected '+' on dependency line"));
2091                                         }
2092                                 }
2093                                 reset = false;
2094 
2095                                 /* If we saw it in the makefile it must be
2096                                  * a file */
2097                                 target->names[i]->stat.is_file = true;
2098                                 /* Make sure that we use dependencies 
2099                                  * entered for makefiles */
2100                                 target->names[i]->state = build_dont_know;
2101 
2102                                 /* If the target is special we delegate 
2103                                  * the processing */
2104                                 if (target->names[i]->special_reader 
2105                                     != no_special) {
2106                                         special_reader(target->names[i], 
2107                                                        depes, 
2108                                                        command);
2109                                 }       
2110                                 /* Check if this is a "a%b : x%y" type rule */




  24  */
  25 
  26 /*
  27  *      read.c
  28  *
  29  *      This file contains the makefile reader.
  30  */
  31 
  32 /*
  33  * Included files
  34  */
  35 #include <alloca.h>               /* alloca() */
  36 #include <errno.h>                /* errno */
  37 #include <fcntl.h>                /* fcntl() */
  38 #include <mk/defs.h>
  39 #include <mksh/macro.h>           /* expand_value(), expand_macro() */
  40 #include <mksh/misc.h>            /* getmem() */
  41 #include <mksh/read.h>            /* get_next_block_fn() */
  42 #include <sys/uio.h>              /* read() */
  43 #include <unistd.h>               /* read(), unlink() */
  44 #include <libintl.h>
  45 
  46 
  47 /*
  48  * typedefs & structs
  49  */
  50 
  51 /*
  52  * Static variables
  53  */
  54 
  55 static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
  56 
  57 /*
  58  * File table of contents
  59  */
  60 static  void            parse_makefile(register Name true_makefile_name, register Source source);
  61 static  Source          push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source);
  62 extern  void            enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
  63 extern  Name            normalize_name(register wchar_t *name_string, register int length);
  64 


 101         register int            n;
 102         char                    *path;
 103         register Source         source = ALLOC(Source);
 104         Property                orig_makefile = makefile;
 105         Dependency              *dpp;
 106         Dependency              dp;
 107         register int            length;
 108         wchar_t                 *previous_file_being_read = file_being_read;
 109         int                     previous_line_number = line_number;
 110         wchar_t                 previous_current_makefile[MAXPATHLEN];
 111         Makefile_type           save_makefile_type;
 112         Name                    normalized_makefile_name;
 113         register wchar_t        *string_start;
 114         register wchar_t        *string_end;
 115 
 116 
 117 
 118         wchar_t * wcb = get_wstring(makefile_name->string_mb);
 119 
 120         if (max_include_depth++ >= 40) {
 121                 fatal(gettext("Too many nested include statements"));
 122         }
 123         if (makefile->body.makefile.contents != NULL) {
 124                 retmem(makefile->body.makefile.contents);
 125         }
 126         source->inp_buf =
 127           source->inp_buf_ptr =
 128             source->inp_buf_end = NULL;
 129         source->error_converting = false;
 130         makefile->body.makefile.contents = NULL;
 131         makefile->body.makefile.size = 0;
 132         if ((makefile_name->hash.length != 1) ||
 133             (wcb[0] != (int) hyphen_char)) {
 134                 if ((makefile->body.makefile.contents == NULL) &&
 135                     (doname_it)) {
 136                         if (makefile_path == NULL) {
 137                                 char *pfx = make_install_prefix();
 138                                 char *path;
 139 
 140                                 add_dir_to_path(".",
 141                                                 &makefile_path,
 142                                                 -1);
 143 
 144                                 // As regularly installed
 145                                 asprintf(&path, "%s/../share/lib/make", pfx);
 146                                 add_dir_to_path(path, &makefile_path, -1);
 147                                 free(path);
 148 
 149                                 // Tools build
 150                                 asprintf(&path, "%s/../../share/", pfx);
 151                                 add_dir_to_path(path, &makefile_path, -1);
 152                                 free(path);
 153                                     
 154                                 add_dir_to_path("/usr/share/lib/make",
 155                                                 &makefile_path,
 156                                                 -1);
 157                                 add_dir_to_path("/etc/default",
 158                                                 &makefile_path,
 159                                                 -1);
 160 
 161                                 free(pfx);
 162                         }
 163                         save_makefile_type = makefile_type;
 164                         makefile_type = reading_nothing;
 165                         if (doname(makefile_name, true, false) == build_dont_know) {
 166                                 /* Try normalized filename */
 167                                 string_start=get_wstring(makefile_name->string_mb);
 168                                 for (string_end=string_start+1; *string_end != L'\0'; string_end++);
 169                                 normalized_makefile_name=normalize_name(string_start, string_end - string_start);
 170                                 if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) || 
 171                                         (doname(normalized_makefile_name, true, false) == build_dont_know)) {
 172                                         n = access_vroot(makefile_name->string_mb,
 173                                                  4,
 174                                                  chase_path ?
 175                                                  makefile_path : NULL,
 176                                                  VROOT_DEFAULT);
 177                                         if (n == 0) {


 188                                         }
 189                                 }
 190                                 retmem(string_start);
 191                                 /* 
 192                                  * Commented out: retmem_mb(normalized_makefile_name->string_mb);
 193                                  * We have to return this memory, but it seems to trigger a bug
 194                                  * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
 195                                  * is compiled using Sun C++ 5.6).
 196                                  */
 197                                 // retmem_mb(normalized_makefile_name->string_mb); 
 198                         }
 199                         makefile_type = save_makefile_type;
 200                 }
 201                 source->string.free_after_use = false;
 202                 source->previous = NULL;
 203                 source->already_expanded = false;
 204                 /* Lock the file for read, but not when -n. */
 205                 if (lock_makefile && 
 206                     !do_not_exec_rule) {
 207 
 208                          make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
 209                          (void) sprintf(make_state_lockfile,
 210                                                 "%s.lock",
 211                                                 make_state->string_mb);
 212                         (void) file_lock(make_state->string_mb,
 213                                          make_state_lockfile,
 214                                          (int *) &make_state_locked,
 215                                          0);
 216                         if(!make_state_locked) {
 217                                 printf("-- NO LOCKING for read\n");
 218                                 retmem_mb(make_state_lockfile);
 219                                 make_state_lockfile = 0;
 220                                 return failed;
 221                         }
 222                 }
 223                 if (makefile->body.makefile.contents == NULL) {
 224                         save_makefile_type = makefile_type;
 225                         makefile_type = reading_nothing;
 226                         if ((doname_it) &&
 227                             (doname(makefile_name, true, false) == build_failed)) {
 228                                 if (complain) {
 229                                         (void) fprintf(stderr,
 230                                                        gettext("make: Couldn't make `%s'\n"),
 231                                                        makefile_name->string_mb);
 232                                 }
 233                                 max_include_depth--;
 234                                 makefile_type = save_makefile_type;
 235                                 return failed;
 236                         }
 237                         makefile_type = save_makefile_type;
 238                         //
 239                         // Before calling exists() make sure that we have the right timestamp
 240                         //
 241                         makefile_name->stat.time = file_no_time;
 242 
 243                         if (exists(makefile_name) == file_doesnt_exist) {
 244                                 if (complain ||
 245                                     (makefile_name->stat.stat_errno != ENOENT)) {
 246                                         if (must_exist) {
 247                                                 fatal(gettext("Can't find `%s': %s"),
 248                                                       makefile_name->string_mb,
 249                                                       errmsg(makefile_name->
 250                                                              stat.stat_errno));
 251                                         } else {
 252                                                 warning(gettext("Can't find `%s': %s"),
 253                                                         makefile_name->string_mb,
 254                                                         errmsg(makefile_name->
 255                                                                stat.stat_errno));
 256                                         }
 257                                 }
 258                                 max_include_depth--;
 259                                 if(make_state_locked && (make_state_lockfile != NULL)) {
 260                                         (void) unlink(make_state_lockfile);
 261                                         retmem_mb(make_state_lockfile);
 262                                         make_state_lockfile = NULL;
 263                                         make_state_locked = false;
 264                                 }
 265                                 retmem(wcb);
 266                                 retmem_mb((char *)source);
 267                                 return failed;
 268                         }
 269                         /*
 270                          * These values are the size and bytes of
 271                          * the MULTI-BYTE makefile.
 272                          */


 277                         if (report_file) {
 278                                 for (dpp = &makefiles_used;
 279                                      *dpp != NULL;
 280                                      dpp = &(*dpp)->next);
 281                                 dp = ALLOC(Dependency);
 282                                 dp->next = NULL;
 283                                 dp->name = makefile_name;
 284                                 dp->automatic = false;
 285                                 dp->stale = false;
 286                                 dp->built = false;
 287                                 *dpp = dp;
 288                         }
 289                         source->fd = open_vroot(makefile_name->string_mb,
 290                                                 O_RDONLY,
 291                                                 0,
 292                                                 NULL,
 293                                                 VROOT_DEFAULT);
 294                         if (source->fd < 0) {
 295                                 if (complain || (errno != ENOENT)) {
 296                                         if (must_exist) {
 297                                                 fatal(gettext("Can't open `%s': %s"),
 298                                                       makefile_name->string_mb,
 299                                                       errmsg(errno));
 300                                         } else {
 301                                                 warning(gettext("Can't open `%s': %s"),
 302                                                         makefile_name->string_mb,
 303                                                         errmsg(errno));
 304                                         }
 305                                 }
 306                                 max_include_depth--;
 307                                 return failed;
 308                         }
 309                         (void) fcntl(source->fd, F_SETFD, 1);
 310                         orig_makefile->body.makefile.contents =
 311                           makefile->body.makefile.contents =
 312                             source->string.text.p =
 313                               source->string.buffer.start =
 314                                 ALLOC_WC((int) (makefile_name->stat.size + 2));
 315                         if (makefile_type == reading_cpp_file) {
 316                                 forget_after_parse = true;
 317                         }
 318                         source->string.text.end = source->string.text.p;
 319                         source->string.buffer.end =
 320                           source->string.text.p + makefile_name->stat.size;
 321                 } else {


 323                         source->fd = -1;
 324                         source->string.text.p =
 325                           source->string.buffer.start =
 326                             makefile->body.makefile.contents;
 327                         source->string.text.end =
 328                           source->string.buffer.end =
 329                             source->string.text.p + makefile->body.makefile.size;
 330                         source->bytes_left_in_file =
 331                           makefile->body.makefile.size;
 332                 }
 333                 file_being_read = wcb;
 334         } else {
 335                 char            *stdin_text_p;
 336                 char            *stdin_text_end;
 337                 char            *stdin_buffer_start;
 338                 char            *stdin_buffer_end;
 339                 char            *p_mb;
 340                 int             num_mb_chars;
 341                 size_t          num_wc_chars;
 342 
 343                 MBSTOWCS(wcs_buffer, "Standard in");
 344                 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
 345                 /*
 346                  * Memory to read standard in, then convert it
 347                  * to wide char strings.
 348                  */
 349                 stdin_buffer_start =
 350                   stdin_text_p = getmem(length = 1024);
 351                 stdin_buffer_end = stdin_text_p + length;
 352                 MBSTOWCS(wcs_buffer, "standard input");
 353                 file_being_read = (wchar_t *) wsdup(wcs_buffer);
 354                 line_number = 0;
 355                 while ((n = read(fileno(stdin),
 356                                  stdin_text_p,
 357                                  length)) > 0) {
 358                         length -= n;
 359                         stdin_text_p += n;
 360                         if (length == 0) {
 361                                 p_mb = getmem(length = 1024 +
 362                                               (stdin_buffer_end -
 363                                                stdin_buffer_start));
 364                                 (void) strncpy(p_mb,
 365                                                stdin_buffer_start,
 366                                                (stdin_buffer_end -
 367                                                 stdin_buffer_start));
 368                                 retmem_mb(stdin_buffer_start);
 369                                 stdin_text_p = p_mb +
 370                                   (stdin_buffer_end - stdin_buffer_start);
 371                                 stdin_buffer_start = p_mb;
 372                                 stdin_buffer_end =
 373                                   stdin_buffer_start + length;
 374                                 length = 1024;
 375                         }
 376                 }
 377                 if (n < 0) {
 378                         fatal(gettext("Error reading standard input: %s"),
 379                               errmsg(errno));
 380                 }
 381                 stdin_text_p = stdin_buffer_start;
 382                 stdin_text_end = stdin_buffer_end - length;
 383                 num_mb_chars = stdin_text_end - stdin_text_p;
 384 
 385                 /*
 386                  * Now, convert the sequence of multibyte chars into
 387                  * a sequence of corresponding wide character codes.
 388                  */
 389                 source->string.free_after_use = false;
 390                 source->previous = NULL;
 391                 source->bytes_left_in_file = 0;
 392                 source->fd = -1;
 393                 source->already_expanded = false;
 394                 source->string.buffer.start =
 395                   source->string.text.p = ALLOC_WC(num_mb_chars + 1);
 396                 source->string.buffer.end =
 397                     source->string.text.p + num_mb_chars;
 398                 num_wc_chars = mbstowcs(source->string.text.p,
 399                                         stdin_text_p,
 400                                         num_mb_chars);
 401                 if ((int) num_wc_chars >= 0) {
 402                         source->string.text.end =
 403                           source->string.text.p + num_wc_chars;
 404                 }
 405                 (void) retmem_mb(stdin_text_p);
 406         }
 407         line_number = 1;
 408         if (trace_reader) {
 409                 (void) printf(gettext(">>>>>>>>>>>>>>>> Reading makefile %s\n"),
 410                               makefile_name->string_mb);
 411         }
 412         parse_makefile(makefile_name, source);
 413         if (trace_reader) {
 414                 (void) printf(gettext(">>>>>>>>>>>>>>>> End of makefile %s\n"),
 415                               makefile_name->string_mb);
 416         }
 417         if(file_being_read) {
 418                 retmem(file_being_read);
 419         }
 420         file_being_read = previous_file_being_read;
 421         line_number = previous_line_number;
 422         makefile_type = reading_nothing;
 423         max_include_depth--;
 424         if (make_state_locked) {
 425                 /* Unlock .make.state. */
 426                 unlink(make_state_lockfile);
 427                 make_state_locked = false;
 428                 retmem_mb(make_state_lockfile);
 429         }
 430         if (forget_after_parse) {
 431                 retmem(makefile->body.makefile.contents);
 432                 makefile->body.makefile.contents = NULL;
 433         }
 434         retmem_mb((char *)source);


 713                                 /* And push the value */
 714                                 extrap->previous = source;
 715                                 source = extrap;
 716                                 CACHE_SOURCE(0);
 717                                 goto line_evald;
 718                         }
 719                 }
 720         default:
 721                 goto line_evald;
 722         }
 723 
 724         /* We now have a line we can start reading */
 725  line_evald:
 726         if (source == NULL) {
 727                 GOTO_STATE(exit_state);
 728         }
 729         /* Check if this is an include command */
 730         if ((makefile_type == reading_makefile) &&
 731             !source->already_expanded) {
 732             if (include_space[0] == (int) nul_char) {
 733                 MBSTOWCS(include_space, "include ");
 734                 MBSTOWCS(include_tab, "include\t");
 735             }
 736             if ((IS_WEQUALN(source_p, include_space, 8)) ||
 737                 (IS_WEQUALN(source_p, include_tab, 8))) {
 738                 source_p += 7;
 739                 if (iswspace(*source_p)) {
 740                         Makefile_type save_makefile_type;
 741                         wchar_t         *name_start;
 742                         int             name_length;
 743 
 744                         /*
 745                          * Yes, this is an include.
 746                          * Skip spaces to get to the filename.
 747                          */
 748                         while (iswspace(*source_p) ||
 749                                (*source_p == (int) nul_char)) {
 750                                 switch (GET_CHAR()) {
 751                                 case nul_char:
 752                                         GET_NEXT_BLOCK(source);
 753                                         if (source == NULL) {
 754                                                 GOTO_STATE(on_eoln_state);


 857                                      p++);
 858                                 for (q = p;
 859                                      (*q != (int) nul_char) && !iswspace(*q);
 860                                      q++);
 861                                 makefile_name = GETNAME(p, q-p);
 862                                 if (destination.free_after_use) {
 863                                         retmem(destination.buffer.start);
 864                                 }
 865                         }
 866                         source_p++;
 867                         UNCACHE_SOURCE();
 868                         /* Read the file */
 869                         save_makefile_type = makefile_type;
 870                         if (read_simple_file(makefile_name,
 871                                              true,
 872                                              true,
 873                                              true,
 874                                              false,
 875                                              true,
 876                                              false) == failed) {
 877                                 fatal_reader(gettext("Read of include file `%s' failed"),
 878                                              makefile_name->string_mb);
 879                         }
 880                         makefile_type = save_makefile_type;
 881                         do_not_exec_rule = save_do_not_exec_rule;
 882                         CACHE_SOURCE(0);
 883                         goto start_new_line;
 884                 } else {
 885                         source_p -= 7;
 886                 }
 887             } else {
 888                 /* Check if the word include was split across 8K boundary. */
 889                 
 890                 tmp_bytes_left_in_string = source->string.text.end - source_p;
 891                 if (tmp_bytes_left_in_string < 8) {
 892                         tmp_maybe_include = false;
 893                         if (IS_WEQUALN(source_p,
 894                                        include_space,
 895                                        tmp_bytes_left_in_string)) {
 896                                 tmp_maybe_include = true;
 897                         }


1043                         if (source_p != string_start) {
1044                                 if (!macro_seen_in_string) {
1045                                         INIT_STRING_FROM_STACK(name_string,
1046                                                                name_buffer);
1047                                 }
1048                                 append_string(string_start,
1049                                               &name_string,
1050                                               source_p - string_start);
1051                                 macro_seen_in_string = true;
1052                         }
1053                         /* Get more text to read */
1054                         GET_NEXT_BLOCK(source);
1055                         string_start = source_p;
1056                         source_p--;
1057                         if (source == NULL) {
1058                                 GOTO_STATE(on_eoln_state);
1059                         }
1060                         break;
1061                 case newline_char:
1062                         if (paren_count > 0) {
1063                                 fatal_reader(gettext("Unmatched `(' on line"));
1064                         }
1065                         if (brace_count > 0) {
1066                                 fatal_reader(gettext("Unmatched `{' on line"));
1067                         }
1068                         source_p++;
1069                         /* Enter name */
1070                         current_names = enter_name(&name_string,
1071                                                    macro_seen_in_string,
1072                                                    string_start,
1073                                                    source_p - 1,
1074                                                    current_names,
1075                                                    &extra_names,
1076                                                    &target_group_seen);
1077                         first_target = false;
1078                         if (extra_names == NULL) {
1079                                 extra_names = (Name_vector)
1080                                   alloca((int) sizeof (Name_vector_rec));
1081                         }
1082                         /* Do postprocessing or return error */
1083                         if (source->fd >= 0) {
1084                                 line_number++;
1085                         }
1086                         GOTO_STATE(on_eoln_state);


1099                                 if (source == NULL) {
1100                                         GOTO_STATE(on_eoln_state);
1101                                 }
1102                         }
1103                         if (*source_p == (int) newline_char) {
1104                                 if (source->fd >= 0) {
1105                                         line_number++;
1106                                 }
1107                                 *source_p = (int) space_char;
1108                                 string_start = source_p;
1109                                 goto resume_name_scan;
1110                         } else {
1111                                 string_start = source_p;
1112                                 break;
1113                         }
1114                         break;
1115                 case numbersign_char:
1116                         if (paren_count + brace_count > 0) {
1117                                 break;
1118                         }
1119                         fatal_reader(gettext("Unexpected comment seen"));
1120                 case dollar_char:
1121                         if (source->already_expanded) {
1122                                 break;
1123                         }
1124                         /* Save the identifier so far */
1125                         if (source_p != string_start) {
1126                                 if (!macro_seen_in_string) {
1127                                         INIT_STRING_FROM_STACK(name_string,
1128                                                                name_buffer);
1129                                 }
1130                                 append_string(string_start,
1131                                               &name_string,
1132                                               source_p - string_start);
1133                                 macro_seen_in_string = true;
1134                         }
1135                         /* Eval and push the macro */
1136                         source_p++;
1137                         UNCACHE_SOURCE();
1138                         {
1139                                 Source t =
1140                                   (Source) alloca((int) sizeof (Source_rec));
1141                                 source = push_macro_value(t,
1142                                                           buffer,
1143                                                           sizeof buffer,
1144                                                           source);
1145                         }
1146                         CACHE_SOURCE(1);
1147                         string_start = source_p + 1;
1148                         break;
1149                 case parenleft_char:
1150                         paren_count++;
1151                         break;
1152                 case parenright_char:
1153                         if (--paren_count < 0) {
1154                                 fatal_reader(gettext("Unmatched `)' on line"));
1155                         }
1156                         break;
1157                 case braceleft_char:
1158                         brace_count++;
1159                         break;
1160                 case braceright_char:
1161                         if (--brace_count < 0) {
1162                                 fatal_reader(gettext("Unmatched `}' on line"));
1163                         }
1164                         break;
1165                 case ampersand_char:
1166                 case greater_char:
1167                 case bar_char:
1168                         if (paren_count + brace_count == 0) {
1169                                 source_p++;
1170                         }
1171                         /* Fall into */
1172                 case tab_char:
1173                 case space_char:
1174                         if (paren_count + brace_count > 0) {
1175                                 break;
1176                         }
1177                         current_names = enter_name(&name_string,
1178                                                    macro_seen_in_string,
1179                                                    string_start,
1180                                                    source_p,
1181                                                    current_names,
1182                                                    &extra_names,


1187                                   alloca((int) sizeof (Name_vector_rec));
1188                         }
1189                         goto enter_state;
1190                 case colon_char:
1191                         if (paren_count + brace_count > 0) {
1192                                 break;
1193                         }
1194                         if (separator == conditional_seen) {
1195                                 break;
1196                         }
1197 /** POSIX **/
1198 #if 0
1199                         if(posix) {
1200                           emptycount = 0;
1201                         }
1202 #endif
1203 /** END POSIX **/
1204                         /* End of the target list. We now start reading */
1205                         /* dependencies or a conditional assignment */
1206                         if (separator != none_seen) {
1207                                 fatal_reader(gettext("Extra `:', `::', or `:=' on dependency line"));
1208                         }
1209                         /* Enter the last target */
1210                         if ((string_start != source_p) ||
1211                             macro_seen_in_string) {
1212                                 current_names =
1213                                   enter_name(&name_string,
1214                                              macro_seen_in_string,
1215                                              string_start,
1216                                              source_p,
1217                                              current_names,
1218                                              &extra_names,
1219                                              &target_group_seen);
1220                                 first_target = false;
1221                                 if (extra_names == NULL) {
1222                                         extra_names = (Name_vector)
1223                                           alloca((int)
1224                                                  sizeof (Name_vector_rec));
1225                                 }
1226                         }
1227                         /* Check if it is ":" "::" or ":=" */
1228                 scan_colon_label:
1229                         switch (*++source_p) {
1230                         case nul_char:
1231                                 GET_NEXT_BLOCK(source);
1232                                 source_p--;
1233                                 if (source == NULL) {
1234                                         GOTO_STATE(enter_dependencies_state);
1235                                 }
1236                                 goto scan_colon_label;
1237                         case equal_char:
1238                                 if(svr4) {
1239                                   fatal_reader(gettext("syntax error"));
1240                                 }
1241                                 separator = conditional_seen;
1242                                 source_p++;
1243                                 current_names = &depes;
1244                                 GOTO_STATE(scan_name_state);
1245                         case colon_char:
1246                                 separator = two_colon;
1247                                 source_p++;
1248                                 break;
1249                         default:
1250                                 separator = one_colon;
1251                         }
1252                         current_names = &depes;
1253                         on_eoln_state = enter_dependencies_state;
1254                         GOTO_STATE(scan_name_state);
1255                 case semicolon_char:
1256                         if (paren_count + brace_count > 0) {
1257                                 break;
1258                         }
1259                         /* End of reading names. Start reading the rule */
1260                         if ((separator != one_colon) &&
1261                             (separator != two_colon)) {
1262                                 fatal_reader(gettext("Unexpected command seen"));
1263                         }
1264                         /* Enter the last dependency */
1265                         if ((string_start != source_p) ||
1266                             macro_seen_in_string) {
1267                                 current_names =
1268                                   enter_name(&name_string,
1269                                              macro_seen_in_string,
1270                                              string_start,
1271                                              source_p,
1272                                              current_names,
1273                                              &extra_names,
1274                                              &target_group_seen);
1275                                 first_target = false;
1276                                 if (extra_names == NULL) {
1277                                         extra_names = (Name_vector)
1278                                           alloca((int)
1279                                                  sizeof (Name_vector_rec));
1280                                 }
1281                         }
1282                         source_p++;


1369                         switch (*++source_p) {
1370                         case nul_char:
1371                                 if (!macro_seen_in_string) {
1372                                         INIT_STRING_FROM_STACK(name_string,
1373                                                                name_buffer);
1374                                 }
1375                                 append_string(string_start,
1376                                               &name_string,
1377                                               source_p - string_start);
1378                                 GET_NEXT_BLOCK(source);
1379                                 source_p--;
1380                                 string_start = source_p;
1381                                 if (source == NULL) {
1382                                         GOTO_STATE(illegal_eoln_state);
1383                                 }
1384                                 goto scan_append;
1385                         case equal_char:
1386                                 if(!svr4) {
1387                                   append = true;
1388                                 } else {
1389                                   fatal_reader(gettext("Must be a separator on rules"));
1390                                 }
1391                                 break;
1392                         default:
1393                                 /* The "+" just starts a regular name. */
1394                                 /* Start reading that name */
1395                                 goto resume_name_scan;
1396                         }
1397                         /* Fall into */
1398                 case equal_char:
1399                         if (paren_count + brace_count > 0) {
1400                                 break;
1401                         }
1402                         /* We found macro assignment. */
1403                         /* Check if it is legal and if it is appending */
1404                         switch (separator) {
1405                         case none_seen:
1406                                 separator = equal_seen;
1407                                 on_eoln_state = enter_equal_state;
1408                                 break;
1409                         case conditional_seen:
1410                                 on_eoln_state = enter_conditional_state;
1411                                 break;
1412                         default:
1413                                 /* Reader must special check for "MACRO:sh=" */
1414                                 /* notation */
1415                                 if (sh_name == NULL) {
1416                                         MBSTOWCS(wcs_buffer, "sh");
1417                                         sh_name = GETNAME(wcs_buffer, FIND_LENGTH);
1418                                         MBSTOWCS(wcs_buffer, "shell");
1419                                         shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
1420                                 }
1421 
1422                                 if (!macro_seen_in_string) {
1423                                         INIT_STRING_FROM_STACK(name_string,
1424                                                        name_buffer);
1425                                 }
1426                                 append_string(string_start,
1427                                               &name_string,
1428                                               source_p - string_start
1429                                 );
1430 
1431                                 if ( (((target.used == 1) &&
1432                                      (depes.used == 1) &&
1433                                      (depes.names[0] == sh_name)) ||
1434                                     ((target.used == 1) &&
1435                                      (depes.used == 0) &&
1436                                      (separator == one_colon) &&
1437                                      (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) &&
1438                                     (!svr4)) {


1467                                         wchar_t         buffer[100];
1468 
1469                                         INIT_STRING_FROM_STACK(macro_name,
1470                                                                buffer);
1471                                         APPEND_NAME(target.names[0],
1472                                                       &macro_name,
1473                                                       FIND_LENGTH);
1474                                         append_char((int) colon_char,
1475                                                     &macro_name);
1476                                         APPEND_NAME(shell_name,
1477                                                       &macro_name,
1478                                                       FIND_LENGTH);
1479                                         target.names[0] =
1480                                           GETNAME(macro_name.buffer.start,
1481                                                   FIND_LENGTH);
1482                                         separator = equal_seen;
1483                                         on_eoln_state = enter_equal_state;
1484                                         break;
1485                                 } 
1486                                 if(svr4) {
1487                                   fatal_reader(gettext("syntax error"));
1488                                 }
1489                                 else {
1490                                   fatal_reader(gettext("Macro assignment on dependency line"));
1491                                 }
1492                         }
1493                         if (append) {
1494                                 source_p--;
1495                         }
1496                         /* Enter the macro name */
1497                         if ((string_start != source_p) ||
1498                             macro_seen_in_string) {
1499                                 current_names =
1500                                   enter_name(&name_string,
1501                                              macro_seen_in_string,
1502                                              string_start,
1503                                              source_p,
1504                                              current_names,
1505                                              &extra_names,
1506                                              &target_group_seen);
1507                                 first_target = false;
1508                                 if (extra_names == NULL) {
1509                                         extra_names = (Name_vector)
1510                                           alloca((int)


1969  *      enter conditional state
1970  */
1971 case enter_conditional_state:
1972         if (depes.used != 1) {
1973                 GOTO_STATE(poorly_formed_macro_state);
1974         }
1975         for (nvp = &target; nvp != NULL; nvp = nvp->next) {
1976                 for (i = 0; i < nvp->used; i++) {
1977                         enter_conditional(nvp->names[i],
1978                                           depes.names[0],
1979                                           macro_value,
1980                                           append);
1981                 }
1982         }
1983         goto start_new_line;
1984 
1985 /****************************************************************
1986  *      Error states
1987  */
1988 case illegal_bytes_state:
1989         fatal_reader(gettext("Invalid byte sequence"));
1990 case illegal_eoln_state:
1991         if (line_number > 1) {
1992                 if (line_started_with_space == (line_number - 1)) {
1993                         line_number--;
1994                         fatal_reader(gettext("Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)"));
1995                 }
1996         }
1997         fatal_reader(gettext("Unexpected end of line seen"));
1998 case poorly_formed_macro_state:
1999         fatal_reader(gettext("Badly formed macro assignment"));
2000 case exit_state:
2001         return;
2002 default:
2003         fatal_reader(gettext("Internal error. Unknown reader state"));
2004 }
2005 }
2006 
2007 /*
2008  *      push_macro_value(bp, buffer, size, source)
2009  *
2010  *      Macro and function that evaluates one macro
2011  *      and makes the reader read from the value of it
2012  *
2013  *      Return value:
2014  *                              The source block to read the macro from
2015  *
2016  *      Parameters:
2017  *              bp              The new source block to fill in
2018  *              buffer          Buffer to read from
2019  *              size            size of the buffer
2020  *              source          The old source block
2021  *
2022  *      Global variables used:
2023  */


2071  *      is called to setup the dependencies and the commands for it.
2072  *      If the target is a % pattern or part of a target group, then 
2073  *      the appropriate routines are called.
2074  */
2075         
2076 void
2077 enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
2078 {
2079         int                     i;
2080         Boolean                 reset= true;
2081         Chain                   target_group_member;
2082         Percent                 percent_ptr;
2083 
2084         for (; target != NULL; target = target->next) {
2085                 for (i = 0; i < target->used; i++) {
2086                         if (target->names[i] != NULL) {
2087                                 if (target_group_seen) {
2088                                         target_group_member =
2089                                           find_target_groups(target, i, reset);
2090                                         if(target_group_member == NULL) {
2091                                                 fatal_reader(gettext("Unexpected '+' on dependency line"));
2092                                         }
2093                                 }
2094                                 reset = false;
2095 
2096                                 /* If we saw it in the makefile it must be
2097                                  * a file */
2098                                 target->names[i]->stat.is_file = true;
2099                                 /* Make sure that we use dependencies 
2100                                  * entered for makefiles */
2101                                 target->names[i]->state = build_dont_know;
2102 
2103                                 /* If the target is special we delegate 
2104                                  * the processing */
2105                                 if (target->names[i]->special_reader 
2106                                     != no_special) {
2107                                         special_reader(target->names[i], 
2108                                                        depes, 
2109                                                        command);
2110                                 }       
2111                                 /* Check if this is a "a%b : x%y" type rule */