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