00001 /* persist -- Persistent Storage Management 00002 Copyright 2001, 2002 Free Software Foundation, Inc. 00003 Written by Stephane Carrez (stcarrez@nerim.fr) 00004 00005 This file is part of GEL. 00006 00007 GEL is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2, or (at your option) 00010 any later version. 00011 00012 GEL is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with GEL; see the file COPYING. If not, write to 00019 the Free Software Foundation, 59 Temple Place - Suite 330, 00020 Boston, MA 02111-1307, USA. */ 00021 00033 #include "persist.h" 00034 #include <sys/sio.h> 00035 #include <stdarg.h> 00036 #include <time.h> 00037 #include <stdio.h> 00038 00039 inline void 00040 print (const char* msg) 00041 { 00042 serial_print (msg); 00043 } 00044 00045 typedef char country[20]; 00046 typedef char name[12]; 00047 typedef char address[32]; 00048 typedef char buf[64]; 00049 00050 typedef union 00051 { 00052 name u_name; 00053 address u_address; 00054 country u_country; 00055 buf u_buf; 00056 } u_str; 00057 00058 typedef persistent<char> p_char_t; 00059 typedef persistent<short> p_short_t; 00060 typedef persistent<long> p_long_t; 00061 typedef persistent<name> p_name_t; 00062 typedef persistent<country> p_country_t; 00063 typedef persistent<address> p_address_t; 00064 00065 typedef enum 00066 { 00067 P_NAME, 00068 P_FIRSTNAME, 00069 P_ADDRESS, 00070 P_COUNTRY, 00071 P_NUM, 00072 P_AGE, 00073 P_UPDATE_COUNT 00074 } pids_t; 00075 00076 volatile char __counter; 00077 00078 void* 00079 operator new (size_t len) 00080 { 00081 printf ("new called"); 00082 return 0; 00083 } 00084 00085 void 00086 operator delete (void *ptr) 00087 { 00088 ; 00089 } 00090 00091 void 00092 print_array (const char *p, size_t len) 00093 { 00094 while (*p && len) 00095 { 00096 printf ("%c", *p++); 00097 len--; 00098 } 00099 } 00100 00101 void 00102 print_id () 00103 { 00104 p_name_t p_name (P_NAME); 00105 p_name_t p_first_name (P_FIRSTNAME); 00106 00107 printf ("\nHello "); 00108 print_array (p_first_name, sizeof (name)); 00109 printf (" "); 00110 print_array (p_name, sizeof (name)); 00111 printf ("!\n"); 00112 } 00113 00114 typedef enum 00115 { 00116 OP_NAME, 00117 OP_FIRSTNAME, 00118 OP_ADDRESS, 00119 OP_COUNTRY, 00120 OP_NUM, 00121 OP_AGE, 00122 OP_QUIT, 00123 OP_LIST, 00124 OP_HELP 00125 }; 00126 00127 typedef struct command 00128 { 00129 const char *name; 00130 int type; 00131 const char *help; 00132 } command; 00133 00134 /* List of commands with a description string. */ 00135 static const command commands[] = { 00136 { 00137 "name", 00138 OP_NAME, 00139 "Set the name" 00140 } , { 00141 "firstname", 00142 OP_FIRSTNAME, 00143 "Set the first name" 00144 } , { 00145 "address", 00146 OP_ADDRESS, 00147 "Set the address" 00148 } , { 00149 "country", 00150 OP_COUNTRY, 00151 "Set the country" 00152 } , { 00153 "Number", 00154 OP_NUM, 00155 "Set the number" 00156 } , { 00157 "Age", 00158 OP_AGE, 00159 "Set the age" 00160 } , { 00161 "quit", 00162 OP_QUIT, 00163 "Quit the calculator" 00164 } , { 00165 "print", 00166 OP_LIST, 00167 "Print the information" 00168 } , { 00169 "help", 00170 OP_HELP, 00171 "This help" 00172 } , { 00173 0, 00174 0, 00175 0 00176 } 00177 }; 00178 00179 00180 /* Implementation of some libc methods. */ 00181 int 00182 strcmp (const char* s1, const char* s2) 00183 { 00184 while (*s1 && (*s1 == *s2)) 00185 s1++, s2++; 00186 00187 return *s1 - *s2; 00188 } 00189 00190 /* Try to translate a string into a number. We look first for hexadecimal 00191 format, octal and then decimal. If the string could be converted, the 00192 value is returned in `v' and the function returns 0. Otherwise, it 00193 returns -1. */ 00194 int 00195 get_value(const char* buf, long* v) 00196 { 00197 long value = 0; 00198 char c; 00199 00200 if (!(*buf >= '0' && *buf <= '9')) 00201 return -1; 00202 00203 /* Translate an hexadecimal value. */ 00204 if (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')) 00205 { 00206 buf += 2; 00207 while ((c = *buf++)) 00208 { 00209 if (c >= '0' && c <= '9') 00210 c = c - '0'; 00211 else if (c >= 'a' && c <= 'f') 00212 c = c - 'a' + 10; 00213 else if (c >= 'A' && c <= 'F') 00214 c = c - 'A' + 10; 00215 else 00216 return -1; 00217 00218 value = (value << 4) | (long) ((unsigned) c); 00219 } 00220 *v = value; 00221 return 0; 00222 } 00223 else 00224 { 00225 int sign = 0; 00226 00227 if (buf[0] == '-') 00228 { 00229 sign = 1; 00230 buf++; 00231 } 00232 while ((c = *buf++) != 0) 00233 { 00234 if (c >= '0' && c <= '9') 00235 c = c - '0'; 00236 else 00237 return -1; 00238 00239 value = (value * 10) + (long) c; 00240 } 00241 if (sign) 00242 value = -value; 00243 *v = value; 00244 return 0; 00245 } 00246 return -1; 00247 } 00248 00249 /* Busy loop to wait for a command or a valid number. */ 00250 void 00251 cmd_get_string (char *buf) 00252 { 00253 int pos; 00254 char c; 00255 00256 while (1) 00257 { 00258 pos = 0; 00259 while (1) 00260 { 00261 c = serial_recv (); 00262 if (c == '\r' || c == '\n') 00263 break; 00264 00265 if (c == '\b') 00266 { 00267 printf ("\b \b"); 00268 pos--; 00269 if (pos < 0) 00270 pos = 0; 00271 } 00272 else 00273 { 00274 buf[pos] = c; 00275 buf[pos+1] = 0; 00276 printf (&buf[pos]); 00277 pos++; 00278 } 00279 } 00280 00281 printf ("\n"); 00282 buf[pos] = 0; 00283 break; 00284 } 00285 } 00286 00287 static void 00288 print_help() 00289 { 00290 int i; 00291 00292 for (i = 0; commands[i].name; i++) 00293 { 00294 if (commands[i].help == 0) 00295 continue; 00296 00297 printf ("%s\t", commands[i].name); 00298 printf ("%s\n", commands[i].help); 00299 } 00300 } 00301 00302 static name def_name = "Joe"; 00303 static name def_first_name = "Dalton"; 00304 static country def_country = "USA"; 00305 static address def_address = "Citizen bank avenue, Red City"; 00306 00307 int 00308 cmd_loop() 00309 { 00310 int i; 00311 long val; 00312 u_str buf; 00313 00314 // Build persistent objects. 00315 p_name_t p_name (P_NAME, def_name); 00316 p_name_t p_firstname (P_FIRSTNAME, def_first_name); 00317 p_address_t p_address (P_ADDRESS, def_address); 00318 p_country_t p_country (P_COUNTRY, def_country); 00319 p_long_t p_num (P_NUM, 0); 00320 p_long_t p_age (P_AGE, 0); 00321 p_long_t p_update_count (P_UPDATE_COUNT, 0); 00322 00323 print_help (); 00324 while (1) 00325 { 00326 print_id (); 00327 00328 cmd_get_string (buf.u_buf); 00329 for (i = 0; commands[i].name; i++) 00330 if (strcmp (commands[i].name, buf.u_buf) == 0) 00331 break; 00332 00333 if (commands[i].name == 0) 00334 continue; 00335 00336 if (commands[i].type == OP_QUIT) 00337 return 0; 00338 else if (commands[i].type == OP_HELP) 00339 { 00340 print_help (); 00341 continue; 00342 } 00343 else if (commands[i].type == OP_LIST) 00344 { 00345 printf ("Name : "); 00346 print_array (p_name, sizeof (name)); 00347 printf ("\nFirst name : "); 00348 print_array (p_firstname, sizeof (name)); 00349 printf ("\nAddress : %ld, ", (long) p_num); 00350 print_array (p_address, sizeof (address)); 00351 printf ("\nCountry : "); 00352 print_array (p_country, sizeof (country)); 00353 printf ("\nAge : %ld", (long) p_age); 00354 printf ("\nUpdate count : %ld\n", (long) p_update_count); 00355 continue; 00356 } 00357 printf ("New value for %s :", (const char*) commands[i].name); 00358 cmd_get_string (buf.u_buf); 00359 00360 switch (commands[i].type) 00361 { 00362 case OP_NAME: 00363 p_name = buf.u_name; 00364 break; 00365 00366 case OP_FIRSTNAME: 00367 p_firstname = buf.u_name; 00368 break; 00369 00370 case OP_ADDRESS: 00371 p_address = buf.u_address; 00372 break; 00373 00374 case OP_COUNTRY: 00375 p_country = buf.u_country; 00376 break; 00377 00378 case OP_NUM: 00379 if (get_value (buf.u_buf, &val) == 0) 00380 { 00381 p_num = val; 00382 } 00383 break; 00384 00385 case OP_AGE: 00386 if (get_value (buf.u_buf, &val) == 0) 00387 { 00388 p_age = val; 00389 } 00390 break; 00391 } 00392 p_update_count++; 00393 } 00394 } 00395 00396 int 00397 main() 00398 { 00399 serial_init (); 00400 00401 printf ("Simple Persistence Test Program\n"); 00402 cmd_loop (); 00403 return 0; 00404 }