00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdarg.h>
00014
00015 #include "posemath.h"
00016 #include "mathprnt.h"
00017
00018
00019
00020
00021 static char *END(char *s)
00022 {
00023 return &s[strlen(s)];
00024 }
00025
00026 static int ft_string(char *string, char *from, char *to)
00027 {
00028 int count;
00029
00030 count = to - from + 1;
00031 if (count > 256)
00032 {
00033 printf("ft_string: String segment too long!\n");
00034 return -1;
00035 }
00036
00037 if (count < 0)
00038 {
00039 printf("ft_string: End pointer less than start pointer.\n");
00040 return -1;
00041 }
00042
00043 strncpy(string, from, count);
00044 *(string + count) = '\0';
00045
00046 return 0;
00047 }
00048
00049 static int _pmSprintf(char *string, const char *f, va_list ap)
00050 {
00051 char *format;
00052 char *ptr;
00053 char *conv_ptr;
00054 enum { SCAN, CONV, DONE } state;
00055 char fmt[256], fmt2[256];
00056
00057 format = (char *) f;
00058
00059
00060 state = SCAN;
00061 ptr = format;
00062 conv_ptr = format;
00063 *string = '\0';
00064
00065 while (state != DONE)
00066 {
00067 switch (state)
00068 {
00069 case SCAN:
00070 switch (*ptr)
00071 {
00072 case '%':
00073 conv_ptr = ptr;
00074 state = CONV;
00075 break;
00076
00077 case '\0':
00078 sprintf(END(string), format);
00079 state = DONE;
00080 break;
00081 }
00082 break;
00083
00084 case CONV:
00085 switch (*ptr)
00086 {
00087 case '%':
00088 state = SCAN;
00089 break;
00090
00091 case 'd':
00092 case 'o':
00093 case 'x':
00094 case 'u':
00095 ft_string(fmt, format, ptr);
00096 sprintf(END(string), fmt, va_arg(ap, int));
00097 format = ptr + 1;
00098 state = SCAN;
00099 break;
00100
00101 case 'e':
00102 case 'f':
00103 case 'g':
00104 ft_string(fmt, format, ptr);
00105 sprintf(END(string), fmt, va_arg(ap, double));
00106 format = ptr + 1;
00107 state = SCAN;
00108 break;
00109
00110 case 'c':
00111 ft_string(fmt, format, ptr);
00112 sprintf(END(string), fmt, va_arg(ap, int));
00113 format = ptr + 1;
00114 state = SCAN;
00115 break;
00116
00117 case 's':
00118 case 'b':
00119 ft_string(fmt, format, ptr);
00120 sprintf(END(string), fmt, va_arg(ap, char *));
00121 format = ptr + 1;
00122 state = SCAN;
00123 break;
00124
00125 case 'v':
00126 ft_string(fmt, format, conv_ptr - 1);
00127 sprintf(END(string), fmt);
00128 {
00129 PmCartesian vector;
00130
00131 vector = va_arg(ap, PmCartesian);
00132 ft_string(fmt, conv_ptr, ptr - 1);
00133 sprintf(fmt2, "%sf %sf %sf", fmt, fmt, fmt);
00134 sprintf(END(string), fmt2, vector.x, vector.y, vector.z);
00135 }
00136 format = ptr + 1;
00137 state = SCAN;
00138 break;
00139
00140 case 'q':
00141 ft_string(fmt, format, conv_ptr - 1);
00142 sprintf(END(string), fmt);
00143 {
00144 PmQuaternion quat;
00145
00146 quat = va_arg(ap, PmQuaternion);
00147 ft_string(fmt, conv_ptr, ptr - 1);
00148 sprintf(fmt2, "%sf %sf %sf %sf", fmt, fmt, fmt, fmt);
00149 sprintf(END(string), fmt2, quat.s, quat.x, quat.y, quat.z);
00150 }
00151 format = ptr + 1;
00152 state = SCAN;
00153 break;
00154
00155 case 'Q':
00156 ft_string(fmt, format, conv_ptr - 1);
00157 sprintf(END(string), fmt);
00158 {
00159 PmQuaternion quat;
00160 PmRotationMatrix mat;
00161
00162 quat = va_arg(ap, PmQuaternion);
00163 ft_string(fmt, conv_ptr, ptr - 1);
00164 pmQuatMatConvert(quat, &mat);
00165 sprintf(fmt2, "\n%sf %sf %sf", fmt, fmt, fmt);
00166 sprintf(END(string), fmt2, mat.x.x, mat.y.x, mat.z.x);
00167 sprintf(END(string), fmt2, mat.x.y, mat.y.y, mat.z.y);
00168 sprintf(END(string), fmt2, mat.x.z, mat.y.z, mat.z.z);
00169 }
00170 format = ptr + 1;
00171 state = SCAN;
00172 break;
00173
00174 case 'm':
00175 ft_string(fmt, format, conv_ptr - 1);
00176 sprintf(END(string), fmt);
00177 {
00178 PmRotationMatrix mat;
00179
00180 mat = va_arg(ap, PmRotationMatrix);
00181 ft_string(fmt, conv_ptr, ptr - 1);
00182 sprintf(fmt2, "\n%sf %sf %sf ", fmt, fmt, fmt);
00183 sprintf(END(string), fmt2, mat.x.x, mat.y.x, mat.z.x);
00184 sprintf(END(string), fmt2, mat.x.y, mat.y.y, mat.z.y);
00185 sprintf(END(string), fmt2, mat.x.z, mat.y.z, mat.z.z);
00186 }
00187 format = ptr + 1;
00188 state = SCAN;
00189 break;
00190
00191 case 'p':
00192 ft_string(fmt, format, conv_ptr - 1);
00193 sprintf(END(string), fmt);
00194 {
00195 PmPose pose;
00196
00197 pose = va_arg(ap, PmPose);
00198 ft_string(fmt, conv_ptr, ptr - 1);
00199 sprintf(fmt2, "%sf %sf %sf %sf %sf %sf %sf",
00200 fmt, fmt, fmt, fmt, fmt, fmt, fmt);
00201 sprintf(END(string), fmt2,
00202 pose.tran.x, pose.tran.y, pose.tran.z,
00203 pose.rot.s, pose.rot.x, pose.rot.y, pose.rot.z);
00204
00205 }
00206 format = ptr + 1;
00207 state = SCAN;
00208 break;
00209
00210 case 'P':
00211 ft_string(fmt, format, conv_ptr - 1);
00212 sprintf(END(string), fmt);
00213 {
00214 PmPose pose;
00215 PmRotationMatrix mat;
00216
00217 pose = va_arg(ap, PmPose);
00218 ft_string(fmt, conv_ptr, ptr - 1);
00219 pmQuatMatConvert(pose.rot, &mat);
00220 sprintf(fmt2, "\n%sf %sf %sf %sf", fmt, fmt, fmt, fmt);
00221 sprintf(END(string), fmt2, mat.x.x, mat.y.x, mat.z.x,
00222 pose.tran.x);
00223 sprintf(END(string), fmt2, mat.x.y, mat.y.y, mat.z.y,
00224 pose.tran.y);
00225 sprintf(END(string), fmt2, mat.x.z, mat.y.z, mat.z.z,
00226 pose.tran.z);
00227 }
00228 format = ptr + 1;
00229 state = SCAN;
00230 break;
00231
00232 case '-':
00233 case '+':
00234 case ' ':
00235 case '#':
00236 case '.':
00237 case 'l':
00238 case '0':
00239 case '1':
00240 case '2':
00241 case '3':
00242 case '4':
00243 case '5':
00244 case '6':
00245 case '7':
00246 case '8':
00247 case '9':
00248 break;
00249
00250 default:
00251 printf("Invalid conversion specification: %s\n", format);
00252 return -1;
00253 }
00254 break;
00255
00256 default:
00257 printf("Programming error in math_sprintf.\n");
00258 return -1;
00259 }
00260 ptr++;
00261 }
00262 return 0;
00263 }
00264
00265 void pmSprintf(char *string, const char *fmt, ...)
00266 {
00267 va_list ap;
00268
00269 va_start(ap, fmt);
00270 _pmSprintf(string, fmt, ap);
00271 va_end(ap);
00272 }
00273
00274 void pmPrintf(const char *fmt, ...)
00275 {
00276 va_list ap;
00277 char string[512];
00278
00279 va_start(ap, fmt);
00280 _pmSprintf(string, fmt, ap);
00281 printf("%s", string);
00282 va_end(ap);
00283 }
00284
00285 void pmFprintf(FILE *fp, const char *fmt, ...)
00286 {
00287 va_list ap;
00288 char string[512];
00289
00290 va_start(ap, fmt);
00291 _pmSprintf(string, fmt, ap);
00292 fprintf(fp, "%s", string);
00293 va_end(ap);
00294 }