1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* //device/tools/dmtracedump/CreateTrace.c 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** Copyright 2006, The Android Open Source Project 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 5de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** Licensed under the Apache License, Version 2.0 (the "License"); 6de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** you may not use this file except in compliance with the License. 7de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 9de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 11de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** Unless required by applicable law or agreed to in writing, software 12de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** distributed under the License is distributed on an "AS IS" BASIS, 13de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a test file in the format required by dmtrace. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NOT_VM 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Profile.h" // from VM header 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <assert.h> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/time.h> 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <ctype.h> 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Values from the header of the data file. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DataHeader { 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int magic; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short version; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short offsetToData; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long startWhen; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DataHeader; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define VERSION 2 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint versionNumber = VERSION; 474d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipinceint verbose = 0; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDataHeader header = { 0x574f4c53, VERSION, sizeof(DataHeader), 0LL }; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *versionHeader = "*version\n"; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *clockDef = "clock=thread-cpu\n"; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *keyThreads = 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"*threads\n" 564d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince"1 main\n" 574d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince"2 foo\n" 584d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince"3 bar\n" 594d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince"4 blah\n"; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *keyEnd = "*end\n"; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct dataRecord { 644d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince unsigned int time; 654d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince int threadId; 664d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince unsigned int action; /* 0=entry, 1=exit, 2=exception exit */ 674d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *fullName; 684d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *className; 694d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *methodName; 704d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *signature; 714d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince unsigned int methodId; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} dataRecord; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectdataRecord *records; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BUF_SIZE 1024 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar buf[BUF_SIZE]; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct stack { 804d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince dataRecord **frames; 814d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince int indentLevel; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} stack; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Mac OS doesn't have strndup(), so implement it here. 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *strndup(const char *src, size_t len) 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *dest = (char *) malloc(len + 1); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strncpy(dest, src, len); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest[len] = 0; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dest; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the input file. It looks something like this: 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * # This is a comment line 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4 1 A 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 6 1 B 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8 1 B 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10 1 A 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * where the first column is the time, the second column is the thread id, 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and the third column is the method (actually just the class name). The 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * number of spaces between the 2nd and 3rd columns is the indentation and 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * determines the call stack. Each called method must be indented by one 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * more space. In the example above, A is called at time 4, A calls B at 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * time 6, B returns at time 8, and A returns at time 10. Thread 1 is the 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only thread that is running. 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An alternative file format leaves out the first two columns: 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * B 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * B 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In this file format, the thread id is always 1, and the time starts at 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2 and increments by 2 for each line. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid parseInputFile(const char *inputFileName) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int time = 0, threadId; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int linenum = 0; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextRecord = 0; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int indentLevel = 0; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack *callStack; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *inputFp = fopen(inputFileName, "r"); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (inputFp == NULL) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perror(inputFileName); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the number of lines in the buffer */ 1354d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince int numRecords = 0; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxThreadId = 1; 1374d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince int maxFrames = 0; 1384d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *indentEnd; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (fgets(buf, BUF_SIZE, inputFp)) { 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *cp = buf; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*cp == '#') 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1434d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince numRecords += 1; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isdigit(*cp)) { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int time = strtoul(cp, &cp, 0); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (isspace(*cp)) 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId = strtoul(cp, &cp, 0); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxThreadId < threadId) 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxThreadId = threadId; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1524d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince indentEnd = cp; 1534d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince while (isspace(*indentEnd)) 1544d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince indentEnd += 1; 1554d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (indentEnd - cp + 1 > maxFrames) 1564d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince maxFrames = indentEnd - cp + 1; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numThreads = maxThreadId + 1; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Add space for a sentinel record at the end */ 1614d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince numRecords += 1; 1624d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince records = (dataRecord *) malloc(sizeof(dataRecord) * numRecords); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project callStack = (stack *) malloc(sizeof(stack) * numThreads); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numThreads; ++ii) { 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project callStack[ii].frames = NULL; 1674d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince callStack[ii].indentLevel = 0; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rewind(inputFp); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (fgets(buf, BUF_SIZE, inputFp)) { 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int indent; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int action; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *save_cp; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project linenum += 1; 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *cp = buf; 1784d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip lines that start with '#' */ 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*cp == '#') 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1824d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince 1834d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince /* Get time and thread id */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isdigit(*cp)) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the line does not begin with a digit, then fill in 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * default values for the time and threadId. 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project time += 2; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadId = 1; 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project time = strtoul(cp, &cp, 0); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (isspace(*cp)) 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadId = strtoul(cp, &cp, 0); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Allocate space for the thread stack, if necessary 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (callStack[threadId].frames == NULL) { 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataRecord **stk; 2014d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince stk = (dataRecord **) malloc(sizeof(dataRecord *) * maxFrames); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project callStack[threadId].frames = stk; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indentLevel = callStack[threadId].indentLevel; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project save_cp = cp; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (isspace(*cp)) { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indent = cp - save_cp + 1; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].time = time; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].threadId = threadId; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project save_cp = cp; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*cp != '\n') 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 217de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Remove trailing spaces */ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp -= 1; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (isspace(*cp)) 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp -= 1; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += 1; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = cp - save_cp; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].fullName = strndup(save_cp, len); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Parse the name to support "class.method signature" */ 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].className = NULL; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].methodName = NULL; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].signature = NULL; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(save_cp, '.'); 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp) { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = cp - save_cp; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len > 0) 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].className = strndup(save_cp, len); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project save_cp = cp + 1; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(save_cp, ' '); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp == NULL) 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(save_cp, '\n'); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp && cp > save_cp) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = cp - save_cp; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].methodName = strndup(save_cp, len); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project save_cp = cp + 1; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(save_cp, ' '); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp == NULL) 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = strchr(save_cp, '\n'); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cp && cp > save_cp) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = cp - save_cp; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].signature = strndup(save_cp, len); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2534d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (verbose) { 2544d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf("Indent: %d; IndentLevel: %d; Line: %s", indent, indentLevel, buf); 2554d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince } 2564d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = 0; 2584d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (indent == indentLevel + 1) { // Entering a method 2594d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (verbose) 2604d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf(" Entering %s\n", records[nextRecord].fullName); 2614d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince callStack[threadId].frames[indentLevel] = &records[nextRecord]; 2624d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince } else if (indent == indentLevel) { // Exiting a method 2634d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince // Exiting method must be currently on top of stack (unless stack is empty) 2644d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (callStack[threadId].frames[indentLevel - 1] == NULL) { 2654d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (verbose) 2664d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf(" Exiting %s (past bottom of stack)\n", records[nextRecord].fullName); 2674d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince callStack[threadId].frames[indentLevel - 1] = &records[nextRecord]; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = 1; 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2704d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (indentLevel < 1) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Error: line %d: %s", linenum, buf); 2724d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(stderr, " expected positive (>0) indentation, found %d\n", 2734d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince indent); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2764d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince char *name = callStack[threadId].frames[indentLevel - 1]->fullName; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(name, records[nextRecord].fullName) == 0) { 2784d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (verbose) 2794d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf(" Exiting %s\n", name); 2804d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince action = 1; 2814d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince } else { // exiting method doesn't match stack's top method 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Error: line %d: %s", linenum, buf); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " expected exit from %s\n", 2844d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince callStack[threadId].frames[indentLevel - 1]->fullName); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nextRecord != 0) { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Error: line %d: %s", linenum, buf); 2914d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(stderr, " expected indentation %d [+1], found %d\n", 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indentLevel, indent); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2964d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince if (verbose) { 2974d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf(" Nonzero indent at first record\n"); 2984d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince printf(" Entering %s\n", records[nextRecord].fullName); 2994d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince } 3004d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This is the first line of data, so we allow a larger 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // initial indent. This allows us to test popping off more 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // frames than we entered. 3044d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince indentLevel = indent - 1; 3054d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince callStack[threadId].frames[indentLevel] = &records[nextRecord]; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3074d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action == 0) 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indentLevel += 1; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indentLevel -= 1; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project records[nextRecord].action = action; 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project callStack[threadId].indentLevel = indentLevel; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextRecord += 1; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Mark the last record with a sentinel */ 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&records[nextRecord], 0, sizeof(dataRecord)); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Write values to the binary data file. 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid write2LE(FILE* fp, unsigned short val) 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc(val & 0xff, fp); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc(val >> 8, fp); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid write4LE(FILE* fp, unsigned int val) 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc(val & 0xff, fp); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 8) & 0xff, fp); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 16) & 0xff, fp); 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 24) & 0xff, fp); 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid write8LE(FILE* fp, unsigned long long val) 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc(val & 0xff, fp); 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 8) & 0xff, fp); 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 16) & 0xff, fp); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 24) & 0xff, fp); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 32) & 0xff, fp); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 40) & 0xff, fp); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 48) & 0xff, fp); 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc((val >> 56) & 0xff, fp); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeDataRecord(FILE *dataFp, int threadId, unsigned int methodVal, 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int elapsedTime) 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (versionNumber == 1) 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project putc(threadId, dataFp); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write2LE(dataFp, threadId); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write4LE(dataFp, methodVal); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write4LE(dataFp, elapsedTime); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeDataHeader(FILE *dataFp) 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timeval tv; 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timezone tz; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gettimeofday(&tv, &tz); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned long long startTime = tv.tv_sec; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startTime = (startTime << 32) | tv.tv_usec; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project header.version = versionNumber; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write4LE(dataFp, header.magic); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write2LE(dataFp, header.version); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write2LE(dataFp, header.offsetToData); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project write8LE(dataFp, startTime); 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeKeyMethods(FILE *keyFp) 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataRecord *pRecord, *pNext; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *methodStr = "*methods\n"; 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fwrite(methodStr, strlen(methodStr), 1, keyFp); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Assign method ids in multiples of 4 */ 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId = 0; 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pRecord = records; pRecord->fullName; ++pRecord) { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pRecord->methodId) 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id = ++methodId << 2; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodId = id; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Assign this id to all the other records that have the 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * same name. 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pNext = pRecord + 1; pNext->fullName; ++pNext) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pNext->methodId) 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pRecord->fullName, pNext->fullName) == 0) 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pNext->methodId = id; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pRecord->className == NULL || pRecord->methodName == NULL) { 4024d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(keyFp, "0x%x %s m ()\n", 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodId, pRecord->fullName); 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pRecord->signature == NULL) { 4054d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(keyFp, "0x%x %s %s ()\n", 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodId, pRecord->className, 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodName); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 4094d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(keyFp, "0x%x %s %s %s\n", 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodId, pRecord->className, 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pRecord->methodName, pRecord->signature); 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeKeys(FILE *keyFp) 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(keyFp, "%s%d\n%s", versionHeader, versionNumber, clockDef); 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fwrite(keyThreads, strlen(keyThreads), 1, keyFp); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeKeyMethods(keyFp); 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fwrite(keyEnd, strlen(keyEnd), 1, keyFp); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeDataRecords(FILE *dataFp) 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataRecord *pRecord; 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pRecord = records; pRecord->fullName; ++pRecord) { 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int val = METHOD_COMBINE(pRecord->methodId, pRecord->action); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeDataRecord(dataFp, pRecord->threadId, val, pRecord->time); 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid writeTrace(const char* traceFileName) 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *fp = fopen(traceFileName, "w"); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fp == NULL) { 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perror(traceFileName); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeKeys(fp); 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeDataHeader(fp); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeDataRecords(fp); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(fp); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint parseOptions(int argc, char **argv) 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int err = 0; 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 4514d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince int opt = getopt(argc, argv, "v:d"); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opt == -1) 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opt) { 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'v': 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project versionNumber = strtoul(optarg, NULL, 0); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (versionNumber != 1 && versionNumber != 2) { 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Error: version number (%d) must be 1 or 2\n", 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project versionNumber); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project err = 1; 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 4634d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince case 'd': 4644d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince verbose = 1; 4654d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince break; 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project err = 1; 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return err; 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint main(int argc, char** argv) 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *inputFile; 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *traceFileName = NULL; 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseOptions(argc, argv) || argc - optind != 2) { 4814d9b60166efe75325efc76823dab0181a78ca445Rodrigo Ipince fprintf(stderr, "Usage: %s [-v version] [-d] input_file trace_prefix\n", 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argv[0]); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inputFile = argv[optind++]; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseInputFile(inputFile); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceFileName = argv[optind++]; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeTrace(traceFileName); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 494