|
funkalicious 0.1
|
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 }