Mercurial > hg > index.cgi
comparison lwasm/pseudo.c @ 55:bad2ee25acdd
Added string comparison pseudo ops
author | lost@l-w.ca |
---|---|
date | Tue, 05 Apr 2011 23:59:41 -0600 |
parents | c6b8b455d67f |
children | 62372522ce9c |
comparison
equal
deleted
inserted
replaced
54:2077b755b8b4 | 55:bad2ee25acdd |
---|---|
20 */ | 20 */ |
21 | 21 |
22 #include <stdio.h> | 22 #include <stdio.h> |
23 #include <ctype.h> | 23 #include <ctype.h> |
24 #include <string.h> | 24 #include <string.h> |
25 #include <stdlib.h> | |
25 | 26 |
26 #include <lw_alloc.h> | 27 #include <lw_alloc.h> |
27 | 28 |
28 #include "lwasm.h" | 29 #include "lwasm.h" |
29 #include "instab.h" | 30 #include "instab.h" |
1159 for (i = 0; i < l -> len; i++) | 1160 for (i = 0; i < l -> len; i++) |
1160 { | 1161 { |
1161 lwasm_emitexpr(l, e, 1); | 1162 lwasm_emitexpr(l, e, 1); |
1162 } | 1163 } |
1163 } | 1164 } |
1165 | |
1166 /* string conditional argument parser */ | |
1167 /* | |
1168 argument syntax: | |
1169 | |
1170 a bare word ended by whitespace, comma, or NUL | |
1171 a double quote delimited string containing arbitrary printable characters | |
1172 a single quote delimited string containing arbitrary printable characters | |
1173 | |
1174 In a double quoted string, a double quote cannot be represented. | |
1175 In a single quoted string, a single quote cannot be represented. | |
1176 | |
1177 */ | |
1178 char *strcond_parsearg(char **p) | |
1179 { | |
1180 char *arg; | |
1181 char *tstr; | |
1182 int i; | |
1183 tstr = *p; | |
1184 | |
1185 if (!**p || isspace(**p)) | |
1186 { | |
1187 return lw_strdup(""); | |
1188 } | |
1189 | |
1190 if (*tstr == '"') | |
1191 { | |
1192 // double quote delim | |
1193 tstr++; | |
1194 for (i = 0; tstr[i] && tstr[i] != '"'; i++) | |
1195 /* do nothing */ ; | |
1196 | |
1197 arg = lw_alloc(i + 1); | |
1198 strncpy(arg, tstr, i); | |
1199 arg[i] = 0; | |
1200 | |
1201 if (tstr[i]) | |
1202 i++; | |
1203 | |
1204 *p += i; | |
1205 return arg; | |
1206 } | |
1207 else if (*tstr == '\'') | |
1208 { | |
1209 // single quote delim | |
1210 tstr++; | |
1211 for (i = 0; tstr[i] && tstr[i] != '\''; i++) | |
1212 /* do nothing */ ; | |
1213 | |
1214 arg = lw_alloc(i + 1); | |
1215 strncpy(arg, tstr, i); | |
1216 arg[i] = 0; | |
1217 | |
1218 if (tstr[i]) | |
1219 i++; | |
1220 | |
1221 *p += i; | |
1222 return arg; | |
1223 } | |
1224 else | |
1225 { | |
1226 // bare word - whitespace or comma delim | |
1227 for (i = 0; tstr[i] && !isspace(tstr[i]) && tstr[i] != ','; i++) | |
1228 /* do nothing */ ; | |
1229 | |
1230 arg = lw_alloc(i + 1); | |
1231 strncpy(arg, tstr, i); | |
1232 arg[i] = 0; | |
1233 if (tstr[i] == ',') | |
1234 i++; | |
1235 | |
1236 *p += i; | |
1237 return arg; | |
1238 } | |
1239 } | |
1240 | |
1241 /* string conditional helpers */ | |
1242 /* return "1" for true, "0" for false */ | |
1243 int strcond_eq(char **p) | |
1244 { | |
1245 char *arg1; | |
1246 char *arg2; | |
1247 int c = 0; | |
1248 | |
1249 arg1 = strcond_parsearg(p); | |
1250 arg2 = strcond_parsearg(p); | |
1251 | |
1252 if (strcmp(arg1, arg2) == 0) | |
1253 c = 1; | |
1254 lw_free(arg1); | |
1255 lw_free(arg2); | |
1256 return c; | |
1257 } | |
1258 | |
1259 int strcond_ieq(char **p) | |
1260 { | |
1261 char *arg1; | |
1262 char *arg2; | |
1263 int c = 0; | |
1264 | |
1265 arg1 = strcond_parsearg(p); | |
1266 arg2 = strcond_parsearg(p); | |
1267 | |
1268 if (strcasecmp(arg1, arg2) == 0) | |
1269 c = 1; | |
1270 lw_free(arg1); | |
1271 lw_free(arg2); | |
1272 return c; | |
1273 } | |
1274 | |
1275 int strcond_ne(char **p) | |
1276 { | |
1277 char *arg1; | |
1278 char *arg2; | |
1279 int c = 0; | |
1280 | |
1281 arg1 = strcond_parsearg(p); | |
1282 arg2 = strcond_parsearg(p); | |
1283 | |
1284 if (strcmp(arg1, arg2) != 0) | |
1285 c = 1; | |
1286 lw_free(arg1); | |
1287 lw_free(arg2); | |
1288 return c; | |
1289 } | |
1290 | |
1291 int strcond_ine(char **p) | |
1292 { | |
1293 char *arg1; | |
1294 char *arg2; | |
1295 int c = 0; | |
1296 | |
1297 arg1 = strcond_parsearg(p); | |
1298 arg2 = strcond_parsearg(p); | |
1299 | |
1300 if (strcasecmp(arg1, arg2) != 0) | |
1301 c = 1; | |
1302 lw_free(arg1); | |
1303 lw_free(arg2); | |
1304 return c; | |
1305 } | |
1306 | |
1307 int strcond_peq(char **p) | |
1308 { | |
1309 char *arg0; | |
1310 char *arg1; | |
1311 char *arg2; | |
1312 int plen; | |
1313 int c = 0; | |
1314 | |
1315 arg0 = strcond_parsearg(p); | |
1316 arg1 = strcond_parsearg(p); | |
1317 arg2 = strcond_parsearg(p); | |
1318 | |
1319 plen = strtol(arg0, NULL, 10); | |
1320 if (strlen(arg1) > plen) | |
1321 arg1[plen] = 0; | |
1322 if (strlen(arg2) > plen) | |
1323 arg2[plen] = 0; | |
1324 | |
1325 if (strcmp(arg1, arg2) == 0) | |
1326 c = 1; | |
1327 lw_free(arg0); | |
1328 lw_free(arg1); | |
1329 lw_free(arg2); | |
1330 return c; | |
1331 } | |
1332 | |
1333 int strcond_ipeq(char **p) | |
1334 { | |
1335 char *arg0; | |
1336 char *arg1; | |
1337 char *arg2; | |
1338 int plen; | |
1339 int c = 0; | |
1340 | |
1341 arg0 = strcond_parsearg(p); | |
1342 arg1 = strcond_parsearg(p); | |
1343 arg2 = strcond_parsearg(p); | |
1344 | |
1345 plen = strtol(arg0, NULL, 10); | |
1346 if (strlen(arg1) > plen) | |
1347 arg1[plen] = 0; | |
1348 if (strlen(arg2) > plen) | |
1349 arg2[plen] = 0; | |
1350 | |
1351 if (strcasecmp(arg1, arg2) == 0) | |
1352 c = 1; | |
1353 lw_free(arg0); | |
1354 lw_free(arg1); | |
1355 lw_free(arg2); | |
1356 return c; | |
1357 } | |
1358 | |
1359 int strcond_pne(char **p) | |
1360 { | |
1361 char *arg0; | |
1362 char *arg1; | |
1363 char *arg2; | |
1364 int plen; | |
1365 int c = 0; | |
1366 | |
1367 arg0 = strcond_parsearg(p); | |
1368 arg1 = strcond_parsearg(p); | |
1369 arg2 = strcond_parsearg(p); | |
1370 | |
1371 plen = strtol(arg0, NULL, 10); | |
1372 if (strlen(arg1) > plen) | |
1373 arg1[plen] = 0; | |
1374 if (strlen(arg2) > plen) | |
1375 arg2[plen] = 0; | |
1376 | |
1377 if (strcmp(arg1, arg2) != 0) | |
1378 c = 1; | |
1379 lw_free(arg0); | |
1380 lw_free(arg1); | |
1381 lw_free(arg2); | |
1382 return c; | |
1383 } | |
1384 | |
1385 int strcond_ipne(char **p) | |
1386 { | |
1387 char *arg0; | |
1388 char *arg1; | |
1389 char *arg2; | |
1390 int plen; | |
1391 int c = 0; | |
1392 | |
1393 arg0 = strcond_parsearg(p); | |
1394 arg1 = strcond_parsearg(p); | |
1395 arg2 = strcond_parsearg(p); | |
1396 | |
1397 plen = strtol(arg0, NULL, 10); | |
1398 if (strlen(arg1) > plen) | |
1399 arg1[plen] = 0; | |
1400 if (strlen(arg2) > plen) | |
1401 arg2[plen] = 0; | |
1402 | |
1403 if (strcasecmp(arg1, arg2) != 0) | |
1404 c = 1; | |
1405 lw_free(arg0); | |
1406 lw_free(arg1); | |
1407 lw_free(arg2); | |
1408 return c; | |
1409 } | |
1410 | |
1411 int strcond_seq(char **p) | |
1412 { | |
1413 char *arg0; | |
1414 char *arg1; | |
1415 char *arg2; | |
1416 char *rarg1; | |
1417 char *rarg2; | |
1418 | |
1419 int plen; | |
1420 int c = 0; | |
1421 | |
1422 arg0 = strcond_parsearg(p); | |
1423 arg1 = strcond_parsearg(p); | |
1424 arg2 = strcond_parsearg(p); | |
1425 | |
1426 rarg1 = arg1; | |
1427 rarg2 = arg2; | |
1428 | |
1429 plen = strtol(arg0, NULL, 10); | |
1430 if (strlen(arg1) > plen) | |
1431 { | |
1432 rarg1 += strlen(arg1) - plen; | |
1433 } | |
1434 if (strlen(arg2) > plen) | |
1435 { | |
1436 rarg2 += strlen(arg2) - plen; | |
1437 } | |
1438 if (strcmp(rarg1, rarg2) == 0) | |
1439 c = 1; | |
1440 lw_free(arg0); | |
1441 lw_free(arg1); | |
1442 lw_free(arg2); | |
1443 return c; | |
1444 } | |
1445 | |
1446 int strcond_iseq(char **p) | |
1447 { | |
1448 char *arg0; | |
1449 char *arg1; | |
1450 char *arg2; | |
1451 char *rarg1; | |
1452 char *rarg2; | |
1453 | |
1454 int plen; | |
1455 int c = 0; | |
1456 | |
1457 arg0 = strcond_parsearg(p); | |
1458 arg1 = strcond_parsearg(p); | |
1459 arg2 = strcond_parsearg(p); | |
1460 | |
1461 rarg1 = arg1; | |
1462 rarg2 = arg2; | |
1463 | |
1464 plen = strtol(arg0, NULL, 10); | |
1465 if (strlen(arg1) > plen) | |
1466 { | |
1467 rarg1 += strlen(arg1) - plen; | |
1468 } | |
1469 if (strlen(arg2) > plen) | |
1470 { | |
1471 rarg2 += strlen(arg2) - plen; | |
1472 } | |
1473 | |
1474 if (strcasecmp(rarg1, rarg2) == 0) | |
1475 c = 1; | |
1476 lw_free(arg0); | |
1477 lw_free(arg1); | |
1478 lw_free(arg2); | |
1479 return c; | |
1480 } | |
1481 | |
1482 | |
1483 int strcond_sne(char **p) | |
1484 { | |
1485 char *arg0; | |
1486 char *arg1; | |
1487 char *arg2; | |
1488 char *rarg1; | |
1489 char *rarg2; | |
1490 | |
1491 int plen; | |
1492 int c = 0; | |
1493 | |
1494 arg0 = strcond_parsearg(p); | |
1495 arg1 = strcond_parsearg(p); | |
1496 arg2 = strcond_parsearg(p); | |
1497 | |
1498 rarg1 = arg1; | |
1499 rarg2 = arg2; | |
1500 | |
1501 plen = strtol(arg0, NULL, 10); | |
1502 if (strlen(arg1) > plen) | |
1503 { | |
1504 rarg1 += strlen(arg1) - plen; | |
1505 } | |
1506 if (strlen(arg2) > plen) | |
1507 { | |
1508 rarg2 += strlen(arg2) - plen; | |
1509 } | |
1510 | |
1511 if (strcmp(rarg1, rarg2) != 0) | |
1512 c = 1; | |
1513 lw_free(arg0); | |
1514 lw_free(arg1); | |
1515 lw_free(arg2); | |
1516 return c; | |
1517 } | |
1518 | |
1519 int strcond_isne(char **p) | |
1520 { | |
1521 char *arg0; | |
1522 char *arg1; | |
1523 char *arg2; | |
1524 char *rarg1; | |
1525 char *rarg2; | |
1526 | |
1527 int plen; | |
1528 int c = 0; | |
1529 | |
1530 arg0 = strcond_parsearg(p); | |
1531 arg1 = strcond_parsearg(p); | |
1532 arg2 = strcond_parsearg(p); | |
1533 | |
1534 rarg1 = arg1; | |
1535 rarg2 = arg2; | |
1536 | |
1537 plen = strtol(arg0, NULL, 10); | |
1538 if (strlen(arg1) > plen) | |
1539 { | |
1540 rarg1 += strlen(arg1) - plen; | |
1541 } | |
1542 if (strlen(arg2) > plen) | |
1543 { | |
1544 rarg2 += strlen(arg2) - plen; | |
1545 } | |
1546 | |
1547 if (strcasecmp(rarg1, rarg2) != 0) | |
1548 c = 1; | |
1549 lw_free(arg0); | |
1550 lw_free(arg1); | |
1551 lw_free(arg2); | |
1552 return c; | |
1553 } | |
1554 | |
1555 /* string conditionals */ | |
1556 PARSEFUNC(pseudo_parse_ifstr) | |
1557 { | |
1558 static struct strconds | |
1559 { | |
1560 char *str; | |
1561 int (*fn)(char **ptr); | |
1562 } strops[] = { | |
1563 { "eq", strcond_eq }, | |
1564 { "ieq", strcond_ieq }, | |
1565 { "ne", strcond_ne }, | |
1566 { "ine", strcond_ine }, | |
1567 { "peq", strcond_peq }, | |
1568 { "ipeq", strcond_ipeq }, | |
1569 { "pne", strcond_pne }, | |
1570 { "ipne", strcond_ipne }, | |
1571 { "seq", strcond_seq }, | |
1572 { "iseq", strcond_iseq }, | |
1573 { "sne", strcond_sne }, | |
1574 { "isne", strcond_isne }, | |
1575 { NULL, 0 } | |
1576 }; | |
1577 int tv = 0; | |
1578 char *tstr; | |
1579 int i, strop; | |
1580 | |
1581 l -> len = 0; | |
1582 | |
1583 if (as -> skipcond && !(as -> skipmacro)) | |
1584 { | |
1585 as -> skipcount++; | |
1586 skip_operand(p); | |
1587 return; | |
1588 } | |
1589 | |
1590 tstr = strcond_parsearg(p); | |
1591 if (!**p || isspace(**p)) | |
1592 { | |
1593 lwasm_register_error(as, l, "Bad string condition"); | |
1594 return; | |
1595 } | |
1596 | |
1597 for (strop = 0; strops[strop].str != NULL; strop++) | |
1598 if (strcasecmp(strops[strop].str, tstr) == 0) | |
1599 break; | |
1600 | |
1601 lw_free(tstr); | |
1602 | |
1603 if (strops[strop].str == NULL) | |
1604 { | |
1605 lwasm_register_error(as, l, "Bad string condition"); | |
1606 } | |
1607 | |
1608 tv = (*(strops[strop].fn))(p); | |
1609 | |
1610 if (!tv) | |
1611 { | |
1612 as -> skipcond = 1; | |
1613 as -> skipcount = 1; | |
1614 } | |
1615 } |