N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/Vaike/linux/system-addons/system/soap/sensor_preprocessor.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute
00027  * it and/or modify it under the terms of the GNU General Public
00028  * License as published by the Free Software Foundation; version 2 of
00029  * the License. Accordingly, this program is distributed in the hope
00030  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00031  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00032  * PURPOSE. See the GNU General Public License for more details.
00033  */
00034 
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <strings.h>
00040 #include <sys/time.h>
00041 #include <ctype.h>
00042 #include <wait.h>
00043 #include <limits.h>
00044 
00045 #ifndef GCC
00046 #define GCC "/usr/bin/gcc"
00047 #endif
00048 
00049 #define FILENAME_LEN  24
00050 #define MAX_OBJ_FILES 512
00051 
00052 static const char *gcc_path = GCC;
00053 static const char *include_dirs[] = { "-I" PREFIX "/include", "-I.", NULL };
00054 static const char *library_dirs[] = { "-L" PREFIX "/lib", NULL };
00055 static const char *additional_libs[] = { "-lipc", "-lpthread", NULL };
00056 static const char *my_app;
00057 static char *additional_objects[MAX_OBJ_FILES + 1];
00058 
00059 
00060 inline static int usage(void)
00061 {
00062         fprintf(stderr, "Usage: %s [--with-gcc path to gcc (%s)] "
00063                 "[--preserve-c-translation] [multiple gcc options]"
00064                 " <input file>\n", my_app, gcc_path);
00065         return -1;
00066 }
00067 
00068 
00069 inline static int no_input(void)
00070 {
00071         fprintf(stderr, "%s: no input files\n", my_app);
00072         return -1;
00073 }
00074 
00075 
00076 inline static int no_file(char *name)
00077 {
00078         char msg[PATH_MAX];
00079         sprintf(msg, "%s: %s", my_app, name);
00080         perror(msg);
00081         return -1;
00082 }
00083 
00084 
00085 static int local_file_with_c(char *dot_h)
00086 {
00087         char path[PATH_MAX + 1];
00088         int filename_len;
00089         char *end, dot_c[PATH_MAX + 1];
00090         strncpy(dot_c, dot_h, PATH_MAX);
00091         if ((end = index(dot_c, '.')) == NULL)
00092                 return 0;
00093         *(end+1) = 'c';
00094         *(end+2) = '\0';
00095         filename_len = strlen(dot_c);
00096 
00097         if (getcwd(path, PATH_MAX - filename_len) == NULL)
00098                 return 0;
00099         strcat(path, "/");
00100         strcat(path, dot_c);
00101 
00102         if (access(path, R_OK) < 0)
00103             return 0;
00104         return 1;
00105 }
00106 
00107 
00108 static char *rtrim(char *string)
00109 {
00110         if (string != NULL) {
00111                 char *end = string;
00112                 while (*(end+1) != '\0')
00113                         end++;
00114 
00115                 while (end >= string && isspace(*end)) {
00116                         *end = '\0';
00117                         end--;
00118                 }
00119         }
00120         return string;
00121 }
00122 
00123 
00124 static char *ltrim(char *string)
00125 {
00126         if (string != NULL) {
00127                 char *end = string;
00128                 while (*(end+1) != '\0')
00129                         end++;
00130 
00131                 while (string <= end && isspace(*string))
00132                         string++;
00133         }
00134         return string;
00135 }
00136 
00137 
00138 static char *trim(char *string)
00139 {
00140         return rtrim(ltrim(string));
00141 }
00142 
00143 
00144 static char *next_ws(char *string)
00145 {
00146         char *end = string;
00147         while (!isspace(*end) && *end != ')' 
00148                && *end != ';' && *end != ']')
00149                 end++;
00150         return end;
00151 }
00152 
00153 
00154 static char *skip_ws(char *string)
00155 {
00156         char *end = string;
00157         while (isspace(*end))
00158                 end++;
00159         return end;
00160 }
00161 
00162 
00163 static char *get_sensor_main(void)
00164 {
00165         return "}\n"
00166                 "\n"
00167                 "\n"
00168                 "int main(int argc, char *argv[])\n"
00169                 "{\n"
00170                 "       if (argc != 3)\n"
00171                 "               fprintf(stderr, \"Usage: %%s"
00172                 " <data port> <cmd port>\", argv[0]);\n"
00173                 "       ipc_data_port = atoi(argv[1]);\n"
00174                 "       ipc_cmd_port = atoi(argv[2]);\n"
00175                 "\n"
00176                 "       initialize_ipc(-1);\n"
00177                 "\n"
00178                 "       while (!quitting()) {\n"
00179                 "               sensor_app();\n"
00180                 "       }\n"
00181                 "       pthread_join(data_thread, NULL);\n"
00182                 "       pthread_join(cmd_thread, NULL);\n"
00183                 "\n"
00184                 "       return 0;\n"
00185                 "}\n"
00186                 "\n";
00187 }
00188 
00189 
00190 static char *my_mktemp(char *string)
00191 {
00192         if (string != NULL) {
00193                 while (*string != '\0') {
00194                         if (*string == 'X') {
00195                         try_again:
00196                                 *string = '0' + (char)((double)'z' * 
00197                                                        ((double)random() / 
00198                                                         (RAND_MAX + (double)'0')));
00199                                 if (!isalnum(*string))
00200                                         goto try_again;
00201                         }
00202                         string++;
00203                 }
00204         }
00205         return string;
00206 }
00207 
00208 
00209 static void transform(FILE *infile, FILE *outfile)
00210 {
00211         unsigned int app_def = 0;
00212         unsigned int incl_def = 0;
00213         unsigned int brace_count = 0;
00214         int obj = 0, line_len = 512;
00215         char line[line_len];
00216 
00217         while (fgets(line, line_len, infile) != NULL) {
00218                 char new_line[2048];
00219                 char *cur_in = line;
00220                 char *cur_out = new_line;
00221                 char unused[256];
00222                 int spaces = 0;
00223 
00224                 memset(new_line, '\0', 1024);
00225                 while (*cur_in != '\0') {
00226                         if (*cur_in == '\n') {
00227                                 cur_in++;
00228                                 spaces = 0;
00229                         } else if (*cur_in == '{') {
00230                                 brace_count++;
00231                                 *cur_out++ = *cur_in++;
00232                                 spaces = 0;
00233                         } else if (isspace(*cur_in)) {
00234                                 spaces++;
00235                                 *cur_out++ = *cur_in++;
00236                         } else if (*cur_in == '}') {
00237                                 brace_count--;
00238                                 cur_in++;
00239                                 if (app_def > 0 && brace_count == 0) {
00240                                         sprintf(cur_out, get_sensor_main());
00241                                         cur_out += strlen(cur_out);
00242                                 } else
00243                                         *cur_out++ = '}';
00244                                 spaces = 0;
00245                         } else if (*cur_in == ']') {
00246                                 cur_in++;
00247                                 *cur_out++ = ')';
00248                                 spaces = 0;
00249                         } else if (strncmp(cur_in, "incl:", 5) == 0) {
00250                                 char dot_h[PATH_MAX];
00251                                 char *file = index(cur_in, ':');
00252                                 file++;
00253                                 sprintf(dot_h, "%s", trim(file));
00254                                 sprintf(cur_out, "#include <%s>", dot_h);
00255 
00256                                 if (local_file_with_c(dot_h) &&
00257                                     obj < MAX_OBJ_FILES) {
00258                                         char *end, *dot_o =
00259                                                 (char*) malloc(PATH_MAX + 1);
00260                                         snprintf(dot_o, PATH_MAX,
00261                                                  "%s", trim(file));
00262                                         end = index(dot_o, '.');
00263                                         *(end+1) = 'o';
00264                                         *(end+2) = '\0';
00265                                         additional_objects[obj++] = dot_o;
00266                                 }
00267                                 break;
00268                         } else if (strncmp(cur_in, "decl:", 5) == 0) {
00269                                 char *vars = index(cur_in, ':');
00270                                 vars++;
00271                                 sprintf(cur_out, "long %s", trim(vars));
00272                                 if (incl_def == 0 && app_def == 0) {
00273                                         sprintf(cur_out, 
00274                                                 "#include <stdio.h>\n"
00275                                                 "#include <stdlib.h>\n"
00276                                                 "#include <ipc.h>\n"
00277                                                 "#include <sensor_app.h>\n\n"
00278                                                 "int long_len ="
00279                                                 " sizeof(long);\n\n");
00280                                         incl_def++;
00281                                         cur_out += strlen(cur_out);
00282                                 }
00283                                 break;
00284                         } else if (strncmp(cur_in, "funct:", 6) == 0) {
00285                                 char *end, *a_end, *args;
00286                                 char *name = index(cur_in, ':');
00287                                 name++;
00288                                 name = skip_ws(name);
00289                                 args = next_ws(name);
00290                                 *args = '\0';
00291                                 args++;
00292                                 end = index(args, '{');
00293                                 *end = '\0';
00294 
00295                                 if (incl_def == 0 && app_def == 0) {
00296                                         sprintf(cur_out, 
00297                                                 "#include <stdio.h>\n"
00298                                                 "#include <stdlib.h>\n"
00299                                                 "#include <ipc.h>\n"
00300                                                 "#include <sensor_app.h>\n\n"
00301                                                 "int long_len ="
00302                                                 " sizeof(long);\n\n");
00303                                         incl_def++;
00304                                         cur_out += strlen(cur_out);
00305                                 }
00306 
00307                                 sprintf(cur_out, "long %s(", trim(name));
00308 
00309                                 do {
00310                                         a_end = index(args, ',');
00311                                         if (a_end != NULL)
00312                                                 *a_end = '\0';
00313 
00314                                         strcat(cur_out, "long ");
00315                                         strcat(cur_out, trim(args));
00316                                         if (a_end != NULL) {
00317                                                 strcat(cur_out, ", ");
00318                                                 args = a_end + 1;
00319                                                 args = skip_ws(args);
00320                                         }
00321                                 } while (a_end != NULL);
00322                                 strcat(cur_out, ")\n{");
00323                                 brace_count++;
00324                                 break;
00325                         } else if (strncmp(cur_in, "app:", 4) == 0) {
00326                                 char *name = NULL, *args = NULL;
00327                                 char *end = NULL;
00328 
00329                                 name = index(cur_in, ':');
00330                                 name++;
00331                                 if (incl_def == 0 && app_def == 0) {
00332                                         sprintf(cur_out, 
00333                                                 "#include <stdio.h>\n"
00334                                                 "#include <stdlib.h>\n"
00335                                                 "#include <ipc.h>\n"
00336                                                 "#include <sensor_app.h>\n\n"
00337                                                 "int long_len ="
00338                                                 " sizeof(long);\n\n");
00339                                         incl_def++;
00340                                         cur_out += strlen(cur_out);
00341                                 }
00342 
00343                                 if ((args = index(name, '(')) != NULL) {
00344                                         end = index(args, ')');
00345                                         *args = '\0';
00346                                         args++;
00347                                         args = trim(args);
00348                                         *end = '\0';
00349                                         end++;
00350                                         sprintf(cur_out,
00351                                                 "int ipc_data_port,"
00352                                                 " ipc_cmd_port;\n"
00353                                                 "const long %s;\n"
00354                                                 "const char *my_app = \"%s\";"
00355                                                 "\n\nvoid sensor_app()\n{",
00356                                                 trim(args), trim(name));
00357                                 } else
00358                                         sprintf(cur_out,
00359                                                 "int ipc_data_port,"
00360                                                 " ipc_cmd_port;\n"
00361                                                 "const char *my_app = \"%s\";"
00362                                                 "\n\nvoid sensor_app()\n{",
00363                                                 trim(name));
00364                                 app_def++;
00365                                 brace_count++;
00366                                 break;
00367                         } else if (sscanf(cur_in, "when [ %s", unused) == 1) {
00368                                 char x, *end, *func, *compare;
00369                                 char spacing[128];
00370                                 char *assign = index(cur_in, '[');
00371                                 assign++;
00372                                 func = strstr(cur_in, "<-");
00373                                 *func = '\0';
00374                                 func += 2;
00375                                 func = skip_ws(func);
00376                                 end = next_ws(func);
00377                                 x = *end;
00378                                 *end = '\0';
00379                                 memset(spacing, '\0', 128);
00380                                 memset(spacing, ' ', spaces);
00381 
00382                                 sprintf(cur_out, "consume(\"%s\","
00383                                         " (unsigned char*)&%s, &long_len);"
00384                                         "\n%sif (%s ",
00385                                         trim(func), trim(assign),
00386                                         spacing, trim(assign));
00387                                 *end = x;
00388                                 cur_in = end;
00389                                 cur_out += strlen(cur_out);
00390                                 spaces = 0;
00391                         } else if (strncmp(cur_in, "produce:", 8) == 0) {
00392                                 char x, *end;
00393                                 char *assign = index(cur_in, ':');
00394                                 assign++;
00395                                 assign = skip_ws(assign);
00396                                 end = next_ws(assign);
00397                                 x = *end;
00398                                 *end = '\0';
00399 
00400                                 sprintf(cur_out, "produce(Soap_Long,"
00401                                         " (unsigned char*)&%s, long_len)",
00402                                         trim(assign));
00403                                 *end = x;
00404                                 cur_in = end;
00405                                 cur_out += strlen(cur_out);
00406                                 spaces = 0;
00407                         } else if (index(cur_in, ':') != NULL) {
00408                                 char x, *funct_name, *args, *end;
00409                                 char *begin, *delim = index(cur_in, ':');
00410 
00411                                 begin = delim-1;
00412                                 while (isalnum(*begin) || *begin == '_')
00413                                         begin--;
00414 
00415                                 if (begin == cur_in) {
00416                                         *cur_out++ = *cur_in++;
00417                                         continue;
00418                                 }
00419                                 funct_name = begin + 1;
00420                                 *delim = '\0';
00421 
00422                                 end = args = delim + 1;  // FIXME
00423                                 while (*end != ';')
00424                                         end++;
00425                                 x = *end;
00426                                 *end = '\0';
00427                                 sprintf(cur_out, "%s(%s)",
00428                                         trim(funct_name), trim(args));
00429                                 *end = x;
00430                                 cur_in = end;
00431                                 cur_out += strlen(cur_out);
00432                                 spaces = 0;
00433                         } else {
00434                                 *cur_out++ = *cur_in++;
00435                                 spaces = 0;
00436                         }
00437                 }
00438                 fprintf(outfile, "%s\n", new_line);
00439         }
00440 }
00441 
00442 
00443 int main(int argc, char *argv[])
00444 {
00445         unsigned int keep_c = 0;
00446         int i, j = 0, k = 0;
00447         int error, status, verbose = 0;
00448         char *gcc_arg0;
00449         char *gcc_comp_args[ARG_MAX];
00450         char *gcc_link_args[ARG_MAX];
00451         char *in_filename = NULL;
00452         FILE *infile, *outfile;
00453         char *final_executable;
00454         char intermediate_c[FILENAME_LEN + 1] = "";
00455         char intermediate_o[FILENAME_LEN + 1] = "";
00456         struct timeval now;
00457 
00458         gettimeofday(&now, NULL);
00459         srandom((unsigned int) now.tv_sec);
00460 
00461         my_app = rindex(argv[0], '/');
00462         if (my_app == NULL)
00463                 my_app = argv[0];
00464         else
00465                 my_app++;
00466 
00467         if (argc < 2)
00468                 return no_input();
00469 
00470         for (i = 0; i < ARG_MAX; i++) {
00471                 gcc_comp_args[i] = (char *)0;
00472                 gcc_link_args[i] = (char *)0;
00473         }
00474         gcc_comp_args[j++] = gcc_arg0;
00475         gcc_link_args[k++] = gcc_arg0;
00476 
00477         for (i = 0; i <= MAX_OBJ_FILES; i++)
00478                 additional_objects[i] = NULL;
00479 
00480         for (i = 1; i < argc - 1; i++) {
00481                 if (strncmp(argv[i], "--with-gcc", 10) == 0)
00482                         gcc_path = argv[++i];
00483                 else if (strncmp(argv[i], "--preserve-c-translation", 26) == 0)
00484                         keep_c++;
00485                 else if (strncmp(argv[i], "-o", 2) == 0)
00486                         final_executable = argv[++i];
00487                 else if (strncmp(argv[i], "-v", 2) == 0) {
00488                         verbose++;
00489                         gcc_comp_args[j++] = argv[i];
00490                         gcc_link_args[k++] = argv[i];
00491                 } else if (strncmp(argv[i], "-h", 2) == 0)
00492                         return usage();
00493                 else if (strncmp(argv[i], "--help", 6) == 0)
00494                         return usage();
00495                 else {
00496                         gcc_comp_args[j++] = argv[i];
00497                         gcc_link_args[k++] = argv[i];
00498                 }
00499         }
00500         if ((in_filename = argv[argc - 1]) == NULL)
00501                 return no_input();
00502 
00503         if (keep_c) {
00504                 snprintf(intermediate_c, FILENAME_LEN, "%s.c", final_executable);
00505         } else {
00506                 strncpy(intermediate_c, "/tmp/sppXXXXXX.c", FILENAME_LEN);
00507                 my_mktemp(intermediate_c);
00508         }
00509         strncpy(intermediate_o, "/tmp/sppXXXXXX.o", FILENAME_LEN);
00510         my_mktemp(intermediate_o);
00511 
00512         gcc_arg0 = rindex(gcc_path, '/');
00513         if (my_app == NULL)
00514                 gcc_arg0 = (char*) gcc_path;
00515         else
00516                 gcc_arg0++;
00517 
00518         if ((infile = fopen(in_filename, "r")) == NULL)
00519                 return no_file(in_filename);
00520         if ((outfile = fopen(intermediate_c, "w")) == NULL)
00521                 return no_file((char*)intermediate_c);
00522 
00523         transform(infile, outfile);
00524 
00525         fclose(infile);
00526         fclose(outfile);
00527 
00528 
00529         gcc_comp_args[0] = gcc_arg0;
00530         gcc_comp_args[j++] = "-c";
00531         gcc_comp_args[j++] = "-o";
00532         gcc_comp_args[j++] = (char*) intermediate_o;
00533         for (i = 0; include_dirs[i] != NULL; i++)
00534                 gcc_comp_args[j++] = (char*) include_dirs[i];
00535         gcc_comp_args[j++] = (char*) intermediate_c;
00536 
00537         gcc_link_args[0] = gcc_arg0;
00538         gcc_link_args[k++] = "-static";
00539         gcc_link_args[k++] = "-o";
00540         gcc_link_args[k++] = final_executable;
00541         gcc_link_args[k++] = (char*) intermediate_o;
00542         for (i = 0; additional_objects[i] != NULL; i++)
00543                 gcc_link_args[k++] = (char*) additional_objects[i];
00544         for (i = 0; library_dirs[i] != NULL; i++)
00545                 gcc_link_args[k++] = (char*) library_dirs[i];
00546         for (i = 0; additional_libs[i] != NULL; i++)
00547                 gcc_link_args[k++] = (char*) additional_libs[i];
00548 
00549 
00550         if (verbose) {
00551                 for (i = 0; i < j; i++) {
00552                         fprintf(stderr, "%s ", gcc_comp_args[i]);
00553                         fflush(stderr);
00554                 }
00555                 fprintf(stderr, "\n\n");
00556         }
00557 
00558         /* compile */
00559         if (!fork()) {
00560                 int error = 0;
00561                 if ((error = execv(gcc_path, gcc_comp_args)) < 0)
00562                         perror(my_app);
00563                 exit(-1);
00564         } else
00565                 wait(&status);
00566 
00567         if (WIFEXITED(status)) {
00568                 if ((error = WEXITSTATUS(status)) < 0)
00569                         goto end;
00570         } else {
00571                 error = -1;
00572                 goto end;
00573         }
00574 
00575         if (verbose) {
00576                 fprintf(stderr, "\n");
00577                 for (i = 0; i < k; i++) {
00578                         fprintf(stderr, "%s ", gcc_link_args[i]);
00579                         fflush(stderr);
00580                 }
00581                 fprintf(stderr, "\n\n");
00582         }
00583 
00584         /* link */
00585         if (!fork()) {
00586                 int error = 0;
00587                 if ((error = execv(gcc_path, gcc_link_args)) < 0)
00588                         perror(my_app);
00589                 exit(-1);
00590         } else
00591                 wait(&status);
00592 
00593         if (WIFEXITED(status))
00594                 error = WEXITSTATUS(status);
00595 
00596  end:
00597         for (i = 0; additional_objects[i] != NULL; i++)
00598                 free(additional_objects[i]);
00599 
00600         if (!keep_c)
00601                 unlink(intermediate_c);
00602         unlink(intermediate_o);
00603 
00604         return error;
00605 }


© 2007, Los Alamos National Security, LLC.