1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "cutils/event_tag_map.h"
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "cutils/log.h"
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mman.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OUT_TAG "EventTagMap"
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Single entry.
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventTag {
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int    tagIndex;
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char*     tagStr;
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EventTag;
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Map.
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct EventTagMap {
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* memory-mapped source file; we get strings from here */
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void*           mapAddr;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    size_t          mapLen;
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* array of event tags, sorted numerically by tag index */
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventTag*       tagArray;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int             numTags;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* fwd */
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int processFile(EventTagMap* map);
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int countMapLines(const EventTagMap* map);
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int parseMapLines(EventTagMap* map);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int scanTagLine(char** pData, EventTag* tag, int lineNum);
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sortTags(EventTagMap* map);
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dumpTags(const EventTagMap* map);
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Open the map file and allocate a structure to manage it.
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We create a private mapping because we want to terminate the log tag
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * strings with '\0'.
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectEventTagMap* android_openEventTagMap(const char* fileName)
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventTagMap* newTagMap;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    off_t end;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = -1;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    newTagMap = calloc(1, sizeof(EventTagMap));
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (newTagMap == NULL)
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = open(fileName, O_RDONLY);
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fd < 0) {
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: unable to open map '%s': %s\n",
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            OUT_TAG, fileName, strerror(errno));
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    end = lseek(fd, 0L, SEEK_END);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    (void) lseek(fd, 0L, SEEK_SET);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (end < 0) {
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: unable to seek map '%s'\n", OUT_TAG, fileName);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    newTagMap->mapAddr = mmap(NULL, end, PROT_READ | PROT_WRITE, MAP_PRIVATE,
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                fd, 0);
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (newTagMap->mapAddr == MAP_FAILED) {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: mmap(%s) failed: %s\n",
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            OUT_TAG, fileName, strerror(errno));
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    newTagMap->mapLen = end;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (processFile(newTagMap) != 0)
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return newTagMap;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail:
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    android_closeEventTagMap(newTagMap);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fd >= 0)
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        close(fd);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Close the map.
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid android_closeEventTagMap(EventTagMap* map)
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (map == NULL)
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    munmap(map->mapAddr, map->mapLen);
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(map);
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Look up an entry in the map.
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The entries are sorted by tag number, so we can do a binary search.
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char* android_lookupEventTag(const EventTagMap* map, int tag)
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int hi, lo, mid;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    lo = 0;
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hi = map->numTags-1;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (lo <= hi) {
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int cmp;
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mid = (lo+hi)/2;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmp = map->tagArray[mid].tagIndex - tag;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (cmp < 0) {
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* tag is bigger */
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            lo = mid + 1;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (cmp > 0) {
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* tag is smaller */
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hi = mid - 1;
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* found */
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return map->tagArray[mid].tagStr;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Determine whether "c" is a whitespace char.
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline int isCharWhitespace(char c)
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (c == ' ' || c == '\n' || c == '\r' || c == '\t');
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Determine whether "c" is a valid tag char.
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline int isCharValidTag(char c)
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ((c >= 'A' && c <= 'Z') ||
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (c >= 'a' && c <= 'z') ||
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (c >= '0' && c <= '9') ||
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (c == '_'));
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Determine whether "c" is a valid decimal digit.
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline int isCharDigit(char c)
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (c >= '0' && c <= '9');
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Crunch through the file, parsing the contents and creating a tag index.
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int processFile(EventTagMap* map)
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventTag* tagArray = NULL;
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* get a tag count */
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    map->numTags = countMapLines(map);
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (map->numTags < 0)
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //printf("+++ found %d tags\n", map->numTags);
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* allocate storage for the tag index array */
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    map->tagArray = calloc(1, sizeof(EventTag) * map->numTags);
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (map->tagArray == NULL)
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* parse the file, null-terminating tag strings */
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (parseMapLines(map) != 0) {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: file parse failed\n", OUT_TAG);
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* sort the tags and check for duplicates */
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sortTags(map) != 0)
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Run through all lines in the file, determining whether they're blank,
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * comments, or possibly have a tag entry.
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This is a very "loose" scan.  We don't try to detect syntax errors here.
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The later pass is more careful, but the number of tags found there must
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * match the number of tags found here.
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Returns the number of potential tag entries found.
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int countMapLines(const EventTagMap* map)
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int numTags, unknown;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char* cp;
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char* endp;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cp = (const char*) map->mapAddr;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    endp = cp + map->mapLen;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    numTags = 0;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unknown = 1;
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (cp < endp) {
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*cp == '\n') {
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unknown = 1;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (unknown) {
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (isCharDigit(*cp)) {
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* looks like a tag to me */
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                numTags++;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                unknown = 0;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else if (isCharWhitespace(*cp)) {
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* might be leading whitespace before tag num, keep going */
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* assume comment; second pass can complain in detail */
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                unknown = 0;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* we've made up our mind; just scan to end of line */
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cp++;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return numTags;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Parse the tags out of the file.
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int parseMapLines(EventTagMap* map)
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int tagNum, lineStart, lineNum;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* cp;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* endp;
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cp = (char*) map->mapAddr;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    endp = cp + map->mapLen;
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* insist on EOL at EOF; simplifies parsing and null-termination */
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (*(endp-1) != '\n') {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: map file missing EOL on last line\n", OUT_TAG);
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tagNum = 0;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    lineStart = 1;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    lineNum = 1;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (cp < endp) {
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        //printf("{%02x}", *cp); fflush(stdout);
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*cp == '\n') {
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            lineStart = 1;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            lineNum++;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (lineStart) {
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (*cp == '#') {
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* comment; just scan to end */
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                lineStart = 0;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else if (isCharDigit(*cp)) {
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* looks like a tag; scan it out */
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (tagNum >= map->numTags) {
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    fprintf(stderr,
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        "%s: more tags than expected (%d)\n", OUT_TAG, tagNum);
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return -1;
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0)
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return -1;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                tagNum++;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                lineNum++;      // we eat the '\n'
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* leave lineStart==1 */
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else if (isCharWhitespace(*cp)) {
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* looks like leading whitespace; keep scanning */
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr,
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "%s: unexpected chars (0x%02x) in tag number on line %d\n",
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    OUT_TAG, *cp, lineNum);
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* this is a blank or comment line */
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cp++;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (tagNum != map->numTags) {
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "%s: parsed %d tags, expected %d\n",
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            OUT_TAG, tagNum, map->numTags);
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Scan one tag line.
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "*pData" should be pointing to the first digit in the tag number.  On
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * successful return, it will be pointing to the last character in the
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * tag line (i.e. the character before the start of the next line).
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Returns 0 on success, nonzero on failure.
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int scanTagLine(char** pData, EventTag* tag, int lineNum)
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* cp = *pData;
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* startp;
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* endp;
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned long val;
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    startp = cp;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (isCharDigit(*++cp))
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ;
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *cp = '\0';
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    val = strtoul(startp, &endp, 10);
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert(endp == cp);
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (endp != cp)
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "ARRRRGH\n");
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tag->tagIndex = val;
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (*++cp != '\n' && isCharWhitespace(*cp))
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ;
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (*cp == '\n') {
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "%s: missing tag string on line %d\n", OUT_TAG, lineNum);
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tag->tagStr = cp;
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (isCharValidTag(*++cp))
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ;
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (*cp == '\n') {
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* null terminate and return */
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *cp = '\0';
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (isCharWhitespace(*cp)) {
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* CRLF or trailin spaces; zap this char, then scan for the '\n' */
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *cp = '\0';
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* just ignore the rest of the line till \n
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        TODO: read the tag description that follows the tag name
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        */
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while (*++cp != '\n') {
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "%s: invalid tag chars on line %d\n", OUT_TAG, lineNum);
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *pData = cp;
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //printf("+++ Line %d: got %d '%s'\n", lineNum, tag->tagIndex, tag->tagStr);
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Compare two EventTags.
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int compareEventTags(const void* v1, const void* v2)
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const EventTag* tag1 = (const EventTag*) v1;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const EventTag* tag2 = (const EventTag*) v2;
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return tag1->tagIndex - tag2->tagIndex;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Sort the EventTag array so we can do fast lookups by tag index.  After
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the sort we do a quick check for duplicate tag indices.
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Returns 0 on success.
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sortTags(EventTagMap* map)
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    qsort(map->tagArray, map->numTags, sizeof(EventTag), compareEventTags);
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 1; i < map->numTags; i++) {
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (map->tagArray[i].tagIndex == map->tagArray[i-1].tagIndex) {
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "%s: duplicate tag entries (%d:%s and %d:%s)\n",
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                OUT_TAG,
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                map->tagArray[i].tagIndex, map->tagArray[i].tagStr,
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                map->tagArray[i-1].tagIndex, map->tagArray[i-1].tagStr);
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Dump the tag array for debugging.
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dumpTags(const EventTagMap* map)
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < map->numTags; i++) {
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const EventTag* tag = &map->tagArray[i];
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("  %3d: %6d '%s'\n", i, tag->tagIndex, tag->tagStr);
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
439