funkalicious 0.1

material_property_args.c

Go to the documentation of this file.
00001 /*
00002 ** material_property_args.c
00003 ** 
00004 ** Made by (Johnny Q. Hacker)
00005 ** Login   <solarion@borkborkbork>
00006 ** 
00007 
00008     Copyright (C) 2009 Joseph Pingenot
00009 
00010     This program is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Affero General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Affero General Public License for more details.
00019 
00020     You should have received a copy of the GNU Affero General Public License
00021     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00022 
00023 ** Started on  Wed Dec  9 13:34:02 2009 Johnny Q. Hacker
00024 ** Last update Sun May 12 01:17:25 2002 Speed Blue
00025 */
00026 
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031 #include <glib-2.0/glib.h>
00032 #include <gio/gio.h>
00033 #include "material_property_args.h"
00034 #include "config.h"
00035 
00036 extern void program_print_version(FILE* f);
00037 extern void libdotcode_print_version(FILE* f);
00038 
00039 #define MATERIAL_PROPERTY_ARGS_DOMAIN 1026
00040 
00041 struct args args = {
00042   .file=NULL,
00043   .property=NULL,
00044   .points = NULL,
00045   .xslices = NULL,
00046   .yslices = NULL,
00047   .zslices = NULL,
00048   .check_cached=TRUE
00049 };
00050 
00051 /*ints is an array of strings (glib's strv) containing ints that we
00052   need to convert into proper ints
00053   *NOTE: ints is freed after this.
00054 */
00055 int* vector_from_ints(char** ints, GError **err) {
00056   /*This little loop looks useless, but it counts the number of
00057     entries (not the termination condition)*/
00058   int i=0;
00059   for(i=0; ints[i] != NULL; i++);
00060   /*And then check the number of entries*/
00061   if(i != 3) {
00062     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 100, "Too %s vector components given (%d; expected %d)", (i<3)?"few":"many", i, 3);
00063     g_strfreev(ints);
00064     return NULL;
00065   }
00066   int* vec = (int*)malloc(3*sizeof(int));
00067   if(vec == NULL) {
00068     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 100, "Failed to allocated storage for 3 ints (the vector)");
00069     g_strfreev(ints);
00070     return NULL;
00071   }
00072   for(i=0; ints[i] != NULL; i++) {
00073     int val=-1;
00074     val = atoi(ints[i]);
00075     #ifdef DEBUG1
00076     fprintf(stderr, "ints[%d]=(%s) val=%d", i, ints[i], val);
00077     #endif
00078     if(val < 0) {
00079       *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 100, "Got an invalid (negative) vector component: %d", val);
00080       free(vec);
00081       g_strfreev(ints);
00082       return NULL;
00083     }
00084     vec[i] = val;
00085   }
00086   g_strfreev(ints);
00087   return vec;
00088 }
00089 
00090 
00091 double* new_double_from_string(const char* s, GError **err) {
00092   double* d = (double*)malloc(sizeof(double));
00093   if(d == NULL) {
00094     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 1, "material_property_args_args.c::new_double_from_string: Error occurred converting string (%s) to double: out of memory/malloc failed", s);
00095     return NULL;
00096   }
00097   char *end;
00098   errno = 0;
00099   *d = strtod(s, &end);
00100   if(((end == s) && (*d == 0)) || (errno != 0)) {
00101     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 2, "material_property_args_args.c::new_double_from_string: Error occurred converting string (%s) to double: %s", s, strerror(errno));
00102     free(d);
00103     return NULL;
00104   }
00105   return d;
00106 }
00107 
00108 int* new_int_from_string(const char* s, GError **err) {
00109   int* d = (int*)malloc(sizeof(int));
00110   if(d == NULL) {
00111     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 1, "material_property_args_args.c::new_int_from_string: Error occurred converting string (%s) to int: out of memory/malloc failed", s);
00112     return NULL;
00113   }
00114   char *end;
00115   errno = 0;
00116   *d = strtod(s, &end);
00117   if(((end == s) && (*d == 0)) || (errno != 0)) {
00118     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 2, "material_property_args_args.c::new_int_from_string: Error occurred converting string (%s) to int: %s", s, strerror(errno));
00119     free(d);
00120     return NULL;
00121   }
00122   return d;
00123 }
00124 
00125 struct args* process_args(int argc, char **argv, GError **err) {
00126   int errored = 0;
00127   gchar **file_names = NULL;
00128   gboolean print_version = FALSE;
00129   gchar** xslices = NULL;
00130   gchar** yslices = NULL;
00131   gchar** zslices = NULL;
00132   gchar** points = NULL;
00133   GOptionEntry options[] = {
00134     { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &file_names,},
00135     { "version", 'v', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &print_version, "Print version information about this program", NULL },
00136     { "parameter", 'p', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING, &(args.property), "Property to be looked up across the structure (point is \"x,y,z\", in gridsites, e.g. -p=3,7,15)", NULL },
00137     { "at", 'a', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &(points), "point at which to output the specified parameter", NULL},
00138     { "xslice", 'X', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &(xslices), "x coordinate (in grid sites) along which to output a 2D map of the property across the slice of the structure", NULL},
00139     { "yslice", 'Y', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &(yslices), "y coordinate (in grid sites) along which to output a 2D map of the property across the slice of the structure", NULL},
00140     { "zslice", 'Z', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &(zslices), "z coordinate (in grid sites) along which to output a 2D map of the property across the slice of the structure", NULL},
00141     {NULL}
00142   };
00143   GOptionContext *ctx;
00144   ctx = g_option_context_new("- output a parameter at given points in the structure");
00145   g_option_context_add_main_entries(ctx, options, "Options");
00146 
00147   g_option_context_parse(ctx, &argc, &argv, NULL);
00148 
00149   args.xslices = NULL;
00150   int *d;
00151   GError *e = NULL;
00152   if(xslices != NULL) {
00153     for(int i=0; xslices[i] != NULL; i++) {
00154       if((d=new_int_from_string(xslices[i], &e)) != NULL) {
00155   args.xslices = g_list_append(args.xslices, d);
00156       }else{
00157   *err = e;
00158   return NULL;
00159       }
00160     }
00161   }
00162   args.yslices = NULL;
00163   e = NULL;
00164   if(yslices != NULL) {
00165     for(int i=0; yslices[i] != NULL; i++) {
00166       if((d=new_int_from_string(yslices[i], &e)) != NULL) {
00167   args.yslices = g_list_append(args.yslices, d);
00168       }else{
00169   *err = e;
00170   return NULL;
00171       }
00172     }
00173   }
00174   args.zslices = NULL;
00175   e = NULL;
00176   if(zslices != NULL) {
00177     for(int i=0; zslices[i] != NULL; i++) {
00178       if((d=new_int_from_string(zslices[i], &e)) != NULL) {
00179   args.zslices = g_list_append(args.zslices, d);
00180       }else{
00181   *err = e;
00182   return NULL;
00183       }
00184     }
00185   }
00186   args.points = NULL;
00187   e = NULL;
00188   int* vec;
00189   if(points != NULL) {
00190     for(int i=0; points[i] != NULL; i++) {
00191       if((vec=vector_from_ints(g_strsplit(points[i], ",", -1), &e)) != NULL) {
00192   args.points = g_list_append(args.points, vec);
00193       }else{
00194   *err = e;
00195   return NULL;
00196       }
00197     }
00198   }
00199   
00200 
00201   gchar* htext = g_option_context_get_help(ctx, FALSE, NULL);
00202   g_option_context_free(ctx);
00203 
00204   args.file = NULL;
00205   if(file_names != NULL) {
00206     if(file_names[1] != NULL) {
00207       *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 101, "more than one grid to process was given!");
00208       errored=1;
00209     }
00210     args.file = g_file_new_for_commandline_arg(file_names[0]);
00211   }
00212   if(args.file == NULL) {
00213     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 101, "You must give a grid to process!");
00214     errored=1;
00215   }
00216 
00217   if(args.property == NULL) {
00218     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 102, "No property was given!");
00219     errored =1;
00220   }
00221 
00222   if(errored){
00223     printf("%s", htext);
00224     printf("\n\n**For version and compilation information, run with --version***");
00225     *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 7, "\n");
00226   }
00227   if(print_version){
00228     program_print_version(stdout);
00229     libdotcode_print_version(stdout);
00230     printf("autotools info:\n\tProject: %s\n\tVersion: %s\n", PACKAGE_NAME, VERSION);
00231     printf("Platform information:\n\tSize of int=%d double=%d\n\tEndianness: %s\n", SIZEOF_INT, SIZEOF_DOUBLE, 
00232 #ifdef WORDS_BIGENDIAN
00233      "big"
00234 #else
00235      "little"
00236 #endif
00237      );
00238     if(*err == NULL) *err = g_error_new(MATERIAL_PROPERTY_ARGS_DOMAIN, 7, "\n");
00239     return NULL;
00240   }
00241   if(errored){
00242     return NULL;
00243   }
00244   return &args;
00245 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines